Recent

Author Topic: Trying to format a Memo with little success  (Read 1878 times)

JLWest

  • Hero Member
  • *****
  • Posts: 1259
Re: Trying to format a Memo with little success
« Reply #15 on: November 08, 2022, 03:54:04 pm »
@PascalDregon

in reply #10 I stated 'The procedure is coded to onDrawItem. ', but I still can't figure out how to call the Procedure.

Thanks.
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

wp

  • Hero Member
  • *****
  • Posts: 10454
Re: Trying to format a Memo with little success
« Reply #16 on: November 08, 2022, 04:24:36 pm »
Hey, why don't you look at the full project which i had added?

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   [...]
  4.   Listbox1.Style := lbOwnerDrawFixed;
  5.   Listbox1.OnDrawItem := @Listbox1DrawItem;
  6. end;

JLWest

  • Hero Member
  • *****
  • Posts: 1259
Re: Trying to format a Memo with little success
« Reply #17 on: November 08, 2022, 05:11:35 pm »
@wp

I don't know, I just missed it, I guess.

Line 3 What is that?  additional code  [...]
Line 4 Listbox1.Style := lbOwnerDrawFixed;  This is set in the Listbox in styles.
Line 5 Listbox1.OnDrawItem := @Listbox1DrawItem; If the procedure you wrote is coded to ONDrawitem why would it need to be set in code in FormCreate.

I'm sorry wp, I still don't know how to implement this procedure.


FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

wp

  • Hero Member
  • *****
  • Posts: 10454
Re: Trying to format a Memo with little success
« Reply #18 on: November 08, 2022, 06:13:42 pm »
OK, then slowly...

You do not call the Listbox1DrawItem procedure yourself - this is done by the listbox when it paints itself: It checks the value assigned to Style, and if that is one of the owner-drawn cases (such as lbOwnerDrawFixed) it fires the OnDrawItem event, and this finally leads to the Listbox1DrawItem code.

So, all you have to do are the following two steps:
- In the Object Inspector you set Listbox.Style to lbOwnerDrawFixed. Or you do this by code in the OnCreate event of the form (or similar)
- Double-click on the OnDrawItem event and paste the code from my Listbox1DrawItem procedure (and, of course, make the adjustments needed for your case - my code is just a sample, but should show the principle). If you already have the code somewhere you can simply assign the address of the procedure to the OnDrawItem event of the listbox: Listbox.OnDrawItem := @Listbox_ondrawitem_handler.

I am aware that having both kinds of assignements in my demo could be confusion, but I made the experience that changes made in the object inspector often are difficult to find, but the usual way in visual programming. Therefore, I kept both although only one method is sufficient.

JLWest

  • Hero Member
  • *****
  • Posts: 1259
Re: Trying to format a Memo with little success
« Reply #19 on: November 08, 2022, 06:54:01 pm »
OK - So I assume the listbox1 is loaded with data and the data looks like:

  ADD|Addstring
  Align|Assigment
  Carete|Position
...

Thanks for your patience.
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

wp

  • Hero Member
  • *****
  • Posts: 10454
Re: Trying to format a Memo with little success
« Reply #20 on: November 08, 2022, 07:01:59 pm »
OK - So I assume the listbox1 is loaded with data and the data looks like:

  ADD|Addstring
  Align|Assigment
  Carete|Position
...

Yes. I had used a tab character (#9) in my sample, but you can use the '|' as separator equally well. Just adapt the line which splits the parts at the separator. In the code in reply #9 this is happens in line 9.

JLWest

  • Hero Member
  • *****
  • Posts: 1259
Re: Trying to format a Memo with little success
« Reply #21 on: November 08, 2022, 07:55:41 pm »
@wp  Am I right in thinking the listbox doesn't have 2 columns, but an artificial drawn two columns. If the onClick event is programed there is no way to determine if the right or left column item was clicked.
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

wp

  • Hero Member
  • *****
  • Posts: 10454
Re: Trying to format a Memo with little success
« Reply #22 on: November 08, 2022, 08:07:35 pm »
Yes it's just a single column, painted such that the left part of the string is left-aligned and the right part is rightaligned within each row rectangle.

To determine whether the left or right part is clicked you first determine the clicked row index, then extract the combined string from the listbox items, split it again at the separator, measure the pixel width of both parts using Canvas.TextWidth, and finally check whether the clicked point is in the left or right part. OK - a bit of work, but not more than customdrawing of the items, and it's almost the same code.

If you want it easier you can try the stringgrid solution mentioned by Zvoni in reply #7. Assign a handler for the OnPrepareCanvas event to the right column in which you set the Alignment of the Canvas.TextStyle to taRightJustify.

JLWest

  • Hero Member
  • *****
  • Posts: 1259
Re: Trying to format a Memo with little success
« Reply #23 on: November 08, 2022, 08:47:24 pm »
@wp No for now I'll stay with the Listbox implementation and follow it thru. Interested to see what the final will look like. Sounds like the pixel measurement will require further help.

Thanks
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

wp

  • Hero Member
  • *****
  • Posts: 10454
Re: Trying to format a Memo with little success
« Reply #24 on: November 08, 2022, 10:15:11 pm »
A few hints:
  • Write a handler for the Listbox.OnMouseDown event which gives you the coordinates X, Y (relative to the listbox) where the click occured.
  • Call the TListbox method ItemAtPos which takes the clicked point (Point(X, Y)) as parameter and calculates the index of the clicked listbox item.
  • Call the TListbox method ItemRect which takes the item index as parameter and calculates the clicked item rectangle coordinates (again relative to the listbox).
  • Get the text of the clicked item from Listbox.Items[clickedindex]
  • Split the clicked item text into its two parts - you can do the same as in OnItemDraw.
  • Measure the width of the left part: w := Listbox.CanvasTextWidth(leftpart).
  • If the X coordinate of the mouse-down was less than ClickedRect.Left + w then the left text was clicked.
  • Measure the width of the right part: w := Listbox.CanvasTextWidth(rightpart)
  • If the X coordinate of the mouse-down was greater than ClickedRect.Right - w then the right text was clicked.

JLWest

  • Hero Member
  • *****
  • Posts: 1259
Re: Trying to format a Memo with little success
« Reply #25 on: November 08, 2022, 10:39:14 pm »
@wp - I think I can do that maybe.
I have a few questions on OnItemDraw.

I have the demo working and trying to adjust the width. Is is possible to indent from the left or do I have to be on the left edge of the listbox.
Probably because it's just a tstringlist.

How can I add more dots. Be nice if it was a variable.
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

wp

  • Hero Member
  • *****
  • Posts: 10454
Re: Trying to format a Memo with little success
« Reply #26 on: November 09, 2022, 12:00:07 am »
I have the demo working and trying to adjust the width. Is is possible to indent from the left or do I have to be on the left edge of the listbox.
Well, it's ownerdrawn - you decide what is painted.

If you look at the OnDrawItem code you see that it gets a rectangle as parameter, ARect. This is the area covered by the item. If you want to indent the text at the left by 20 pixels, simply do "inc(ARect.Left, 20)" and draw the text as the modified ARect.Left now. Note that there is already an "InflateRect(ARect, -4, 0)" in my code because I want a small distance to the very left and right of the listbox (InflateRect(ARect, dx, dy) subtracts dx from the left and adds dx to the right of the rect so that its width increases by 2*dx, the same with dy).

How can I add more dots. Be nice if it was a variable.
My code at first paints a full row of dots across the width of the listbox and finally paints the text over it (in my first version I had painted centered dots only between the two text parts - but this was annoying because the dots were moving when I increased the listbox width). And if you look carefully at the code you'll see that each dot actually is drawn as a dot plus a space because dots alone appeared to be too close to my feeling.
Code: Pascal  [Select][+][-]
  1.   DotWidth := Listbox1.Canvas.TextWidth('. ');   // "dot" plus "space", also in the next line
  2.   CenterPart := DupeString('. ', (ARect.Right - ARect.Left) div DotWidth);
  3.  
If you want them wider simply add one or two more spaces, or declare a variable for it:
Code: Pascal  [Select][+][-]
  1. var
  2.   dot: string;
  3. ...
  4.   dot := '  .  ';  // space space dot space space
  5. ...  
  6.   DotWidth := Listbox1.Canvas.TextWidth(dot);
  7.   CenterPart := DupeString(dot, (ARect.Right - ARect.Left) div DotWidth);

JLWest

  • Hero Member
  • *****
  • Posts: 1259
Re: Trying to format a Memo with little success
« Reply #27 on: November 09, 2022, 02:05:40 am »
@wp thanks

I'll work with it a while and see if I can figure it out.
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

Zvoni

  • Hero Member
  • *****
  • Posts: 1591
Re: Trying to format a Memo with little success
« Reply #28 on: November 09, 2022, 08:50:10 am »
Or use a StringGrid. See Sample-Project
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

JLWest

  • Hero Member
  • *****
  • Posts: 1259
Re: Trying to format a Memo with little success
« Reply #29 on: November 09, 2022, 05:30:46 pm »
That Grid looks a lot better than I thought it would. Thanks.

Or use a StringGrid. See Sample-Project
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

 

TinyPortal © 2005-2018