在WM_LBUTTONDOWN消息中获取鼠标坐标

5

以下是 MSG 的结构:

typedef struct tagMSG {
  HWND   hwnd; 
  UINT   message; 
  WPARAM wParam; 
  LPARAM lParam; 
  DWORD  time; 
  POINT  pt; 
} MSG, *PMSG; 

消息的处理流程如下:
long WINAPI WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam)

我的问题: 在消息过程中,为什么不将POINT变量传递给窗口过程,如何找到鼠标的POINT?通过GetCursorPos()吗?我发现一些示例直接通过LOWORD(lParam), HIWORD(lParam)获取它..你能告诉我相关信息吗?谢谢...

我看到有人这样写,这是正确的吗?我不确定:

RECT rect1;
long WINAPI WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam)
{
    HDC hDC;        
    WORD x,y;   
    PAINTSTRUCT ps;     

    x = LOWORD(lParam); 
    y = HIWORD(lParam);

    switch(iMessage)
    {
    case WM_LBUTTONDOWN:
        if(wParam&MK_CONTROL)
        {
            rect1.left = x; 
            rect1.top = y;
        }
        else if(wParam&MK_SHIFT)
        {
            rect1.left = x; 
            rect1.top = y;
        }
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    default:
        return(DefWindowProc(hWnd,iMessage,wParam,lParam));
    }
    return 0;
}

你的问题前半部分和后半部分有什么关系? - Mahmoud Al-Qudsi
我只想说,当我们调用GetMessage(xx)时,我们得到了鼠标指针,但在处理函数中,它消失了,为什么Windows会这样做?我的英语很差,我说的清楚吗?谢谢... - Mr.Tu
我可以根据你的标题投反对票吗? - Deanna
我也已将你的“process function”更正为“window procedure”,因为这样只会更加混淆事情。 - Deanna
2个回答

8
在处理函数中,为什么不将POINT变量传递给处理函数,如何找到鼠标的POINT?
如果您真的想要获取这些信息,有单独的函数来检索它们。大多数消息处理程序不处理鼠标输入,并且对于几乎永远不会使用它们的消息处理程序来说,传递额外的参数是没有意义的。(可以认为WndProc应该被定义为采用MSG*; 我不知道其设计的原因,但我猜测随着时间的推移,成员被添加到MSG结构中。)
通过GetCursorPos()吗?

不。GetCursorPos将返回鼠标光标的当前位置,这可能与生成消息时的位置不同。您应该使用GetMessagePos。(这类似于GetAsyncKeyStateGetKeyState之间的区别。)

类似地,消息处理程序可以通过GetMessageTime获取消息时间。


@Mr.Tu:在你的例子中,lParamwParam的含义取决于消息类型,所以在检查消息类型之前尝试提取坐标数据会非常误导人。并且使用LOWORDHIWORD来提取坐标是错误的;您需要使用GET_X_LPARAMGET_Y_LPARAM来正确处理多监视器系统上的负坐标。 - jamesdlin
1
嗯,有宏可以做这个事情。LPARAM 的高位是 x,低位是 y(如果我没记错的话)。请参见 http://msdn.microsoft.com/en-us/library/windows/desktop/ms645607%28v=vs.85%29.aspx。 - johnathan
@johnathon:嗯?是的,正如我在评论中提到的那样(以及你链接页面上提到的那样),这些宏是GET_X_LPARAMGET_Y_LPARAM - jamesdlin

4

坐标并没有消失,它们在lParam中。请参阅MSDN上的WM_MOUSEMOVE消息

A window receives this message through its WindowProc function.
...
lParam

    The low-order word specifies the x-coordinate of the cursor.
The coordinate is relative to the upper-left corner of the client area.

    The high-order word specifies the y-coordinate of the cursor.
The coordinate is relative to the upper-left corner of the client area.
...
Use the following code to obtain the horizontal and vertical position:

xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);

是的,它是正确的,因为它仅限于WM_MOUSEMOVE消息。如果它不属于鼠标消息,例如WM_KEYDOWN、WM_CHAR,那么我也可以这样做吗? xPos = GET_X_LPARAM(lParam); yPos = GET_Y_LPARAM(lParam); 感谢您的回答... - Mr.Tu
为什么不直接阅读关于WM_KEYDOWN消息WM_CHAR消息的内容呢? - Alexey Frunze
那个更新如何使问题不同,如果我们不知道它应该做什么,而且rect1未定义,我们怎么知道代码是否正确? - Alexey Frunze
哦,对不起,我忘记了在 process-function 之前定义了 rect1,RECT rect1; - Mr.Tu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接