如何获得 window 主菜单栏边界?

How to get window main menu bar bounds?

我的目标是从没有主菜单栏的外国应用程序中获取 window 的屏幕截图。我正在使用此代码:

BitBlt(Canvas.Handle, 0, 0, Width, Height, WinDC, xShift, yShift, SRCCOPY);

其中xShiftyShift的变量值我需要自己确定,因为windows在不同的应用中可以有不同的风格,或者系统可以有不同的主题。

所以我的问题是,如何获取 window 主菜单栏左下角的坐标(我的 xShiftyShift 变量需要)?这张图说明了这一点:

或者,有没有办法直接获取没有主菜单栏的 window 的客户端边界,而不需要这一步?

如果您有 window 句柄,您可以获得所需的所有信息。 GetClientRect 函数将为您提供 window 客户区,但左上角坐标将为 (0,0)。要将其转换为偏移量,您必须使用 ClientToScreen 函数获取该点的屏幕坐标,然后只需减去 window 屏幕坐标即可获得所需的偏移量。

var
  WindowRect, WindowClientRect: TRect;
  Origin: TPoint;
  Ofs: TPoint;

  Windows.GetWindowRect(Handle, WindowRect);
  Windows.GetClientRect(Handle, WindowClientRect);
  Origin := WindowClientRect.TopLeft;
  Windows.ClientToScreen(Handle, Origin);
  Ofs.X := Origin.X - WindowRect.Left;
  Ofs.Y := Origin.Y - WindowRect.Top;

因此调用您的 BitBlt 函数将如下所示

BitBlt(Canvas.Handle, 0, 0, WindowClientRect.Width, WindowClientRect.Height, WinDC, Ofs.X, Ofs.Y, SRCCOPY);

我不确定 TRect 在 Delphi 2010 中是否具有 WidthHeight 属性,因此您可能需要计算 Width 和 [= WindowClientRect 你自己的 17=]。

感谢@Dalija Prasnikar,工作代码是:

function WindowToBMP(WD: HWND ): TBitmap;
var
  WinDC: HDC;
  WindowRect, WindowClientRect: TRect;
  Origin: TPoint;
  Ofs: TPoint;
begin
    Result := TBitmap.Create;
    GetWindowRect(WD, WindowRect);
    GetClientRect(WD, WindowClientRect);
    Origin := WindowClientRect.TopLeft;
    ClientToScreen(WD, Origin);
    Ofs.X := Origin.X - WindowRect.Left;
    Ofs.Y := Origin.Y - WindowRect.Top;
    with Result, WindowClientRect do
    begin
        Width := WindowClientRect.Right - WindowClientRect.Left;
        Height := WindowClientRect.Bottom - WindowClientRect.Top;
        WinDC:=GetWindowDC(Wd);
        ShowWindow(Wd, SW_SHOW);
        BringWindowToTop(WD);
        try
            BitBlt( Canvas.Handle, 0, 0, Width, Height, WinDC, Ofs.X, Ofs.Y, SRCCOPY);
        finally
        end;
    end;
end;