Page 1 of 1

Lazarus pascal unexplained behaviour

lazarus pascal unexplained behaviour

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
Examples: "MacOS X - Your question", "MS Word - Your Tip or Trick".

Please note that switching to another language when reading a post will not work!
Posts will not have a translated counterpart.




RSS Feed

Home Forums Software Development Delphi, Lazarus, Free Pascal lazarus pascal unexplained behaviour

This topic contains 24 replies, has 2 voices, and was last updated by  hans 1 month, 1 week ago.

Viewing 15 posts - 1 through 15 (of 25 total)
  • Author
    Posts
  • 12094

    jimb2019
    Participant

    This code should place shape2 at x,y coord (y is pre-set) and move it again

    after a predetermined pause (.  Del_Dot_Wait)

    In fact, it does nothing until repeat loop concludes then performs BOTH moves.    

      I have tried several ideas, do while, and using  TTimer class, but with !similar! problem .

    I trust this is an appropriate question. Thanks

    procedure TForm1.check_response(Sender: TObject);

    begin

      form1.Shape2.left := 200;{}

      Start_Time := GetTickCount64();

      Repeat

        Inter_Time := GetTickCount64();

        Lapse_Time := Inter_time – Start_time;

      Until Lapse_time > Del_Dot_Wait;

      form1.Shape2.left := 10;

    end; 

    12096

    hans
    Keymaster

    Hi Jim!

    Welcome to the forum! Yes of course this is an appropriate question 

    Note: I’m not an expert … but I love tinkering with Lazarus Pascal 

    As for your code; I did a test with a slightly modified code since I was missing a few things (always a good idea to upload a small demo/test project).

    unit Unit1;
    {$mode objfpc}{$H+}
    interface
    uses
      Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;
    type
      { TForm1 }
      TForm1 = class(TForm)
        Button1: TButton;
        Shape2: TShape;
        procedure Button1Click(Sender: TObject);
      private
      public
      end;
    var
      Form1: TForm1;
    implementation
    {$R *.lfm}
    { TForm1 }
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Start_Time, Inter_Time, Lapse_time, Del_Dot_Wait : qword;
    begin
      Shape2.left := 200;{}
      Del_Dot_Wait := 10000;
      Start_Time := GetTickCount64();
      Repeat
        Inter_Time := GetTickCount64();
        Lapse_Time := Inter_time-Start_time;
      Until Lapse_time > Del_Dot_Wait;
      Shape2.left := 10;
    end;
    end.     

    and I’m seeing the same thing you’re seeing on my machine (running MacOS Mojave 10.14.5, Lazarus 2.1.0 r61305M FPC 3.0.4 x86_64-darwin-cocoa (alpha) – so from trunk/svn). Not sure what OS you’re working with or what version of Lazarus/FPC.

    What I often do, while testing such odd behavior, is add an “Application.ProcessMessages;” in one or more places.
    In your code, if I would experience the same issue, I’d do this:

    procedure TForm1.Button1Click(Sender: TObject);
    var
      Start_Time, Inter_Time, Lapse_time, Del_Dot_Wait : qword;
    begin
      Shape2.left := 200;{}
      Application.ProcessMessages; // <-- add here so it draws the moved shape
      Del_Dot_Wait := 10000;
      Start_Time := GetTickCount64();
      Repeat
        Inter_Time := GetTickCount64();
        Lapse_Time := Inter_time-Start_time;
      Until Lapse_time > Del_Dot_Wait;
      Shape2.left := 10;
    end;

    but I noticed this didn’t seem to make a difference either.

    So I went a different route, since I suspect GetTickCount is gobbling up some of the time needed to update the position of Shape2.
    I’m using InSecond() from the dateutils unit.

    procedure TForm1.Button1Click(Sender: TObject);
    var
      EndTime:TDateTime;
    begin
      Shape2.left := 200;{}
      EndTime := IncSecond(Now,1); // from unit dateutils, add one second to now
      Repeat
        application.ProcessMessages;
      Until EndTime<=Now;
      Shape2.left := 10;
    end; 

    This does work! 

    Another advantage is that this approach will not freeze or lock your application because we use “application.ProcessMessages;” in the loop.
    If you need milliseconds, there is also a incMilliseconds() function in the dateutils unit.

    12098

    jimb2019
    Participant

    Thanks Hans,

    I believe that the GetTickCount must use some time, but It should NOT prevent the dot being displayed first, that aside, your code  does work 

    I cannot see were you declare USE   dateutils, but I addded it to mine…

    NOW, in use, the dot will will be in the temp position for less than one second, but using the incMillisecond parameter solved that  so

    THANKS!!!!,

     this has been the longest debug episode since 1985 when I had a problem with 9k of 8085 Assembler code written by someone who did NOT believe in commenting code! 

    I hope I do not become a pest but I have may more problems, I am getting back into programming after a break, my last medium was Delphi, Lazarus seems to be more top heavy…

    One problem is the tray at the top of the IDE screen, there is the Unit 1 which has the program source code and other that I added during the early days to write experimental code to try algorithms etc. 

    unit2                        Not  used

    unit3                           Not used

    control.inc                ????????

    testtimer                 DOS pascal version I wrote, using some of the code  

    brush.inc                      ?????????

    Graph               ????????

    NEW_fieldst.lpr      ????????????

     Can I delete these ones I do not want or are they part of my code

    As you can see, I am out of date and flying in fog, very frustrating

    I would still like to know why mu original delay code failed, it annoys me.

    Thanks again Hans.

    Jim

    Best is the enemy of good enough

    Barrs Law Of Recursive Futility

    If you are smart enough to use one of these…

       ,,, you can probably manage without one!

     

    12100

    hans
    Keymaster

    Yeah, I posted only a part of the code with the new function – so the “uses” is something I should have added.
    That’s why I wrote it in the code comments that the function came from dateutils .

    Glad to hear it worked out with incMillisecond 

    Haha, yeah working with code written by others is a challenge at times, let alone when they leave out comments. I run into that every now and then as well. The last time I worked with assembler was on a Commodore Amiga (Motorola 68000). I may have done an attempt to do assembler on an Intel 386, but quickly ran away screaming hahaha.

    I wouldn’t say that Lazarus is more top heavy, maybe for really small applications. But as applications get bigger, the size of the application will increase much less than Delphi. The turning point for me (I started with Delphi 1.0 and used it up to Delphi 2006) was when I noticed how much faster Lazarus applications can be, compared to Delphi (at the time – I’m sure Delphi has improved in the meanwhile). Another thing where Delphi lost me is the use of FireMonkey instead of VLC, and the fact that MacOS and iOS 64 bit is not (yet) supported. I’m not a fan of custom drawn controls – I prefer native controls.
    But time will tell if I will switch back or not – I do keep testing Delphi every now and then to see where they are at.
    For now I’m very happy with Lazarus (you’ll see that all my applications on this website are written in Lazarus).

    Sounds like you’re indeed getting your feet wet with Lazarus – very cool!
    And you’ll notice it works a little bit different than Delphi or Turbo Pascal (at least that was my experience).

    Units that are not used; 

    First thing is to realize is that if a file is open in Lazarus, then this does not mean the file is part of your project perse.

    When debugging or looking for the declaration of a function, Lazarus can open a Lazarus Pascal unit (for example control.inc, brush.inc and Graph).
    This does not mean it’s now a “fixed” part of your project. So you can close those without worry.

    Next, I’d first check which units are marked as required in your project file (menu: Project -> Project Inspector).
    Remove the files you don’t need – for example your unit2 and unit3 could be in there by mistake and therefore can be removed.

    I also tend to clean up (remove) files from the project directory when I do not need them anymore (just to clean up) – sometimes by moving them in a separate sub directory, just so they stay handy in case I made a mistake in removing the files. For example, you probably opened “testtimer” to review your old code, I do this often as well, but since it’s not part of your project, you can close the file and/or move the file to the backup directory (or leave it where it was, in case it was located not located in your project directory).

    Note: For testing I usually start a small separate project.
    Once done testing I copy the parts of the code that I need to my main unit (or a separate unit).

    The file “NEW_fieldst.lpr” is a project file (Lazarus PRoject).
    A project file is the main file, holding it all together, like DPR files in Delphi.
    You can close this file, it’s not often that you need to be in that file, but it is part of your project.

    Delay in refreshing painting

    Lazarus Pascal appears highly optimized, especially compared to Delphi.
    This does occasionally come with little challenges like this one.
    Coming back to your code; you’ll need to give the application some breathing room in the repeat-until loop.
    You can do this by adding “Application.Processmessages” (recommended) and/or a little sleep like sleep(100) or something like that (I believe that using sleep() is frowned upon ). LCL (Lazarus VCL counterpart) handles a lot through messaging (probably inherited from the original Delphi 7.x / Windows). ProcessMessages briefly jumps to the mechanism that handles these messages – repainting an control could be one of those messages.

    Since I already delete the project file, you could give this a try – I haven’t tested it.

    procedure TForm1.Button1Click(Sender: TObject);
    var
      Start_Time, Inter_Time, Lapse_time, Del_Dot_Wait : qword;
    begin
      Shape2.left := 200;{}
      Del_Dot_Wait := 10000;
      Start_Time := GetTickCount64();
      Repeat
        application.ProcessMessages; // <-- process LCL messages
        Inter_Time := GetTickCount64();
        Lapse_Time := Inter_time-Start_time;
      Until Lapse_time > Del_Dot_Wait;
      Shape2.left := 10;
    end;

    Feel free to ask – I’d be happy to help. Always nice to see other Lazarus Developers here 

    12106

    jimb2019
    Participant

    Hi Hans,

    Thanks for the copious notes. Some of it is a bit over my head, but where I DO understand, it is very informative, I continue to learn. We seem to have shared several experiences in the field.

    A bit of info re the project I am working on; you may well have had a “Field Test” at the optician at some time, I am making a pc based app that will vaguely emulate this test.  

    red dots are flashed up in the field of view, the user clicks a button if they see it, the dots are pre-made and stored in a file of array, (cells), so far a cell contains :=

    the dot #

    x coord.

    y coord

    boolean, dot seen = true or false

    the flash duration is pre-set, around  0.03 Sec

    The max time during which a response is made; around 1 to 2 sec

    A random wait up to 4 – 8 sec before next flash

    Many of the system procedures have been built and tested in temporary forms etc, integrating them is a bit tricky and I am using flow charts to keep a handle on it 

     I have tried to include the mane pascal file as it stands so far, not sure if it worked but it may help to see how I am approaching it, some of the procedures are simply “techology provers”

    The Create dots is where the present problems lie, it is a mess

    Most of the code is just creating x,y coord’s within a circle, and excluding the centre of the circle

    THEN the data is loaded into the array

    Monitoring the values created they suddenly go crazy with values of > 64000!!!!   

    I very smart pal of mine has become interested in this and may be able to add some sense, we will see.

    Anyway, It is all very good FUN  I will be 75 next month but my health is not great so it is good to have an interest that is not to physically taxing!

    Thanks and best wishes, Jim

    12108

    hans
    Keymaster

    Hi Jim,

    I’m sorry to hear your health is not that great. 
    However, I think it’s cool that you’re still tinkering with stuff like that – I hope to be able to do that as well, 23 years from now.

    Best wishes, and feel free to ask if you have questions!

    Hans

    12114

    jimb2019
    Participant

    Hi Hans.

    Still 3 steps forward and 2 steps backl!

    I Think I have managed to create the “dot data”  for this project and save in an array which will be stored in files, ( alternative data sets),

    However,It seems I obviously do NOT understand how to implement your use of TDateTime.

    The following code should simply display 1 dot moving from x,y location to another, pausing at each long enough to be seen, this is simply a technology prover, not part of the final program.

    I am sorry about the formatting but it is NOT compatible with any text editor I have!!

    I trust you will seed this code with a few values and educate me further!

    Did I mention I have found a buddy who is  interested and quite clever, I should be having a meeting nest week!

    Best wishes, Jim

    procedure TForm1.disparray(Sender: TObject);

    VAR

      a : word ;

      EndTime :TDateTime;

    BEGIN

      //create__dots(Sender);

      FOR a := 1 to 5 DO

      BEGIN

        shape2.Left := (cells[a].x);

        shape2.top := (cells[a].y);

        label1.caption := IntToStr(cells[a].x);

        label2.caption := IntToStr(cells[a].y);

        EndTime := IncMilliSecond(Now,100);

        Repeat

          application.ProcessMessages;

        Until EndTime <= Now;

      END;

    END;   

    12116

    hans
    Keymaster

    Hi Jim,

    Your function looks correct, and after testing it, it works correct.
    Can you tell me what is going wrong or what your concerns are? (since you’re saying “should” simply display 1 dot moving)

    I’ve attached a MP4 screen recording of my example project running, and included my test project.

    Note that I’m running Lazarus under MacOS (Cocoa/64bit) from trunk (SVN) – so I can test and use the latest Lazarus changes. 
    On what OS are you running Lazarus and what version are you using? (just in case we run into something goofy)

    p.s. if you want to paste code; just paste it straight from Lazarus into the editor, select the code and press the “Source Code” button (in this editor, the button on the far right). So you’ll get something like this:

    unit Unit1;
    {$mode objfpc}{$H+}
    interface
    uses
      Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, dateutils;
    type
      { TForm1 }
      TForm1 = class(TForm)
        Button1: TButton;
        Label1: TLabel;
        Label2: TLabel;
        Shape2: TShape;
        procedure Button1Click(Sender: TObject);
      private
      public
      end;
    var
      Form1: TForm1;
    implementation
    {$R *.lfm}
    procedure TForm1.Button1Click(Sender: TObject);
    var
      a : word ;
      EndTime : TDateTime;
      cells : array [1..5] of tpoint;
    begin
      // dummy data
      cells[1].x := 10;
      cells[1].y := 100;
      cells[2].x := 30;
      cells[2].y := 100;
      cells[3].x := 50;
      cells[3].y := 100;
      cells[4].x := 70;
      cells[4].y := 100;
      cells[5].x := 90;
      cells[5].y := 100;
      FOR a := 1 to 5 DO
      BEGIN
        shape2.Left := (cells[a].x);
        shape2.top := (cells[a].y);
        label1.caption := IntToStr(cells[a].x);
        label2.caption := IntToStr(cells[a].y);
        EndTime := IncMilliSecond(Now,100);
        Repeat
          application.ProcessMessages;
        Until EndTime <= Now;
      END;
    END;
    end.

    It will “remove” empty lines, so if you want line breaks in to, then I usually do that with SHIFT+ENTER.

    All that may seem like a lot of extra work, so feel free to attach your example code as a zip file, if that makes it easier 

    Attachments:
    12120

    jimb2019
    Participant

    Interesting!

    I appears my version of Lazarus was V1.6.4, date 02/01/17, downloaded a couple of months ago, not sure why it’s so old

    I have replaced it with V2.0.2  date 13.04/19, although it was a bit confusing and seemed to be a combined install and update rather than a clean install.

    I did backup the entire directory of my lazarus.

    The result is that the code still behaves as before.

    Occasionally, the program crashes after running this test for a second time.

     I suppose it is possible that some of the delicate settings in Lazarus have defaulted to inappropriate values ?

    Crashes are a tricky one, no obvious error messages or clues.

    He-Ho, I’ll plod on…

    Jim

      

    12134

    jimb2019
    Participant

    Hi Hans,

    I’ve made a few strides forward recently but hit a problem with dissembling a button.

    Button name is SEEN, The code 

    “seen,enable ::= False”      should inhibit the button, but does not do it

    The only stuff on a google search suggests following this with a sleep or delay, but several tries at a few techniques all fail ..

    I can send the surrounding code but feel it is irrelevant as a Variable Watch should show up the button state

    Any thoughts?

    Thanks in advance and best wishes,

    Jim   

    12136

    hans
    Keymaster

    New Lazarus versions

    I forgot if you had mentioned what OS you’re running.
    For Windows, Lazarus is a completely new install (IDE and compiler).
    For MacOS you’ll have to install Lazarus (IDE) and the compiler (FPC and FPC sources) – the compiler is not always needed, but I always do anyway.

    The update feeling may come from components you may or may  not have installed. Since I run from trunk/SVN, I every now and then have to do a manual Build -> Build Lazarus to recompile previously installed components.

    As for sensitive settings; after a first install, everything should be set fine. It’s usually paths that one should worry about when tinkering with the settings.
    If you’re running MacOS then the debugger can be tricky. GDB is no longer supported by Apple, and it may or may not work. LLDB (which is what Apple uses in XCode) is still in alpha or beta phase for use with Lazarus. It works but it can be very slow. For this reason (since I work on a Mac) I have the debugger default set to “none” and only use it when things go sideway.

    Lazarus also has a command line tool, called “strip” to strip debug info and other useless info (when distributing the application), making the executable often quite a bit smaller. 

    Application crashing

    In my experience, Lazarus code is very stable, and a crash is (in my case) always caused by my own code. For example going out of index, or using a pointer to something that no longer exists. It’s a little difficult to judge what the problem may or may not be without knowing the entire code.
    Running with debugger or adding some “exit” statements in the code, could help determining where it crashes.

    Also keep in mind; Lazarus is continuously being further developed. So you may have ran into a bug, which you could report in the Lazarus BugTracker if you’d like.

    Disable button

    You’re right;

    seen.enabled := false;

    should disable the button, so there is something going goofy for sure.
    I don’t know what OS you’re running. If it’s MacOS, then you’ll have to keep in mind that the Cocoa widget set is still in alpha or beta stage. So there may be some issues there (again: reporting a bug would be good).

    I haven’t run into this issue though.

    I did see a post from 2011 suggesting the idea to add a sleep, but honestly do not think this should be the way to do it.
    In case you application is somehow resource hungry, and messages (eg. disable the button) do not come through, you could try the following right after disabling the button:

    Application.ProcessMessages; 

    It should just work right away though without the need for a sleep or a processmessages.
    On that note; the Lazarus Forum is also a great resource and at times people can be very helpful.

    If you’d like I can look at the code, or even test it on my machine (probably better to do that through email then I guess).
    I guess I should ask; what OS are you running Lazarus on? (apologies if you’ve mentioned it before)

    12144

    jimb2019
    Participant

    Hi Hans,

    My lazarus is v 2.0,2, I think I did mention it, but maybe no I run win10, ( I hate it!!!) a lot of MS software has leapt  into obscure geekdom.

    I do NOT have a glue why the button would not change stat but the problem went away… It would be nice to know what was wrong before, I have a recurring problem, putting a button or label on the form and not being able to resize 

    Anyway I have made more progress and now need to convert my file handeling from DOS pascal to OOP

    I would be grateful if you you could send a dummy procedure with declarations etc to enable me to see the format, All the examples on the we search seem to be for more complex problems like append, which confuses the learning.

    I have managed to master the time delays and other minor problems that were bothering me.

    One helpful diagnostic tool would be to enable printing contents of my array of records to the screen like I did in DOS

    Write(‘x = ‘),x,(‘ y = ‘),y,… etc), WriteLn;

    I think  canvas object would be one solution, but the tutorial left me confused This is not for the program while running in final use but for debugging

    It would still be a very useful thing for other projects!!

    I did have ‘membership’ on Stack Overflow a long time ago but lost my password, it is a complex login procedure (unlike yours), and I was eventually blacklisted.

    A bit humiliating, I was a Moderator on the American Wind energy website years ago, back in the 90’s ao I was not really a problem guy!

    Thanks again for you help

    Best wishes, Jim

    12159

    hans
    Keymaster

    Hi Jim,

    Yeah, I’m not a big fan of Windows either – but I have had to work with because of work, even though I do most on my Mac.

    I prefer using the trunk/SVN version of Lazarus, which comes with the latest and greatest improvements and sometimes new bugs 
    But since I work on a Mac, and I need the Cocoa widget set, I’m kind-a stuck using the SVN version (Cocoa is still in Alpha or Beta phase).

    As for the glitches you seem to experience; these may be known bugs in that version.
    If you dare to do it, you could install from SVN as well. I believe there are 2 tools out there that should make it easy to do: Lazarus Manager and FPCUpDeluxe.
    I do it manually through Terminal (Shell) and have never tried either tool.

    For OOP file handling; checkout TFileStream. I had to get used to it (I too was used to the old Pascal ways), but it’s very powerful and fast. I really like using it. Having said that; the old school method is still valid and works just as well.

    The link I added are is where I learned it from as well.
    Here a simplified and stripped version of one of the examples found at the links I just gave you.
    The confusing part will be the use of a buffer (versus just reading a string with the old Read and ReadLN functions).
    So in the example below (I hope I didn’t make any typos), basically we open the file (TFileStream.Create), determine it’s size, set the string (txt) to that size so it can hold all we need and then read the file.

    function readstream(AFilename: string): string;
    var
      MyFileStream: TFileStream;
      n: longint;
      txt: string;
    begin
      try MyFileStream := TFileStream.Create(AFilename, fmOpenRead or fmShareDenyWrite);
        n := MyFileStream.Size;
        SetLength(txt, n);
        MyFileStream.Read(txt[1], n); // Read , reads data to a buffer in memory (txt), so we pass a pointer to that
      except // something went wrong!
      end; MyFileStream.Free;
      result := txt;
    end;

    A few notes;

    1) I usually use “array of char”, which works better in my head 
    2) As a “dirty” alternative, you can use a TStringList, if you’re working with text, which has a LoadFromFile function. It loads the text and you can access each line individually. TMemo has this as well.

    3) If you’re working with INI files, then I’d recommend reading up on that topic (here, and here) even though the examples there aren’t the best.

    As for your question on using “write”; you can still use it, but you’ll have to start the executable from a DOS prompt.
    The write output will then be visible 
    I usually dump that kind of info in a TMemo that I have placed on my form (only there/visible when I’m developing).
    ShowMessage() can be handy as well. But again, only during development of course.
    I’m not very familiar with the debugger under Windows, but I think you can tinker with setting a watch for you variable and do some settings on what kind of data it is.

    The Canvas, yeah, that can be confusing at times to me as well, and not all widget sets support it fully.

    For StackExchange you can login/setup an account with your Google/GMail account with just one click.
    But I’ll admit that I mostly read on StackExchange and not to often post anything there.
    I can imagine it feeling a little bit humiliating, but think about it this way; they “automated” all that in such a way that things do go sideways and folks get banned for the wrong (automated) reasons. I’m actually not very thrilled with the login on my own website, but I couldn’t find anything better.

    Wind Energy … hmm, I’ll have to keep that in mind – I may one day have questions for you 

    Enjoy your weekend! 
    Hans

    12163

    jimb2019
    Participant

    Hi Hans,

    Thanks for all the useful stuff on file handling! i have decided to leave for a while till It is the last hurdle to jump! but your links were the clearest examples I have seen so far.

    I have used TMemo to display live multiple values of crucial data and it has proved invaluable.

    Nearly everything is running well………..BUT

    The dot I produce is one small red circle and the program does manage to display this as required for the Eye test, however for a doctor to be able to display the results, I need to be able to display every dot on one screen red for dots seen and black for dots not seen during the test, ( I am not sure I explained allready what this program does), sorry if this is confusing.

    SO I made an array of shapes and then tried to alter the parameters on the fly, to become red dots of the right size, colour etc

    The following code complies but crashes during run start up. I AM LOST.

    I hope I am just doing it badly but, maybe you recognise the problem below

    ***********

    Re WInd energy, I started doing stuff at home in 1986 during a drought, so we could recyle bath water and other grey water, i eventually had a system that pumped the water away from the garden to a filter bed where it feed a pond or the garden. I built a few and sold some, before writing a book on it.

    By 2001 I was known enough to be invited to be an expert on a TV show called ScrapHeap Challenge where the teams had to build a system to grind coffee.. My team lost but it was great fun, I carried on working and studying wind energy and did lots more, hence the AWEA, (now defunct but replaced by something else)

    Bets wishes Jim 

    ******************************************************

    Global declaration  

    Dots: array [0..Num_dots] of Tshape;   

    Intiated by a button 

    procedure TForm1.make_dots(Sender: TObject);

    VAR

      a : Word;

    BEGIN

     FOR a := 1 TO Num_Dots DO

      BEGIN

    // Dots[a].shape := stcircle;

      Dots[a].width := 5;

    // Dots[a].height := 5;

    // Dots[a].color := clred;

    // Dots[a].left := a;

    // Dots[a].top := a;

      END;

    END;  

    Compiles fine

    Run  time error appears:- If FShape… bold and underlined

    **************************************************

    Project New……. raised exception class ‘external SIGSEGV’

                     In file ‘include\shape.inc at line 214

    *************************************************

    Ad this is the code that it points to at line 214 

    procedure TShape.SetShape(Value: TShapeType);

    begin

      if FShape <> Value then

      begin

        FShape := Value;

        StyleChanged(Self);

      end;

    end;     

    12165

    jimb2019
    Participant

    Oh Dear, A bit embarrassing Hans, I woke up last night around midnight and realised I had written rubbish code to create the shapes, I did create a OOP Link List of objects for something about 30 years ago, but cannot remember how,

    I still need help with this but I DO apologise for my stupididty, I will be 75 next month and blame old age!

Viewing 15 posts - 1 through 15 (of 25 total)



You must be logged in to reply to this topic.