为什么 SC_HSCROLL 和 SC_VSCROLL 似乎在 WM_SYSCOMMAND 中切换了?
Why are SC_HSCROLL and SC_VSCROLL seem to be switched in WM_SYSCOMMAND?
我知道这是一个非常古老的东西,但我正在为它绞尽脑汁。有谁知道为什么会这样?
说,当滚动条鼠标点击通知通过 WM_NCHITTEST
-> WM_NCLBUTTONDOWN
-> WM_SYSCOMMAND
-> WM_HSCROLL
或 WM_VSCROLL
传播时,所有此链中的参数似乎遵循文档,除了 SC_HSCROLL
和 SC_VSCROLL
用于 WM_SYSCOMMAND
。所以如果我这样做:
//From within WndProc
if(message == WM_SYSCOMMAND)
{
UINT uiCmd = wParam & 0xFFF0;
if(uiCmd == SC_HSCROLL)
{
TRACE(L"Horiz scroll\n");
}
else if(uiCmd == SC_VSCROLL)
{
TRACE(L"Vertical scroll\n");
}
}
我似乎收到水平方向的垂直通知,反之亦然。
这是来自 Spy++ 的证据。如果我点击这个向下箭头:
这些是 window 收到的通知:
除了 SC_HSCROLL
之外,其他都正确。 WTF?
如果在调试器下查找 __int64 OnDwpNcLButtonDown(CThhemeWnd*, THEME_MSG*)
可见下一个代码:
wParam = HTVSCROLL != HitTest ? SC_VSCROLL : SC_HSCROLL;
SendMessage(*, WM_SYSCOMMAND, (wParam | HitTest), *)
WM_SYSCOMMAND
与 SC_VSCROLL
或 SC_HSCROLL
从此处发送,但明显的代码包含逻辑错误 - SC_VSCROLL
和 SC_HSCROLL
混淆。
正确的代码必须是
wParam = HTVSCROLL == HitTest ? SC_VSCROLL : SC_HSCROLL;
还有
In WM_SYSCOMMAND messages, the four low-order bits of the wParam
parameter are used internally by the system. To obtain the correct
result when testing the value of wParam, an application must combine
the value 0xFFF0 with the wParam value by using the bitwise AND
operator.
这里可见,我们从 WM_NCLBUTTONDOWN
message, which is from WM_NCHITTEST
消息 return
中命中了测试代码的四个低位
0xf087
- 这是 SC_HSCROLL | HTVSCROLL
,在 hscroll 上我们得到 0xf076
即 SC_VSCROLL | HTHSCROLL
这只是 windows uxtheme.OnDwpNcLButtonDown
中的错误
我知道这是一个非常古老的东西,但我正在为它绞尽脑汁。有谁知道为什么会这样?
说,当滚动条鼠标点击通知通过 WM_NCHITTEST
-> WM_NCLBUTTONDOWN
-> WM_SYSCOMMAND
-> WM_HSCROLL
或 WM_VSCROLL
传播时,所有此链中的参数似乎遵循文档,除了 SC_HSCROLL
和 SC_VSCROLL
用于 WM_SYSCOMMAND
。所以如果我这样做:
//From within WndProc
if(message == WM_SYSCOMMAND)
{
UINT uiCmd = wParam & 0xFFF0;
if(uiCmd == SC_HSCROLL)
{
TRACE(L"Horiz scroll\n");
}
else if(uiCmd == SC_VSCROLL)
{
TRACE(L"Vertical scroll\n");
}
}
我似乎收到水平方向的垂直通知,反之亦然。
这是来自 Spy++ 的证据。如果我点击这个向下箭头:
这些是 window 收到的通知:
除了 SC_HSCROLL
之外,其他都正确。 WTF?
如果在调试器下查找 __int64 OnDwpNcLButtonDown(CThhemeWnd*, THEME_MSG*)
可见下一个代码:
wParam = HTVSCROLL != HitTest ? SC_VSCROLL : SC_HSCROLL;
SendMessage(*, WM_SYSCOMMAND, (wParam | HitTest), *)
WM_SYSCOMMAND
与 SC_VSCROLL
或 SC_HSCROLL
从此处发送,但明显的代码包含逻辑错误 - SC_VSCROLL
和 SC_HSCROLL
混淆。
正确的代码必须是
wParam = HTVSCROLL == HitTest ? SC_VSCROLL : SC_HSCROLL;
还有
In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are used internally by the system. To obtain the correct result when testing the value of wParam, an application must combine the value 0xFFF0 with the wParam value by using the bitwise AND operator.
这里可见,我们从 WM_NCLBUTTONDOWN
message, which is from WM_NCHITTEST
消息 return
0xf087
- 这是 SC_HSCROLL | HTVSCROLL
,在 hscroll 上我们得到 0xf076
即 SC_VSCROLL | HTHSCROLL
这只是 windows uxtheme.OnDwpNcLButtonDown