* * *

Author Topic: Problem with TGroupBox and TPaintBox  (Read 826 times)

flaza

  • New member
  • *
  • Posts: 45
Problem with TGroupBox and TPaintBox
« on: April 23, 2017, 10:56:39 am »
Hi.
I'm using Lazarus 1.6.4 on Windows10. I have a form with a groupbox with a listbox, a bevel and a paintbox in the bevel. The paintbox must show text depending on the selected item in the listbox. So far so good. But when I click in teh free area of the groupbox or in the area of the painbox, the paintbox repaints itself, thus losing the text.
I have a demo attached. in that demo I have 3 situations. A listbox and bevel/paintbox directly on the form, a listbox and bevel/paintbox in a groupbox, and a listbox and bevel/paintbox on a panel. On the form and on the panel all goes wel.
Is this a bug or am I missing something?
By the way, I've tried changing the cursor in OnMouseEnter and OnMpouseLeave, but that had no positive effect.

sky_khan

  • Guest
Re: Problem with TGroupBox and TPaintBox
« Reply #1 on: April 23, 2017, 03:16:36 pm »
You should do the painting in paintbox's OnPaint event. Move the code which paints on paintbox to that event, and call Invalidate method of paintbox when listbox changes.

wp

  • Hero Member
  • *****
  • Posts: 3727
Re: Problem with TGroupBox and TPaintBox
« Reply #2 on: April 23, 2017, 03:24:16 pm »
This is because you paint outside the OnPaint event of the Paintbox. While some widgetsets even don't allow this it is not forbidden in Windows, but you must be aware that every system request which is outside your control will erase the paintbox. If the user drags another form across your paintbox the paintbox will get messages to repaint itself, i.e. it will execute the code that you added to the OnPaint event - the other code in ListboxSelectinChange will not be executed, and thus your text must disappear.

you must extend the OnPaint method to contain all the other drawing code, and in the ListboxOnChange you simple call Invalidate of the Paintbox corresponding to the selected listbox item. Maybe something like this:
Code: Pascal  [Select]
  1. procedure TForm1.PaintBoxPaint(Sender: TObject);
  2. var
  3.   pb: TPaintBox;
  4.   txt: String;
  5. begin
  6.   pb := Sender as TPaintBox;
  7.   pb.Canvas.Brush.Color := clMoneyGreen;
  8.   pb.Canvas.FillRect(ClientRect);
  9.   pb.Canvas.Font.name := 'Tahoma';
  10.   pb.Canvas.Font.Color := clBlue;
  11.   if pb = Paintbox1 then
  12.     txt := Listbox.Items[0]
  13.   else if pb = Paintbox2 then
  14.     txt := Listbox.Items[1]
  15.   else if pb = Paintbox3 then
  16.     txt := Listbox.Items[2]
  17.   else
  18.     exit
  19.   TextOut(0, 0, txt);
  20. end;
  21.  
  22. procedure TForm1.ListBoxSelectionChange(Sender: TObject; User: Boolean);
  23. begin
  24.   (Sender as TListbox).Invalidate;
  25. end;  
Lazarus trunk / fpc 3.0.0 / Win32

flaza

  • New member
  • *
  • Posts: 45
Re: Problem with TGroupBox and TPaintBox
« Reply #3 on: April 24, 2017, 06:32:10 pm »
Thx.
Your solution works, except one mistake. In the procedure ListBoxSelectionChange I must call PaintBox.Invalidate and not ListBox.Invalidate. :D

wp

  • Hero Member
  • *****
  • Posts: 3727
Re: Problem with TGroupBox and TPaintBox
« Reply #4 on: April 24, 2017, 06:56:34 pm »
I see another error: in line 19, there's "TextOut(...)" - this would paint the text on the form. you must call "pb.Canvas.TextOut(...)" instead.
Lazarus trunk / fpc 3.0.0 / Win32

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus