为什么SC_HSCROLL和SC_VSCROLL似乎在WM_SYSCOMMAND中切换?

问题描述 投票:2回答:1

我知道这是一个非常古老的东西,但我正在破坏我的大脑。有谁知道为什么会这样?

比方说,当滚动条鼠标点击通知通过WM_NCHITTEST - > WM_NCLBUTTONDOWN - > WM_SYSCOMMAND - > WM_HSCROLLWM_VSCROLL传播时,此链中的所有参数似乎都遵循文档,除了SC_HSCROLLSC_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 ++的证明。如果我单击此向下箭头:

enter image description here

这些是窗口收到的通知:

enter image description here

所有正确的除了SC_HSCROLL。 WTF?

c++ winapi scrollbar spy++ common-controls
1个回答
1
投票

如果在调试器下查找__int64 OnDwpNcLButtonDown(CThhemeWnd*, THEME_MSG*)可见下一个代码:

enter image description here

wParam = HTVSCROLL != HitTest ? SC_VSCROLL : SC_HSCROLL;
SendMessage(*, WM_SYSCOMMAND, (wParam | HitTest), *)

WM_SYSCOMMANDSC_VSCROLLSC_HSCROLL从这一点发送,但明显的代码包含逻辑错误 - SC_VSCROLLSC_HSCROLL混淆。

必须是正确的代码

wParam = HTVSCROLL == HitTest ? SC_VSCROLL : SC_HSCROLL;

在WM_SYSCOMMAND消息中,wParam参数的四个低位由系统内部使用。要在测试wParam的值时获得正确的结果,应用程序必须使用按位AND运算符将值0xFFF0与wParam值组合。

在这里可见,我们已经从WM_NCLBUTTONDOWN消息中找到了四个低位,这是来自WM_NCHITTEST消息返回

0xf087 - 这是SC_HSCROLL | HTVSCROLL,当在hscroll我们得到0xf076这是SC_VSCROLL | HTHSCROLL

这只是uxtheme.OnDwpNcLButtonDown中的windows bug

© www.soinside.com 2019 - 2024. All rights reserved.