Search code examples
c++winapiscrollbarspy++common-controls

Why are SC_HSCROLL and SC_VSCROLL seem to be switched in WM_SYSCOMMAND?


I know it's a really old stuff, but I'm wrecking my brain over it. Does anyone know why this is happening?

Say, when the scrollbar mouse click notification is propagated through WM_NCHITTEST -> WM_NCLBUTTONDOWN -> WM_SYSCOMMAND -> WM_HSCROLL or WM_VSCROLL, all parameters in this chain seem to follow documentation, except SC_HSCROLL and SC_VSCROLL for WM_SYSCOMMAND. So if I do:

//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");
    }
}

I seem to get vertical notification for horizontal and vice versa.

Here's the proof from Spy++. If I click this down arrow:

enter image description here

these are notifications that window receives:

enter image description here

All correct except SC_HSCROLL. WTF?


Solution

  • if look for __int64 OnDwpNcLButtonDown(CThhemeWnd*, THEME_MSG*) under debugger visible next code:

    enter image description here

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

    the WM_SYSCOMMAND with SC_VSCROLL or SC_HSCROLL sent from this point, but obvious code contain logical error - the SC_VSCROLL and SC_HSCROLL confused.

    correct code must be

    wParam = HTVSCROLL == HitTest ? SC_VSCROLL : SC_HSCROLL;
    

    also

    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.

    here visible that in place four low-order bits we have hit test code from WM_NCLBUTTONDOWN message, which is from WM_NCHITTEST message return

    0xf087 - this is SC_HSCROLL | HTVSCROLL , when on hscroll we got 0xf076 which is SC_VSCROLL | HTHSCROLL

    this is simply windows bug in uxtheme.OnDwpNcLButtonDown