Элемент управления RichEdit обладает этой очень раздражающей функцией. Он издает звуковой сигнал каждый раз, когда пользователь пытается переместить курсор за пределы « конечной точки ». Например, вы можете проверить это с WordPad
, который также реализует RICHEDIT. Откройте его, введите текст, а затем нажмите клавишу Home
. Если курсор не был в начале строки:
нажатие клавиши Home
переместит его туда, но затем повторное нажатие клавиши Home
произведет этот звуковой сигнал.
На первый взгляд это казалось переопределением WM_KEYDOWN
и WM_KEYUP
сообщений и блокированием ситуаций, когда RICHEDIT может издать этот звуковой сигнал, было решением ... пока я фактически не начал его реализовывать. К сожалению, это не так просто, как кажется, так как этот сигнал звучит во многих случаях! Так что мой код блокировки клавиш буквально увеличился до 300 с лишним строк, и я все еще вижу, что есть некоторые нажатия клавиш, которые я либо не учел, либо, что еще хуже, мог бы переопределить некоторые полезные действия. (Подробнее читайте ниже.)
Тогда я решил заглянуть внутрь реализации самого элемента управления RICHEDIT. И конечно же, например, если мы посмотрим на реализацию нажатия клавиши Home
, C:\WINDOWS\SysWOW64\msftedit.dll
в моей ОС Windows 10, имеет функцию с именем ?Home@CTxtSelection@@QAEHHH@Z
(или public: int __thiscall CTxtSelection::Home(int,int)
demangled) с отображенным смещением 0x3FC00
, это жестко запрограммировано для вызова MessageBeep (MB_OK) или точно , что я пытаюсь устранить:
И если вы посмотрите на адрес 0x6B64FD38
на скриншоте выше, есть встроенный способ его обойти, который выглядит как флаг 0x800
.
Итак, углубившись в msftedit.dll
, можно найти функцию с именем ?OnAllowBeep@CTxtEdit@@QAEJH@Z
(или public: long __thiscall CTxtEdit::OnAllowBeep(int)
demangled), которая может изменить следующие флаги:
После нескольких дополнительных исследований я обнаружил, что в элемент управления RICHEDIT встроены COM-интерфейсы, такие как ITextServices
и ITextHost
, которые ссылаются на этот флаг как TXTBIT_ALLOWBEEP
в ITextServices::OnTxPropertyBitsChange
методе.
К сожалению, я, похоже, не могу найти способ, как я могу напрямую изменить этот флаг TXTBIT_ALLOWBEEP
(COM не моя сильная сторона.) Я попытался изучить реализацию ITextHost
, но это У меня много виртуальных методов, которые не имеют ничего общего с тем, чего я пытаюсь достичь, и я не знаю, как его реализовать.
Кто-нибудь знает, как очистить этот флаг TXTBIT_ALLOWBEEP
?
PS. Вот почему я не пошел по пути отмены нажатий клавиш:
Просто чтобы дать вам пример. Скажем, если я переопределю клавишу VK_HOME
, нажмите. Мне нужно убедиться, что курсор находится не в начале строки, но также и нет выделения. Тем не менее, мне нужно убедиться, что клавиша Ctrl
не нажата в ситуации, когда курсор находится в самой верхней части окна. Затем то же самое с ключом Shift
, и я даже не уверен, что Alt
делает с ним ... и так далее. О, и это просто клавиша Home
. Также есть Вверх, Вниз, Влево, Вправо, PageUp, PageDown, End, Delete, Backspace. (И это то, что я знал. Может быть, больше, плюс я даже не говорю о IME или других раскладках клавиатуры и т. Д.) Другими словами, это становится беспорядком!
Итак, в конце концов я понял, что предвидение нажатия клавиши - это не путь.