Как программно запретить Windows воспроизводить звук звукового сигнала по умолчанию, когда пользователь щелкает отключенное окно (отключено с помощью EnableWindow (hwnd, FALSE))?

Когда окно отключено с помощью EnableWindow(hwnd, FALSE) и пользователь щелкает по нему, воспроизводится звуковой сигнал по умолчанию. Я не хочу, чтобы это произошло. Как я могу программно отключить это поведение для текущего процесса на C/C++ с кодом Win32?


person user3756504    schedule 24.09.2020    source источник


Ответы (1)


Звуковой сигнал генерируется обработкой окна по умолчанию сообщения WM_SETCURSOR.

Из документов для WM_SETCURSOR:

Если младшее слово параметра lParam равно HTERROR, а старшее слово lParam указывает, что нажата одна из кнопок мыши, DefWindowProc вызывает функцию MessageBeep.

Чтобы предотвратить звуковой сигнал, ваша оконная процедура должна обрабатывать WM_SETCURSOR и не вызывать DefWindowProc в этих условиях.

person Jonathan Potter    schedule 24.09.2020
comment
Спасибо за ответ. Как ни странно, в моем цикле выполнения точка останова никогда не срабатывает: MSG msg; while(GetMessage(&msg, NULL, 0, 0) > 0) { if (msg.message==WM_SETCURSOR) { int i=0; // <--- breakpoint here never gets hit! } TranslateMessage(&msg); DispatchMessage(&msg); } - person user3756504; 24.09.2020
comment
@ user3756504 Сообщение WM_SETCURSOR отправлено в окно - вам нужно обработать это в оконной процедуре. не в цикле сообщений - person RbMm; 24.09.2020
comment
В моей оконной процедуре то же самое: WM_SETCURSOR никогда не принимается. Кстати, это вполне возможно сделать так, как я сделал выше, потому что цикл сообщений отправляется оконной процедуре. Я вижу сообщение с помощью Spy++, но оно никогда не появляется в моей оконной процедуре или цикле обработки сообщений, что является загадочной загадкой. У меня такое чувство, что это как-то связано с тем, что окно отключено. - person user3756504; 24.09.2020
comment
@user3756504 user3756504 некоторые сообщения возвращаются GetMessage или PeekMessage, и вам нужно вызвать DispatchMessage, чтобы передать их оконной процедуре. другие сообщения напрямую передаются оконной процедуре системой и не возвращаются Get[Peek]Message - вы никогда не просматриваете их в цикле сообщений. WM_SETCURSOR напрямую передается оконной процедуре. даже если он отключен. так что какая-то ошибка в вашем коде или вы используете неправильное окно - person RbMm; 24.09.2020
comment
Я исправляюсь, действительно работает в оконной процедуре. Итак, теперь код для избавления от MessageBeep: if (msg==WM_SETCURSOR && LOWORD(lParam)==WORD(HTERROR) && IsWindowEnabled(hwnd)==FALSE) {return TRUE;} Спасибо за помощь! - person user3756504; 24.09.2020