Jump to content

JohnLM

Members
  • Content Count

    359
  • Joined

  • Last visited

Posts posted by JohnLM


  1. Update on this endeavour. . .  a solution has been found and is working, thanks to Alexander S. and Remy for their help. 

     

    After some time, I managed to get the suggested virtual method posted by Remy working successfully, thank you.  But my listview is showing some artifacts in the drawing of the rows.  I will have to research that later.  I will study this method further in order to understand how it works.   Oh, and the run time on my old Dell laptop is now 38ms for the 25k, and 72ms for 100k.  A huge difference! 

     

    Thank you @Alexander Sviridenkov, for first suggesting it to me.  I did do some research into it right after your post and was trying but failing to figure out how to put it all together.   And also to @Remy Lebeau, for the posted code snippet that showed me the way.  Much appreciated!!

     


  2. Specs:  Delphi XE7, VCL, windows 7, Dell laptop (i3 core, 2.40GHz) 

     

    I have been playing around with the Listview control, (via ViewStyle=vsReport) learning how to add items at runtime through code (not using a database/binder), for 100 to a few thousand items.  Again, just playing around with throwing together a quick listview of data, and seeing if there is use for it versus going the database dataset route. 

     

    Note, because I was self-learning about listview from scratch, I did have a lot of trouble figuring out how to populate the listview.  And now that I know how to, I am also sharing it here for reference for others struggling to do the same.  Below, is the code snippet of how I created the initial fields and then populate them.  The ViewStyle should be set to vsReport in the properties section in order to show a table column layout at run time.  It works and that's all that matters at this point in this indeviour. 

     

    procedure TForm1.btnAddClick(Sender: TObject);
    var
      itm : TListItem;
      Col : TListColumn;
      s   : string;
      et  : int64;
      SW  : TStopwatch;
    begin
      Col := lv1.Columns.Add;
      Col.Caption := 'LN';
      Col.Alignment := taLeftJustify;
      Col.Width := 30;
    
      Col := lv1.Columns.Add;
      Col.Caption := 'ItemNo';
      Col.Alignment := taLeftJustify;
      Col.Width := 60;
    
      Col := lv1.Columns.Add;
      Col.Caption := 'Desc';
      Col.Alignment := taLeftJustify;
      Col.Width := 160;
    
    
      setlength(ary,10);                           // create the array length (1,2,3,4,5,6,7,8,9,0) chars
      beep;
      SW := TSTopWatch.StartNew;                   // start timing it
      lv1.Items.BeginUpdate;
      for i := 0 to 25000 do begin                 //
        ary := genRandValues;                      // generate random numbers ie (2,9,8,4,7,5,6,0,1,3)
        s:=listtostr(ary);                         // convert array list into a string var ie ('2984756013')
        itm:=lv1.Items.Add;                        // create a row
        itm.Caption := i.ToString();               // add the major field, ie 'LN', thus the populate with variable i as line numbers
        itm.SubItems.Add(''); itm.SubItems[0]:= s; // itemno ie '2984756013', and so on. 
        itm.SubItems.Add(''); itm.SubItems[1]:= s; //   desc ie same, ...
      end;
      lv1.Items.EndUpdate;
      SW.Stop;                                     // finish timing
    	eb1.text:=(intToStr(SW.ElapsedTicks)+' ticks / '+intToStr(SW.ElapsedMilliseconds)+' ms');
      beep;
    end;

    But the problem I am having is that even when using the .BeginUpdate/.EndUpdate the speed is still a bit slow. 

     

    For example, to fill a listview with 10,000 elements, it costs me about aprox 1.6 seconds run time, or for 25,000 elements, 7.6 seconds. 

     

    I had a look at the earlier part of the for/loop, where I am generating the random numbers and then converting them to strings.  I REM'ed them out and the time was still the same or ever-so-slightly less, maybe 1.5 seconds for instance.  So that does not seem to be a major issue in slowing the listview down. 

     

    Is this the maximum throughput I can expect from listview? or Is there anything else I can do to speed this up a lot more? 

     

     


  3. I don't know why I am having so much trouble with something that seems too easy to accomplish, yet I am.  I just got up and saw these posts, and decided to sketch out an illustration of what I am trying to accomplish.  Please forgive me if I seem too slow at all this.  I am a very slow person these days in my old age. 

     

    Okay.  I have simplified this in an Excel sheet to help illustrate the basic process. 

    * in the finished product, the "irregularly" shaped array should look like what's shown in blue in fig 4. 

     

    1824315769_im-praxis-1-creating-irregularly-shaped-multi-dim-dynamic-arrays.thumb.png.9dc5259753f9da408601c6350b4c1ccb.png

     

     

    I believe the main part of my problem is that I am doing this setlength() inside the parser routine and that I have to build the irregularly shaped array afterwards once I have the (R,C) criteria in fig 4. 

     

    Also, I found this link that may help: https://docwiki.embarcadero.com/RADStudio/Athens/en/Structured_Types_(Delphi)#Multidimensional_Dynamic_Arrays

     

    PS:  I've just updated the grid in fig 4 to show that they are individual elements in the array, not one string. 


  4. Is it possible to set variable size multi-dimentional arrays dynamically at runtime?

    Or, do I have to be clever about it in another way? 

     

    My usual ways to create m-a's are the typical triangle shape, not irregularly shaped. I want to create the irregularly shaped, like the examples listed below. 

     

    I have been playing around with run-time dynamic arrays via SetLength() and then realized I can't create them dynamically with different size Columns. I have been using for/next and repeat/until loops of various kinds to attempt to do the irregularly shapped arrays but when I come to create a new Row and reset the C to 1, the data is wiped or I get strange behavior, which leads me to realize this route is not possible, and that I have to do something really clever, maybe to simulate multi-dim dynamic arrays. 

     

    I have a string list that I want to parse as values--text for strings, numbers for integers.

     

    The multi-dim array can look something like the following examples below: 

     

    where s=string, n=number, r=row, c=column

     

    So, using ex 1, as I parse my string list, (a single column list), R is set to 1 for row 1, and C is set to 1, and as I parse through the list, I inc(C) for row 1, thus, ( 1 [n, n, n] ) 

     

    When I create row 2, I inc(R), and is now row 2, thus ( 2 [n, n, n, n, n] ), . . ., and so on, for row 3, . . . etc. 
     

    ex 1
    ====
    
    R | C - - - >
    -----------------
    1 [n, n, n]
    2 [n, n, n, n, n]
    3 [n, n]
    4 [n, n, n, n]
    5 [n]
    
    ex 2
    ====
    
    R | C - - - >
    -----------------------------------------
    1 [n, n, n, n, n, n, n, n, n, n, n, n, n]
    2 [s, s, s]
    3 [n, n]
    4 [s, s, s, s, s, s, s, s]
    
    ex 3
    ====
    
    R | C - - - >
    --------------------------------------------------------------
    1 [s, s]
    2 [s]
    3 [s, s, s, s, s]
    4 [s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s]
    5 [s, s, s]
    6 [n, n, n, n, n, n, n]

     


  5. Progress update. . . -- on that last next steps I just mentioned, to pull the text from the active tabsheet for the memo I am focused in. . .

     

    I have successfully figured out how to pull the text from the dynamically created memo's.   It was quite difficult to solve, but I did it.  And I did not copy someone else's code snippet. 

     

    And the code snippet to accomplish it: 

    procedure TForm1.PageControl1Change(Sender: TObject);
    var
      frame   : TFrame2;
      edit    : TEdit;
      pgCount : integer;
      tabIdx  : integer;
    begin
      tabIdx  := PageControl1.ActivePageIndex;
      pgCount := pagecontrol1.PageCount;
      frame   := (pagecontrol1.Pages[tabIdx].Components[0] as tframe2);
      edit    := (pagecontrol1.Pages[tabIdx].Components[1] as TEdit);
      StrLines.Assign(frame.memo.Lines);
      listbox1.Items.Assign(frame.memo.Lines);
    end;

     

    Output results are:  text from each memo (left pane) is copied into the listbox (right pane) for proof of concept. 

     

    DynamicTabsMemos_by_JohnLM.thumb.gif.f3af7b4ada65dad22fa9751c0fa0e20f.gif

     

    All this is part of a project that I am working on, to create a tiny hobby IDE for Python for myself. 

     

    It appears that this topic has been solved. 

     


  6. I had to change the memo to frame2.  The memo is inside the frame. 

     

    update code snippet #4 

    procedure TForm1.btnAddClick(Sender: TObject);
    var
      TabSheet: TTabSheet;
      frame2: unit2.TFrame2;
    begin
      inc(idx);
      TabSheet := TTabSheet.Create(PageControl1);
      TabSheet.Caption := 'Untitled-'+idx.ToString;
      TabSheet.PageControl := PageControl1;
      frame2 := tframe2.Create(nil);
      frame2.Parent    := tabsheet;
      frame2.Name      := 'Untitled'+idx.ToString;
      frame2.memo1.Align  := alClient;
      frame2.memo1.Lines.Add(frame2.name); // <<-- this line will show the memos .Name portion in each dynamically create new tab/memo.
      frame2.memo1.Show;
      frame2.memo1.SetFocus;
    end;

     

    Next steps is to get the text from whichever memo I am typing in the tabsheet. 

     

    That should be easy, I think I just need to grab the frame.memo1.lines or frame.memo1.text should return the text from any memo I am currently typing in.

     

    I will look into later today.  I have to get some sleep now. until then. . .


  7. When you add a memo or memos to a form, the default behavior is that Delphi will give the .Name and .Text properties a detault value and assign them the same string to represent that component.  Thus, memo1.name=memo1 for instance.  It prefills this info for our reference at design-time and we can change it or remove it.  I myself usually remove it, the .Text portion and I will usually rename .Name to something much shorter, like .Name=m2 for instance. 

     

    procedure TForm1.btnAddClick(Sender: TObject);
    var
      TabSheet: TTabSheet;
      memo: unit2.TFrame2;
    begin
      inc(idx);
      TabSheet := TTabSheet.Create(PageControl1);
      TabSheet.Caption := 'Untitled-'+idx.ToString;
      TabSheet.PageControl := PageControl1;
      memo := tframe2.Create(nil);
      memo.Parent    := tabsheet;
      memo.Name      := 'Untitled'+idx.ToString;
      memo.memo1.Align  := alClient;
      memo.memo1.Lines.Add(memo.name); // <-- this line will show the memo's .Name portion in each dynamically create new tab/memo.
      memo.memo1.Show;
      memo.memo1.SetFocus;
    end;

     

    1027195734_im-dynamictabsex2.png.4ad68e97c30be94f22c00a170e183a65.png

     

    I guess I don't actually need the .Name portion to show. I was just trying to demonstrate to myself that I was creating unique tabs AND memo's successfully as demonstrated above. 

     

     


  8. Update on progress. . . continues. . . 

     

    @Remy Lebeau, I have tried your suggestion.  And after many hours, I finally got it working, I think.  I never worked with Frames before.  I still don't understand them but in this case, I do believe I have it working, but with a few slight issues. 

     

    1st, the code, now modified for Frame support: 

    procedure TForm1.btnAddClick(Sender: TObject);
    var
      TabSheet: TTabSheet;
      mem: unit2.TFrame2;
    begin
      inc(idx);
      TabSheet := TTabSheet.Create(PageControl1);
      TabSheet.Caption := 'Untitled-'+idx.ToString;
      TabSheet.PageControl := PageControl1;
      mem := tframe2.Create(nil);
      mem.Parent       := tabsheet;
      mem.Name         := 'Untitled'+idx.ToString;
      mem.memo1.Align  := alClient;
      mem.memo1.Show;
      mem.memo1.SetFocus;
    end;

    And the results: 

     

    2060238209_im-dyanmicallycreatedtabswithframessupport.png.faec7fd031dbb8b86217607bf4b8886c.png

     

    As for the issues: 

     

    1) all the tabs I create have the same name, "memo1".  (see code) 

    2) the alignment to client is quirky, but I managed to get it to work to fill the tab area.  (see code) 

    3) the memo's names (for each tab do not show up in the memo's view.  They all say the same thing, "memo1". (see code) 

       they should be "Untitled1, Untitled2, Untitled3, ..." in each memo, just like when you add a new memo to your form in the IDE. 
     


  9. Update on my progress. . . 
     

    You guys can do this!  I have no doubt!  I know you all can figure this out, lickady-split or a few minutes, but I am not in your category.  I am just a lowly hobbiest at best. 


    Unfortunately, I am no component expert, nor am I am Pro at Pascal programming, let alone OOP and all. I am just a casual guy who codes small Windows utilities and other fun and interesting things. Occasionally I will try and learn OOP and component anything but I do not get very far, as I am a very slow learner.  
    Anyway. I have looked into the suggestions here, and also my own searches. 


    I found some resources and spent a great deal of time trying to understand them and then build them, but to no avail. I am just a complete failure in these advanced areas. 


    For instance, in one resource (web search) I did find a routine that shows how to pull properties from all components on the form.  


    And in another resource (web search) I found another routine showing how to pull properties similarly but slitely less detail.  


    And yet in another resource showing similar, I can pull and narrow down to just tmemo's properties, which is just what I was looking for as a start. 


    And then, in another resource, I found where I could: pull the properties of a tmemo and show it in another memo and make changes to the properties in that memo and the routine would show a memo with the changed state.  But, I could not get it to copy from another memo, its properties because it would issue an error: "memo has no parent window" and other errors as well.  I tried many scenarios of code ideas but to no avail. 


    There is one more resource that I found (from the lazarus website) to try out, the next time I come back from a break from this endeavor.  


    As for now and after three very long days and nights and many many hours, so many hours, of trying to figure this out, I am giving this up.  I am taking a break and going back to other projects.  

     

    Thank you all for your suggestions. 


  10. Specs:  XE7, VCL, Win7 

     

    I have a Panel with a TabControl in it and a Memo inside the first TabSheet on a Form that was all created and configured during design time.  And, on the Form in another Panel, I have a [Add] button to dynamically create a new TabSheet and Memo. 


    The main Memo is the default with all the settings that I would like the dynamically created Memos to have.  But setting up all the necessary properties would be tedious and if I change something in the main Memo at design-time, I may not remember to update that to the dynamic ones.   

     

    var
      Form1: TForm1;
      idx: integer=0; // index numb, for adding new tabs to the pagecontrol.
    
    procedure TForm1.btnAddClick(Sender: TObject);
    var
      TabSheet: TTabSheet;
      memo: TMemo;
    begin
      inc(idx);
      TabSheet := TTabSheet.Create(PageControl1);
      TabSheet.Caption := 'Untitled-'+idx.ToString;
      TabSheet.PageControl := PageControl1;
    
      memo := tmemo.Create(pagecontrol1);
      // settings section
      memo.Color := $0017110D;
      memo.Align := alClient;
      .
      .
      .
      // end of settings section
      memo.Parent := tabsheet;
      memo.Show;
      memo.SetFocus;
    end;

    note: I have a lot more properties than what is posted above. 


    Is there a better way to copy all the properties of the main Memo to the dynamically created ones and how can I do this?
     


  11. AoC 2024 Day 23 - LAN Party - part 1 solved using Delphi XE7 

     

    I tweaked it a little by adding Color and Bold to the matched text. 

     

    In this build, the first letter or two-letter code can be entered to search for matches. 

    The left side pane is the original text feed from the website. I added the line numbers.

    The right side pane is the output results of the matches.  
     

    AdventOfCodeDay23_ByJohnLM_part-1.gif

     


  12. I liked the Day 19 and 23 puzzles.  They were easy to solve, but 19 was solved while I was at work while I was walking out into one of my isles to pack out products and where it came to me, but getting it out in code is still a challenge.  I know what I have to do but coding it is a real challenge.  And as for 23, I did solve it in around 12 minutes, but I found a "cosmetic" bug in the output and I am trying to fix that. Both of these are just part 1. 

    • Like 1

  13. re:  Day-23 puzzle -- Note, I am not complaining but giving my observations thus far. 

     

    I don't know.  I mean, it took me a moment to read through the instructions, about 1m:48s.  If I added that to my final time it took me to solve that puzzle, then it was 14 minutes to solve.  I was thinking 12 minutes and thought I could have made that Leaderboard--just joking. And that includes the building of the app, which I over-do too much in, everytime. Oh well.  I am usually pretty quick at thinking for a solution and then writing down (building) the code.  Well, there was a least two puzzles that I did solve.  And sometimes I will solve a puzzle during the coding part as I am building and working out the code, it may come to me.  But then I find issues or I don't quite like it, etc. etc.. 

     

    I believe that the languages those people are using are a lot more sugar-coated in solving the puzzles in AoC2024.  Take for example, Day 20's puzzle.  I watched most of this YT video: "tWhwcORztSY" and saw how supper quick this person was at solving it, not to mention his detailed step-by-step description of how he was solving different parts and how fast he was writing out the code.  I mean, the guy sounded like he wrote the puzzle!  Now mind you, I was not trying to solve that puzzle.  Reading through that puzzle part-way was enough to tell me I would never solve it at the time I was reading it.  I still believe that today, even after watching a video of it.

     

    If you look at the Leaderboard for Day 1's puzzle, you will see a time reading of "1) Dec 01  00:00:04 - qianxyz (AoC++)".  No way anyone could complete it after reading, writing and submitting in 4 seconds. That's got to be 4 minutes.

     

    I believe that the time layout I showed in my last post for "00:00:21" is: Days/Hours/Minutes. 

     

    As much as I could not solve most of these puzzles--and that's okay--I have enjoyed trying to solve them, to date.   I am still trying to solve some, while others are on the back-burner and I will eventually get back to those.  I have very much enjoyed this adventure. It gave me a chance to challenge myself and enjoy each day's puzzles.  I looked forward to each puzzle with antisipation every day, with only two days/puzzles left. 

     


  14. I am currently using Delphi XE7. I forgot to mention that. 

     

    Apparently, there is no switch to turn off debugging after a certain point within a given code block that I may be currently working on. 

     

    I saw this: {$D-}

     

    But that only works before a routine/function/procedure call.  I can't insert it between some code within a routine. And it doesn't seem to work when I tried.

    Oh well.

     

    I guess I can only do one thing that will help a little, and that is to use the following idea shown below using i:=i; multiple times, that in the event I do over-press the F8 key, I will catch it in time in order to stop myself from pressing F8 any further. 

    procedure TForm1.Button1Click(Sender: TObject);
    var i: integer;
    begin 
    1 
    * 2 -- begin debug breakpoint - i have a breakpoint set it. and i press F8 to setp through the lines of code. . .
    3 
    4 
    5 
    6 
    7 -- end debug breakpoint . . .until i reach this line, i want the debugging to stop
    8 
    9 i:=i;
    11 i:=i;
    12 i:=i;
    13 i:=i;
    14 i:=i;
    15 
    end; 

     


  15. Because I have arthritis in my fingers, they can be twitchy at times, and during debugging I can go past the point I want to debug and when that happens, other Units open up and I get lost and loose my focus. Its become quite irritating. 

     

    Say I am begging within the scope of a tbutton, and there may be 7 lines of code.  I don't want the debugging to continue outside that range or else it will continue loading various Units and that is creating extra work for me and causing me frustration. 

     

    procedure TForm1.Button1Click(Sender: TObject);
    begin

    1

    2 -- debugging started via F8. 

    3

    4

    5

    6

    7 -- stop debugging after this. so if i press F8, debugging will not continue to step past it 7. 

    8

    9

    end;


  16. Sorry Cornelius, I don't understand you point on "input file".  what is it?  And for different users?  Anyway.  I was not sharing my source code, if that is what you mean.  Actually, I would be ashamed to show it.  Also, I see no reason why I can not show my output log or report or final outcome, not when the website already shows it in their instructions. 

     

    >> Also, don't post the puzzle text input

    I don't understand what you are saying. 

     

    I'm getting ready to work on the Day-03 puzzle--I took a cellphone screenshot of the instructions and read it last night at work--It seems easy enough. Just some parsing of the string.  And I read (on reddit) that people were getting double-lines and were processing it wrong. And, no--I am not looking for answer on how to solve it or any other puzzle.  I would not read those if they are available, though those are in another language that I don't understand, nor how to read anyway. 

     

    Also, question:  where are the second parts I keep reading about? 

    I read bits here and there about part 1 and part 2.  But I don't see them in any of the days I have seen aready, 1-3. Or do you have to be at the website at a certain time to see it?  I don't know. 

×