如何在win32中使用ScreenToClient,而不是MFC?

时间:2013-06-05 08:05:39

标签: winapi

正如MSDN所说

BOOL ScreenToClient(
  _In_  HWND hWnd,
  LPPOINT lpPoint
);

ScreenToClient的第二个para是指向POINT的指针, 和PINT由MSDN说是

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

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

3 个答案:

答案 0 :(得分:6)

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

RECT r = ...;
MapWindowPoints(NULL, hWnd, (LPPOINT)&r, 2);

答案 1 :(得分: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;

答案 2 :(得分: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的角度来看,这不是最干净的东西,但这些结构必然保持二进制兼容。