2

正如 MSDN 所说

BOOL ScreenToClient(
  _In_  HWND hWnd,
  LPPOINT lpPoint
);

ScreenToClient 的第二个 para 是指向 POINT 的指针,而 MSDN 所说的 PINT 是

typedef struct tagPOINT {
  LONG x;
  LONG y;
} POINT, *PPOINT;

它只有 x 和 y。它不像 MFC ScreenToClient 函数,para 是一个 rect,而 rect 有宽度和高度。我很困惑如何使用 win32 ScreenToClient 功能。

4

3 回答 3

6

您可以使用MapWindowPoints()在单个操作中转换 RECT:

RECT r = ...;
MapWindowPoints(NULL, hWnd, (LPPOINT)&r, 2);
于 2013-06-05T15:44:02.157 回答
5

MFC 实际上有两种方法,它们是重载的。一个接受POINT结构,就像 Win32 函数一样,另一个接受RECT结构,两者的工作方式相同:它将每个点从屏幕映射到客户端。

如果您RECT想在不使用 MFC 的情况下获取客户端坐标,则只需手动执行,如下所示:

RECT rect = GetMyRect();

POINT rectTL;
rectTL.x = rect.left;
rectTL.y = rect.top;
ScreenToClient( hWnd, &rectTL );

POINT rectBR;
rectBR.x = rect.right
rectBR.y = rect.bottom;
ScreenToClient( hWnd, &rectBR );

rect.left   = rectTL.x;
rect.top    = rectTL.y;
rect.right  = rectBR.x;
rect.bottom = rectBR.y;
于 2013-06-05T08:12:31.450 回答
2

请注意,这RECT

typedef struct _RECT {
  LONG left;
  LONG top;
  LONG right;
  LONG bottom;
} RECT, *PRECT;

并且看起来像内存中的两个连续 POINT。因此,您可以做 MFC 源代码所做的事情,大约是。以下(现在我面前没有 MFC 源):

::ScreenToClient(hWnd, (POINT*)&rect->left);
::ScreenToClient(hWnd, (POINT*)&rect->right);

从 C 的角度来看,这不是最干净的事情,但这些结构必然会保持二进制兼容。

于 2013-06-05T08:12:26.633 回答