D7: paintbox in scrollbox

Posted on 2010-01-04
Medium Priority
Last Modified: 2013-11-23
A paintbox in a scrollbox does not paint correctly, when the scrollbars are used. The objects replaced, may be partly repainted at different locations on the track they were replaced along (kind of shadowy). Especially when they move out of sight in the scrollbox (and paintbox).

Setting the scrollbars of the scrollbox to smooth does help for it shows from the immediate moment the visuals are moved, whether they will be painted correctly at their new locations. Now, I noticed that the vertical scrollbar set to smooth does work, but the horizontal one does not when it should. Then I thought maybe this is related to the main problem of painting.

I think it must be primarily related to the fact that paintboxes calculate from the top left and therefore do not allow positioning objects above and to the left, even though relatively speaking the objects should be in the correct domain even when scrolled out of sight.

Another idea is that repainting should not start from the moment the scrollbars are moved but only after their moving (using the mouse) has stopped. I would need an 'on stopscrolling' method but for some reason scrollboxes do not have 'on scroll' methods. This I cannot understand.

Thank you.
Question by:Ron_de_Weijze
  • 6
LVL 25

Expert Comment

ID: 26179532
can you post the application you have at this point, or if it's too big create a new sample app that shows your problem ?

Author Comment

ID: 26180113
Download link: http://www.pmm.nl/demo/PMM65sv.exe.
Test data: after installation in C:\Documents and Settings\User\My documents\My PMM files\Example project.
Open a sheet and scroll it so the objects disappear, then scroll back and that should show you the problem.
LVL 23

Accepted Solution

Ferruccio Accalai earned 2000 total points
ID: 26180712
Wath you're noticing is a known issue of TPaintBox when it's bigger than its TscrollBox parent.

I had a similar problen in the past, and as i've not found a good solution (not many time to search it really), i used a workaround that is to get the paintbox width and height in oncreate and then to repaint using these values in the onpaint event.

For example:

  Form1: TForm1;
  w, h: integer;


{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
  w := PaintBox1.Width;
  h := PaintBox1.Height;

procedure TForm1.PaintBox1Paint(Sender: TObject);
  with PaintBox1.Canvas do
    Brush.Style := bsSolid;
    Brush.Color := clBlue;
    Rectangle(0, 0, w, h);

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.


Author Comment

ID: 26185421
Update: I'm still testing this possible solution.

Author Comment

ID: 26199949
I added a bit of code. SB is the scrollbox. BlitRect is the top left corner moving from the origin at X0Y0 when the scrollbars are used. SecBlitRect has the XY measures of the PaintBox, via VisFormW and H and is fixed at the origin. Now, e.g., when the handle at the scrollbar is moved down, the adjusted origin TempPoint.Y is negative. This is (often) no problem as long as the object in the paintbox is visible. However, as soon as it passes the visibility border, it does become invisible and later is dislocated. This must be caused by the paintbox not being able to handle negative values.
procedure TDrawSheet.UpdateSheet(Proceed : Boolean);
   SecBlitRect, BlitRect : TRect;
   VisFormW, VisFormH : longint;
   ScrollPosH, ScrollPosV : longint;
   TempPoint : TPoint;
   VisFormW := ClientRect.Right;
   VisFormH := ClientRect.Bottom;
   ScrollPosH := SB_Sheet.HorzScrollBar.Position;
   ScrollPosV := SB_Sheet.VertScrollBar.Position;

   BlitRect.Left := ScrollPosH;
   BlitRect.Right := ScrollPosH + VisFormW;
   BlitRect.Top := ScrollPosV;
   BlitRect.Bottom := ScrollPosV + VisFormH;

   SecBlitRect.Left := 1;
   SecBlitRect.Right := VisFormW + 1;
   SecBlitRect.Top := 1;
   SecBlitRect.Bottom := VisFormH + 1;

   { Adjust Origins }
   TempPoint.X := 0 - ScrollPosH;
   TempPoint.Y := 0 - ScrollPosV;

   m_VCanvas.Origin := TempPoint;

Open in new window


Author Comment

ID: 26200001
["as soon as it passes the visibility border, it does become invisible" sorry for that! I mean it does not reappear after it should have been scrolled back into the visible area.]

Author Comment

ID: 26284510
Sometimes it helps just thinking out loud through the problem as ones sees it. That may change the perception and bring (the beginning of) a solution. So I try. An object is positioned in a paintbox at location xy relative to the top-left corner of the paintbox. The paintbox is in a scrollbox that can let the object in the paintbox scroll out of sight. For example, scrolling down moves the object up. The upward movement is realized by 'adding negative' values to the location xy of the object in the paintbox. Then, the object is no longer visible while the paintbox still is, showing different locations than the one where the object was. The coordinates of the object are now negative as seen from the paintbox' top left corner in the scrollbox. So it is as if the scrollbox relocates the paintbox' origin (top left corner). If that really were the origin of the paintbox, obviously the object would no longer exist. Apparently it becomes the origin upon scrolling down, for scrolling back up shows the object is gone from where it was. It pops up again when the screen is refreshed (I ALT-tab to another window and then go back again) or when scrolling it into and out of the paintbox is repeated a few times. However, then it is broken, as if one part is painted after another at a slightly shifted location.

Author Comment

ID: 26304595
There is a zoom function in the app that caused the problem. Without zooming, the problem disappears. Have not found out exactly why yet. Thank you all for trying to help me out.

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Suggested Courses

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question