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

335 Views Asked by At

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?

1

There are 1 best solutions below

3
RbMm On BEST ANSWER

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