Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Canvas does not allow drawing

I want to Draw a Screenshot from the entire screen to a TForm1 Canvas.

This code works well in Delphi XE3

procedure TForm1.Button1Click(Sender: TObject);
var
  c,scr: TCanvas;
  r,r2: TRect;
begin

  c := TCanvas.Create;
  scr := TCanvas.Create;
  c.Handle := GetWindowDC(GetDesktopWindow);
  try

    r := Rect(0, 0, 200, 200);
    form1.Canvas.CopyRect(r, c, r);

  finally
    ReleaseDC(0, c.Handle);
    c.Free;
  end;

Now I want to copy the screenshot to another canvas first. Is there a way to do this without getting this error?

procedure TForm1.Button1Click(Sender: TObject);
var
  c,scr: TCanvas;
  r,r2: TRect;
begin

  c := TCanvas.Create;
  scr := TCanvas.Create;
  c.Handle := GetWindowDC(GetDesktopWindow);
  try

    r := Rect(0, 0, 200, 200);

    scr.CopyRect(r,c,r); <-- Error, canvas does not allow drawing
    form1.Canvas.CopyRect(r, scr, r); <-- Error, canvas does not allow drawing

  finally
    ReleaseDC(0, c.Handle);
    c.Free;
  end;
like image 655
Bob Avatar asked Apr 04 '13 12:04

Bob


2 Answers

If you need to work with an additional canvas you will have to assign a HDC e.g.

var
  WindowHandle:HWND;
  ScreenCanvas,BufferCanvas: TCanvas;
  r,r2: TRect;
  ScreenDC,BufferDC :HDC;
  BufferBitmap : HBITMAP;
begin
  WindowHandle := 0;
  ScreenCanvas := TCanvas.Create;
  BufferCanvas := TCanvas.Create;

  ScreenDC:=GetWindowDC(WindowHandle);
  ScreenCanvas.Handle := ScreenDC;

  BufferDC := CreateCompatibleDC(ScreenDC);
  BufferCanvas.Handle := BufferDC;
  BufferBitmap := CreateCompatibleBitmap(ScreenDC,
                     GetDeviceCaps(ScreenDC, HORZRES),
                     GetDeviceCaps(ScreenDC, VERTRES));
  SelectObject(BufferDC, BufferBitmap);

  try
    r := Rect(0, 0, 200, 200);
    BufferCanvas.CopyRect(r,ScreenCanvas,r);
    form1.Canvas.CopyRect(r, BufferCanvas, r);
  finally
    ReleaseDC(WindowHandle, ScreenCanvas.Handle);
    DeleteDC(BufferDC);
    DeleteObject(BufferBitmap);
    BufferCanvas.Free;
    ScreenCanvas.Free;
  end;
end;
like image 124
bummi Avatar answered Sep 20 '22 08:09

bummi


It's a time to toss my solution into the pot!

procedure TForm1.FormClick(Sender: TObject);
var
  ScreenCanvas: TCanvas;
begin
  ScreenCanvas := TCanvas.Create;
  try
    ScreenCanvas.Handle := GetWindowDC(GetDesktopWindow);
    Win32Check(ScreenCanvas.HandleAllocated);
    Canvas.CopyRect(Canvas.ClipRect, ScreenCanvas, ScreenCanvas.ClipRect);
  finally
    ReleaseDC(GetDesktopWindow, ScreenCanvas.Handle);
    ScreenCanvas.Free;
  end;
end;
like image 29
OnTheFly Avatar answered Sep 20 '22 08:09

OnTheFly