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:
these are notifications that window receives:
All correct except SC_HSCROLL
. WTF?
if look for __int64 OnDwpNcLButtonDown(CThhemeWnd*, THEME_MSG*)
under debugger visible next code:
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