[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 339
  • Last Modified:

How can I prevent TPaintbox graphics from being erased when obscured?

I have a situation where I have a TImage on a work surface.  The Timage may be moverd around on the work surface.  Over the whole work surface is a TPaintBox upon which the user can draw - both over and around the Timage.

It works well, except that if during the work the user passes another window over top, or drags the work surface partly off screen, the portion of the drawing on the TPaintBox that has been obscured is erased.

I know that I could save the contents of the TPaintBox to a Bitmap and restore it, but unless I do that constantly, how can I make sure that it is saved when needed?  

Is there a way to prevent the repaint that is erasing the TPaintBox?
0
DMTrump
Asked:
DMTrump
  • 3
  • 2
1 Solution
 
HypoCommented:
I don't think that it is the repaint that is erasing the data, it is the actual window that moves over the PaintBox that erases the data, the repaint just tries to restore the default TPaintBox control graphics. You can prohibit repaints fropm happening by adding your own message handler for WMPaint, that does nothing; but the effect you will get then is that the area that has been obscured will become white (undefined) like it does for an application that freezes.

My sugestion is that if you want to keep the contents of the TPaintBox whenever it has been obscured by another window, then you should redirect all the user painting to a Bitmaps canvas, which has the same size as the TPaintBox, and then just draw this Bitmap to the TPaintBox.Canvas, in the TPaintBox.OnPaint event.

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  PaintBox1.Canvas.Draw(0, 0, myBitmap);
end;


regards
Hypo
0
 
DMTrumpAuthor Commented:
I created a possible solution myself - but I'll leave the question open in case someone else has a better idea!

I wrote two procedures:

TraceSave is called upon the completion (mouseup, for instance) of any drawing routine.
procedure T_form.TraceSave;
var
  i, j: integer;
begin
  TraceSaved.Height := pbTrace.height;
  TraceSaved.Width := pbTrace.Width;
  BitBlt(TraceSaved.Canvas.Handle, 0, 0, pbTrace.Width, pbTrace.Height,
    pbTrace.Canvas.Handle, 0, 0, SRCCOPY);
end;

TraceBack is called from the the TPaintbox OnPaint event.
procedure T_form.TraceBack;
var
  i, j: integer;
begin
  BitBlt(pbTrace.Canvas.Handle, 0, 0, pbTrace.Width, pbTrace.Height,
    TraceSaved.Canvas.Handle, 0, 0, SRCCOPY);
end;

This seems to work fine - but is there a better way?

0
 
DMTrumpAuthor Commented:
Hypo, Thanks for that suggestion,  I may try that.  (less code than my way, I think) It is important, however that the user be able to observe the drawing as it happens - therefore I think I would have to draw <both> to the BitMap and to the Tpaintbox.  

However, my method would - however unlikely) make it possible for a another application to "pop up" over the drawing area and obscure a drawingoperation in progress.  

If I were to simultaneously draw to both the bitmap and the painbox, that could not happen.  

BTW, in my code, the TraceSaved is a global TBitMap, created and destroyed with the application.
0
 
HypoCommented:
The idea is that you draw on the bitmap when the user does his drawings, and then directly after, you drawn to the bitmap, you draw the bitmap to the PaintBox canvas... I've done this many times myself for custom controls, and it works fine for me :)

regards
Hypo
0
 
DMTrumpAuthor Commented:
Thanks for the help
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now