如何从RICHEDIT控件中消除MessageBeep?

问题描述 投票:4回答:1

RichEdit control有这个非常讨厌的功能。每次用户尝试将光标移动到其“终点”时,它都会发出蜂鸣声。例如,您可以使用同样实现RICHEDIT的WordPad对其进行测试。打开它,键入一些文本,然后点击Home键。如果光标不在行的开头:

enter image description here

击中Home键将移动它,但然后再次击中Home键将产生这种哔哔声。

乍一看似乎压倒WM_KEYDOWNWM_KEYUP消息并阻止情况,当RICHEDIT可以产生哔声是一个解决方案......直到我真正开始实施它。不幸的是,它并不像听起来那么简单,因为这种控制会在很多情况下发出哔哔声!所以我的击键阻止代码真的膨胀到超过300多行,我仍然看到有一些按键,我要么没有考虑,或者更糟糕的是,我可能已经覆盖了一些有用的行为。 (请阅读下面的详细信息。)


然后我决定查看RICHEDIT控件本身的实现。当然,例如,如果我们看看Home按键的实现,我的Windows 10操作系统上的C:\WINDOWS\SysWOW64\msftedit.dll,在映射的偏移量?Home@CTxtSelection@@QAEHHH@Z上有一个名为public: int __thiscall CTxtSelection::Home(int,int)(或0x3FC00 demangled)的函数,它被硬编码为调用MessageBeep(MB_OK),或者正是我想要消除的:

enter image description here

如果你看一下上面屏幕截图中的地址0x6B64FD38,就会有一种内置的方式来绕过它,看起来像是标志0x800

所以更多地挖掘msftedit.dll,似乎有一个名为?OnAllowBeep@CTxtEdit@@QAEJH@Z(或public: long __thiscall CTxtEdit::OnAllowBeep(int) demangled)的函数可以修改这个标志:

enter image description here

经过一番研究后,我发现在RICHEDIT控件中内置了COM接口,例如ITextServicesITextHostTXTBIT_ALLOWBEEP方法中将该标志引用为ITextServices::OnTxPropertyBitsChange

不幸的是,我似乎无法找到直接改变那个TXTBIT_ALLOWBEEP旗帜的方式(COM不是我的强项。)我试图实现ITextHost,但它有很多虚拟方法与什么无关我正在努力实现我不知道如何实现。

有谁知道如何清除TXTBIT_ALLOWBEEP旗帜?


PS。这就是为什么我没有采用超越按键的原因:只是举个例子。说,如果我覆盖VK_HOME键按。我需要确保光标不在行的开头,而且还没有选择。但是,当光标位于窗口的最顶端时,我需要确保Ctrl键没有关闭。然后与Shift键相同,我甚至不确定Alt用它做什么......等等。哦,这只是Home的关键。还有Up,Down,Left,Right,PageUp,PageDown,End,Delete,Backspace。 (这就是我所知道的。可能还有更多,而且我甚至不谈论IME或其他键盘布局等等)换句话说,它变得一团糟!所以,最终我意识到预期击键不是要走的路。

c++ winapi com reverse-engineering richedit
1个回答
7
投票

首先,我们需要将EM_GETOLEINTERFACE消息发送到富编辑窗口 - 这是检索客户端可用于访问丰富的编辑控件的组件对象模型(COM)功能的IRichEditOle对象。

然后为了检索ITextServices指针,在QueryInterface返回的私有IUnknown指针上调用EM_GETOLEINTERFACE

这里存在一些有趣的观点 - IID_ITextServices并不为人所知,但需要从Msftedit.dll运行

来自About Windowless Rich Edit Controls

Msftedit.dll导出名为IID_ITextServices的接口标识符(IID),您可以使用该标识符查询ITextServices接口的IUnknown指针。

在我们得到qazxsw poi指针之后 - 我们根本无法用qazxsw poi面具调用qazxsw poi

代码示例:

ITextServices
© www.soinside.com 2019 - 2024. All rights reserved.