DMTrump
asked on
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?
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?
ASKER
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.H andle, 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.Hand le, 0, 0, pbTrace.Width, pbTrace.Height,
TraceSaved.Canvas.Handle, 0, 0, SRCCOPY);
end;
This seems to work fine - but is there a better way?
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.H
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.Hand
TraceSaved.Canvas.Handle, 0, 0, SRCCOPY);
end;
This seems to work fine - but is there a better way?
ASKER
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.
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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for the help
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(Send
begin
PaintBox1.Canvas.Draw(0, 0, myBitmap);
end;
regards
Hypo