Почему SC_HSCROLL и SC_VSCROLL переключаются в WM_SYSCOMMAND? - PullRequest
2 голосов
/ 05 апреля 2019

Я знаю, что это действительно старая вещь, но я ломаю голову над этим. Кто-нибудь знает, почему это происходит?

Скажем, когда уведомление о щелчке мыши на полосе прокрутки распространяется через 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 ++. Если я нажму эту стрелку вниз:

enter image description here

это уведомления, которые получает окно:

enter image description here

Все правильно, кроме SC_HSCROLL. WTF?

1 Ответ

1 голос
/ 05 апреля 2019

, если ищите __int64 OnDwpNcLButtonDown(CThhemeWnd*, THEME_MSG*) под отладчиком, виден следующий код:

enter image description here

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;

также

В WM_SYSCOMMAND сообщениях четыре младших бита wParam параметр используется внутри системы. Чтобы получить правильный результат при тестировании значения wParam , приложение должно объединить значение 0xFFF0 со значением wParam с использованием побитового И оператор.

здесь видно, что вместо четырех младших битов мы попали в тестовый код из сообщения WM_NCLBUTTONDOWN, то есть из WM_NCHITTEST возврата сообщения

0xf087 - это SC_HSCROLL | HTVSCROLL, когда на hscroll мы получили 0xf076, что SC_VSCROLL | HTHSCROLL

это просто ошибка Windows в uxtheme.OnDwpNcLButtonDown

...