响应鼠标单击
如果用户在光标位于窗口工作区上时单击鼠标按钮,该窗口将收到以下消息之一。
消息 | 含义 |
---|---|
WM_LBUTTONDOWN | 按下左键 |
WM_LBUTTONUP | 松开左键 |
WM_MBUTTONDOWN | 按下中间按钮 |
WM_MBUTTONUP | 松开中间按钮 |
WM_RBUTTONDOWN | 按下右键 |
WM_RBUTTONUP | 松开右侧 |
WM_XBUTTONDOWN | 按下 XBUTTON1 或 XBUTTON2 |
WM_XBUTTONUP | 松开 XBUTTON1 或 XBUTTON2 |
回想一下,工作区是窗口中不包含框架的部分。 有关工作区的详细信息,请参阅什么是窗口?
鼠标坐标
在所有这些消息中,lParam 参数包含鼠标指针的 x 坐标和 y 坐标。 lParam 的最低 16 位包含 x 坐标,接下来的 16 位包含 y 坐标。 使用 GET_X_LPARAM 和 GET_Y_LPARAM 宏从 lParam 解压缩坐标。
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
这些宏已在标头文件 WindowsX.h 中定义。
在 64 位 Windows 上,lParam 是 64 位值。 不使用 lParam 的上 32 位。 如果 Windows 文档提到 lParam 的“低序单词”和“高阶单词”,则 64 位大小写表示低序和低序 32 位的单词。 宏提取正确的值,因此如果您使用它们,您将是安全的。
鼠标坐标以像素为单位,而不是与设备无关的像素 (DIP),并且相对于窗口的工作区进行测量。 坐标为符号值。 工作区上方和左侧的位置具有负坐标,如果跟踪窗口外的鼠标位置,这一点很重要。 我们将在后面的主题中了解如何在窗口外捕获鼠标移动。
其他标志
wParam 参数包含一个按位 OR 的标志,指示其他鼠标按钮的状态以及 Shift 和 Ctrl 键。
标记 | 含义 |
---|---|
MK_CONTROL | 按下了 CTRL 键。 |
MK_LBUTTON | 按下了鼠标左键。 |
MK_MBUTTON | 按下了鼠标中键。 |
MK_RBUTTON | 按下了鼠标右键。 |
MK_SHIFT | 按下了 SHIFT 键。 |
MK_XBUTTON1 | XBUTTON1 按钮已按下。 |
MK_XBUTTON2 | XBUTTON2 按钮已按下。 |
缺少标志意味着未按下相应的按钮或键。 例如,若要测试 CTRL 键是否按下:
if (wParam & MK_CONTROL) { ...
如果需要查找除 Ctrl 和 SHIFT 以外的其他键的状态,请使用键盘输入中介绍的 GetKeyState 函数。
WM_XBUTTONDOWN 和 WM_XBUTTONUP 窗口消息适用于 XBUTTON1 和 XBUTTON2。 wParam 参数表明单击了哪个按钮。
UINT button = GET_XBUTTON_WPARAM(wParam);
if (button == XBUTTON1)
{
// XBUTTON1 was clicked.
}
else if (button == XBUTTON2)
{
// XBUTTON2 was clicked.
}
双击
默认情况下,窗口不会收到双击通知。 若要接收双击,请在注册窗口类时在 WNDCLASS 结构中设置 CS_DBLCLKS 标志。
WNDCLASS wc = { };
wc.style = CS_DBLCLKS;
/* Set other structure members. */
RegisterClass(&wc);
如果按所示设置 CS_DBLCLKS 标志,窗口将收到双击通知。 双击由名称中带有“DBLCLK”的窗口消息表示。 例如,双击鼠标左键将生成以下消息序列:
实际上,通常会生成的第二个 WM_LBUTTONDOWN 消息将成为 WM_LBUTTONDBLCLK 消息。 为右侧、中间和 XBUTTON 按钮定义等效消息。
在收到双击消息之前,无法判断鼠标的第一次单击是双击的开始。 因此,双击操作应继续从第一次鼠标单击开始的操作。 例如,在 Windows Shell 中,单击一下会选择一个文件夹,而双击将打开该文件夹。
非客户端鼠标消息
为在窗口的非工作区内发生的鼠标事件定义一组单独的消息。 这些消息的名称中含有字母“NC”。 例如,WM_NCLBUTTONDOWN 是 WM_LBUTTONDOWN 的非客户端等效项。 典型的应用程序不会截获这些消息,因为 DefWindowProc 函数可正确处理这些消息。 但是,它们对于某些高级函数很有用。 例如,可以使用这些消息在标题栏中实现自定义行为。 如果确实处理这些消息,则通常应在处理后将其传递给 DefWindowProc 。 否则,应用程序将破坏标准功能,例如拖动或最小化窗口。
下一步