D7: paintbox in scrollbox

Posted on 2010-01-04
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
    LVL 25

    Expert Comment

    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

    Download link:
    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 22

    Accepted Solution

    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);

    Author Comment

    Update: I'm still testing this possible solution.

    Author Comment

    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

    ["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

    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

    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.

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    IT, Stop Being Called Into Every Meeting

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
    Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
    how to add IIS SMTP to handle application/Scanner relays into office 365.
    Sending a Secure fax is easy with eFax Corporate ( First, Just open a new email message.  In the To field, type your recipient's fax number You can even send a secure international fax — just include t…

    761 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

    Need Help in Real-Time?

    Connect with top rated Experts

    12 Experts available now in Live!

    Get 1:1 Help Now