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

#c #windows #winapi #windowing

#c #Windows #winapi #управление окнами

Вопрос:

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

Ответ №1:

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

Из docs для WM_SETCURSOR:

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

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

Комментарии:

1. Спасибо за ответ. Забавно, что в моем цикле выполнения точка останова никогда не попадает: MSG msg; while(GetMessage(amp;msg, NULL, 0, 0) > 0) { if (msg.message==WM_SETCURSOR) { int i=0; // <--- breakpoint here never gets hit! } TranslateMessage(amp;msg); DispatchMessage(amp;msg); }

2. @user3756504 WM_SETCURSOR сообщение отправляется в окно — вам нужно обработать это в процедуре window. не в цикле сообщений

3. То же самое и в моей оконной процедуре: WM_SETCURSOR никогда не принимается. Кстати, это вполне возможно сделать так, как я сделал выше, потому что цикл отправки сообщений отправляется в оконную процедуру. Я вижу сообщение с помощью Spy , но оно никогда не отображается в моей оконной процедуре или цикле сообщений, что является загадочной загадкой. У меня такое чувство, что это как-то связано с тем, что окно отключено.

4. @user3756504 некоторые сообщения возвращаются с помощью GetMessage или PeekMessage , и вам нужно вызвать DispatchMessage процедуру передачи его в окно. другие сообщения напрямую передаются в оконную процедуру системой и не возвращаются Get[Peek]Message — вы никогда не просматриваете цикл сообщений. WM_SETCURSOR прямой переход к оконной процедуре. даже если оно отключено. итак, какая-то ошибка в вашем коде или вы используете неправильное окно

5. Я исправлен, действительно, он работает в оконной процедуре. Итак, код, позволяющий избавиться от сигнала сообщения, теперь: if (msg==WM_SETCURSOR amp;amp; LOWORD(lParam)==WORD(HTERROR) amp;amp; IsWindowEnabled(hwnd)==FALSE) {return TRUE;} Спасибо за помощь!