如何在位图上绘制整个表单?

时间:2013-05-22 19:24:29

标签: delphi

我想在TBitmap对象上绘制整个表单,包括标题栏和框架。

GetFormImage很酷,但它有两个问题:

  • 它也不会绘制窗框。
  • 隐藏表单时无效。

你有任何想法解决这些问题吗?

3 个答案:

答案 0 :(得分:5)

访问非客户区域的关键是GetWindowDC功能,其他一切都像往常一样 blitting

procedure TForm5.FormClick(Sender: TObject);
var
  Bitmap: TBitmap;
  DC: HDC;
  FileName: string;
begin
  Bitmap := TBitmap.Create;
  try
    Assert(HandleAllocated);
    DC := GetWindowDC(Handle);
    Win32Check(DC <> 0);

    Bitmap.SetSize(Width, Height);

    Win32Check(BitBlt(Bitmap.Canvas.Handle, 0, 0, Width, Height, DC, 0, 0, SRCCOPY));

    FileName := Name + '.' + GraphicExtension(TBitmap);
    Bitmap.SaveToFile(FileName);

    ShellExecute(HWND_DESKTOP, nil, PChar(FileName), nil, nil, SW_NORMAL);
  finally
    ReleaseDC(Handle, DC);
    Bitmap.Free;
  end;
end;

对于隐藏(未绘制!)窗口的第二种情况 - 请参阅RRUZ的评论。

答案 1 :(得分:1)

这是我使用过的一个你可能觉得有用的功能。

编辑:哎呀我没有完全阅读这个问题。这可能不适用于隐藏的窗口,但我不确定除非表单可以绘制框架本身,否则它不会,操作系统不会。

function GetScreenShot(const aWndHandle:THandle; AeroAware:boolean=true):TBitmap;
var
  wWindow: HDC;
  wRect : TRect;
  wDesktop : THandle;
begin
  Result  := TBitmap.Create;
  try
    if AeroAware then
      wDesktop := GetDesktopWindow
    else
      wDesktop := aWndHandle;

    wWindow := GetDC(wDesktop);
    try
      Result.PixelFormat := pf32bit;
      GetWindowRect(aWndHandle, wRect);
      Result.Width := wRect.Right-wRect.Left;
      Result.Height := wRect.Bottom-wRect.Top;
      if AeroAware then
        BitBlt(Result.Canvas.Handle, 0, 0, Result.Width, Result.Height, wWindow, wRect.Left, wRect.Top, SRCCOPY)
      else
        BitBlt(Result.Canvas.Handle, 0, 0, Result.Width, Result.Height, wWindow, 0, 0, SRCCOPY);
      Result.Modified := True;
    finally
      ReleaseDC(wDesktop, wWindow);
    end;
  except
    Result.Free;
    Result := nil;
  end;
end;

答案 2 :(得分:1)

关于隐藏时捕获表单图像,请使用

AlphaBlend := true;
AlphaBlendValue := 0;

显示表单。 用户将看不到表单,但GetFormImage()将捕获其画布。 我认为这也适用于“OnTheFly”的建议。