#c #winapi #scrollbar #spy #common-controls
#c #winapi #полоса прокрутки #spy #общие элементы управления
Вопрос:
Я знаю, что это действительно старый материал, но я ломаю над этим голову. Кто-нибудь знает, почему это происходит?
Скажем, когда уведомление о щелчке мыши на полосе прокрутки передается через 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 amp; 0xFFF0;
if(uiCmd == SC_HSCROLL)
{
TRACE(L"Horiz scrolln");
}
else if(uiCmd == SC_VSCROLL)
{
TRACE(L"Vertical scrolln");
}
}
Кажется, я получаю вертикальное уведомление для горизонтального и наоборот.
Вот доказательство от Spy . Если я нажму на эту стрелку вниз:
это уведомления, которые получает window:
Все правильно, за исключением SC_HSCROLL
. WTF?
Комментарии:
1. Что это за элемент управления? Это обычный список Win32, ListView или что-то пользовательское. Можете ли вы опубликовать MVCE (минимальный, полный, проверяемый пример).
2. Кроме того, что вы действительно пытаетесь сделать? Как вы можете видеть, сообщение WM_VSCROLL приходит после SYSCOMMAND.
3. @selbie /: Это
richedit
Ответ №1:
если искать __int64 OnDwpNcLButtonDown(CThhemeWnd*, THEME_MSG*)
в отладчике, виден следующий код:
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 с помощью побитового оператора AND .
здесь видно, что вместо четырех младших битов мы получили тестовый код из WM_NCLBUTTONDOWN
сообщения, который является результатом WM_NCHITTEST
возврата сообщения
0xf087
— это SC_HSCROLL | HTVSCROLL
, когда в hscroll мы получили 0xf076
, который SC_VSCROLL | HTHSCROLL
это просто ошибка Windows в uxtheme.OnDwpNcLButtonDown
Комментарии:
1. Интересно. И это было там с тех пор, idk, Windows XP или около того, и никто этого не заметил? В любом случае, спасибо за подтверждение. Я думал, что мне «мерещится» 🙂 Хотя, если ошибка в
uxtheme.dll
, означает ли это, что если процесс не тематический, тоSC_VSCROLL
иSC_HSCROLL
будет отправлен правильно?2. @c00000fd — просто посмотрите на этот ox xp — та же ошибка .
3. @c00000fd — если процесс не тематический — даже не проверяйте .. просто нужна обработка
WM_VSCROLL
иWM_HSCROLL
я думаю.