• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 323
  • Last Modified:

redrawing form background

hi experts, I want to have the background of my prog update without using onpaint to draw the whole thing again because it's causing significant slowdown: I'm drawing a complex background directly to canvas, then have the user draw on the form. I think Onpaint is called to redraw background and as more shapes are drawn, things really slowdown. Also the form resizes and more of the background has to show. thanks
0
IOOI
Asked:
IOOI
  • 2
  • 2
  • 2
  • +2
2 Solutions
 
alikoankCommented:
You can do your drawing on a buffer, then copy buffer to actual canvas.
0
 
LRHGuyCommented:
The best bet is to keep your drawing on a canvas/bitmap, then you can copy it to the screen whenever needed.

This sample has the drawing in fBackgroupBitMap, it centers it in the window's client area.

procedure TfrmMainEstimator.FormPaint(Sender: TObject);
var
  w,h,bh,bw:integer;
begin
  { Center bitmap! }
  w:=ClientWidth;
  h:=ClientHeight;
  bw:=fBackgroundBitMap.Width;
  bh:=fBackgroundBitMap.Height;
  Canvas.CopyMode:=cmSrcCopy;
  Canvas.Draw((W-bw) div 2,(H-bh) div 2,fBackgroundBitMap);
end;

You could instead put the routine into the wm_EraseBackground event with the same results.

Hope that helps!
0
 
Ivanov_GCommented:
If you want your form repainted, you can just post WM_PAINT message like this:

SendMessage(Form1.Handle, WM_PAINT, 0, 0);
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

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

 
IOOIAuthor Commented:
alikoank or others: can you provide code for drawing on a buffer, then copying buffer to actual canvas? I'm hesitant to use bitmap as it can complicate other stuff I'm doing later in the prog. I've increased the points.
0
 
Slick812Commented:
hello  IOOI,  I am not sure that just doing your "Drawing" on a bitmap and then painting that bitmap on your display (Form I guess) will speed things up at all, if you have to do the drawing each time, if you could draw the bitmap ONE Time, then you can just draw the bitmap on the Form canvas. . . since it seems that it's your "Drawing" that is what is slow for you. . . I have drawn all sorts of things and for the most part these draw operations are really fast, even if I do very many of them, seems like you need a way to get your drawing to be faster. What sort of drawing is taking so long?
0
 
alikoankCommented:
create a TBitmap variable and draw your image onto it.

and in your Control's PaintWindow event copy this TBitmap to canvas.

like this:

xxx.PainWindow(DC: HDC);
var
  cnv:TCanvas;
begin
 ...
  cnv.Handle := DC;
  try
    ...
    cnv.CopyRect(Rect(...), MyBitmap.Canvas, Rect(...));
  finally
    cnv.Handle=0;
  end;
 ...
0
 
IOOIAuthor Commented:
hi Slick812,
Yes you're right in saying draw operations are pretty fast. Perhaps I had worded it wrong. It seems the way to go as you suggested is to draw the bitmap once and use it to repaint background.
thanks
0
 
LRHGuyCommented:
That is what I suggested...keeping the drawing in a bitmap and painting it when needed...
0
 
Slick812Commented:
OK, here is some code that might help, Iam not sure about what "Drawing" operations you do, this just draws lines, I use a TPaiintbox, but you can use the same events on your form


private
    { Private declarations }
    DisplayBmp: TBitmap; // this is bitmap to save all drawing operations
    MouseDraw: Boolean;
    mosePos: TPoint; // records last mouse Position




procedure TForm1.FormCreate(Sender: TObject);

begin
MouseDraw := False;
DisplayBmp := TBitmap.Create;
DisplayBmp.Canvas.Brush.Color := $6699DD;
DisplayBmp.Height := PaintBox2.Height;
DisplayBmp.Width := PaintBox2.Width;
DisplayBmp.Canvas.TextOut(20,20, 'PaintBox2 Bitmap');
end;


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeAndNil(DisplayBmp);
end;



procedure TForm1.PaintBox2Paint(Sender: TObject);
begin
// only draw the bitmap, no Drawing operations
PaintBox2.Canvas.Draw(0,0,DisplayBmp);
end;

procedure TForm1.PaintBox2MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
MouseDraw := True;
mosePos.x := X;
mosePos.y := Y;
PaintBox2.Canvas.Pen.Color := $FFCC33;
DisplayBmp.Canvas.Pen.Color := $FFCC33;
end;

procedure TForm1.PaintBox2MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
MouseDraw := False;
end;

procedure TForm1.PaintBox2MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
if MouseDraw then
  begin
// Draw on the PaintBox and Bitmap at the same time;
  PaintBox2.Canvas.MoveTo(mosePos.x, mosePos.y);
  DisplayBmp.Canvas.MoveTo(mosePos.x, mosePos.y);
  PaintBox2.Canvas.LineTo(X, Y);
  DisplayBmp.Canvas.LineTo(X, Y);
  mosePos.x := X;
  mosePos.y := Y;
  end;
end;
0

Featured Post

Industry Leaders: 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!

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