我有一个创建Windows托盘图标的应用程序。当用户右键单击它时,将显示上下文菜单。应用程序正常工作,直到从控制面板完成DPI缩放。例如。当DPI缩放设置为150%(我登录时的缩放值)时,上下文菜单将正确显示,但是当我将DPI缩放更改为125%时(无需注销并再次记录 - 退出并再次登录后)他们同意),上下文菜单被移位,并显示在远离托盘图标的位置。如果我使用GetCursorPos()
代替GET_X_LPARAM(wParam)
和GET_Y_LPARAM(wParam)
来获取鼠标坐标,则不会发生这种情况。
关于NOTIFYICONDATA
(https://msdn.microsoft.com/en-us/library/windows/desktop/bb773352(v=vs.85).aspx)数据结构的MSDN文档在处理 GET_X_LPARAM(wParam)
的回调函数中说and GET_Y_PARAM(wParam)
,uCallbackMessage
应该给出right-mouse-button
点击事件的X和Y坐标(用于调用托盘图标的上下文菜单)。当DPI以上述方式改变时,不会发生这种情况。 GetCursorPos()
然而继续提供正确的价值。
我觉得他们应该总是报告相同的价值。
编辑1 - 假设在右键单击后鼠标没有移动,在这种情况下两者都应该给出相同的坐标。
编辑2 - Repro(有关复制错误的信息)
查看以下开源项目Picotorrent。 在NotifyIconController.cpp::NotifyIconController::Execute()中,我添加了以下代码行来打印GET_X_LPARAM()和GetCursorPos()返回的值(image中突出显示的代码)。
TCHAR debug_string[50];
_stprintf_s(debug_string,sizeof(debug_string), _T("\n\n[wParam :(x,y)=(%d,%d)]\n"), GET_X_LPARAM(wParam), GET_Y_LPARAM(wParam));
OutputDebugString(debug_string);
POINT pt;
GetCursorPos(&pt);
_stprintf_s(debug_string,sizeof(debug_string),_T("[GetCursorPos:(x,y)=(%d,%d)]\n"), pt.x, pt.y);
OutputDebugString(debug_string);
程序Picotorrent在运行时会创建一个托盘图标。当用户右键单击托盘图标时,在单击时鼠标指针的位置上会显示一个上下文菜单。截至目前,要显示上下文菜单,使用GET_X_LPARAM(wParam)和GET_Y_LPARAM(wParam)获取点击的X,Y坐标。
请参阅以下屏幕截图,其中显示了不同DPI缩放值下托盘图标的上下文菜单的位置。
下图显示了DPI缩放率为150%时上下文菜单的位置。这是我登录系统时的DPI缩放值。
下图显示了DPI缩放更改为125%时上下文菜单的位置。请注意,Windows告诉我注销,然后重新登录。但由于我们的任务是研究为什么GET_X_LPARAM()和GetCursorPos()没有显示相同的值(无论是对还是错,无所谓)。另请注意,托盘图标附近不再显示上下文菜单。请记住,我在这里使用GET_X_LPARAM(wParam)和GET_Y_LPARAM(wParam)来获取X和Y坐标以显示菜单,而不是GetCursorPos()。
现在,让我们在调试器的输出窗口中看到输出。
[wParam :(x,y)=(1539,1045)]
[GetCursorPos:(x,y)=(1539,1045)]
[wParam :(x,y)=(1606,1054)]
[GetCursorPos:(x,y)=(1927,1265)]
另外,请参阅以下屏幕截图。
从输出中我们可以清楚地看到,最初GET_X_LPARAM()和GetCursorPos()同意坐标的值,但是当缩放值改变时,它们不会。