如何找出某个VCL组件可以接受的消息列表??? /
例如,如果我想通过向其发送消息来滚动Memo1 我可能会编写以下代码行,知道备忘录可以接受EM_LINESCROLL
SendMessage(Memo1->Handle,EM_LINESCROLL,-1,0);
//Memo1->Perform(EM_SCROLL,SB_LINEUP,0);
Memo1->Perform(EM_SCROLL,SB_LINEDOWN,0);
如何查找某些VCL comps是否可以接受或不接受消息???
答案 0 :(得分:5)
所有组件都接受所有消息,但如果组件没有分配消息处理程序,则它什么都不做
如果您想要发现VCL组件是否具有特定Windows消息的特殊处理程序,您必须查看VCL源代码,这些代码通常随C ++ Builder一起提供(XE和XE2的Starter Edition除外)。
VCL来源位于%CBuilderDir%\ Sources \ VCL(查看我的CBuilder5 / 6)
源代码是用delphi编写的,但要找到我们需要的东西并不困难。
首先,您必须找到目标类的定义。您可以在整个VCL源目录中搜索具有类似
的行的文件 TMemo = Class
(对于TMemo的示例)
打开您找到类的文件,(通常是stdctrls.pas或controls.pas - 最有用的组件位于那里),转到带有类定义的行并向下滚动一下,直到找到一组程序,看起来像
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure WMRButtonDown(var Message: TWMRButtonDown); message WM_RBUTTONDOWN;
......等等。调用这些过程以响应某些消息,这些消息在过程定义之后提供。
如果一个类有某个消息的过程,那么它会提供一些响应。
消息处理程序在delphi中继承,因此如果您没有找到消息的处理程序,则可以查看基类及其消息处理程序。要发现完整的类层次结构,您只需查看帮助文件,或再次查看类定义TMemo = class (TCustomMemo)
并从大括号中获取父类名称。
然后你可以重复搜索所有父类的消息处理程序,直到你到达TObject
: - )
EM_LINESCROLL
的预告,我认为这比没有VCL组件处理它。
如果您只需要为某些消息提供特殊交互,而不是试图确定某个组件是否已经拥有消息处理程序,则可以简单地覆盖组件的WindowProc
方法。 TControl
的所有后代都有这种方法。
此方法处理组件收到的所有消息,您可以在此处添加对其他系统或用户消息的响应。
void __fastcall TMyForm::NewWndProc(Messages::TMessage &Message)
{
if (Message.Msg == EM_LINESCROLL)
// Do something special for this message
else OldWndProc(Message);
}
你需要做的只是保留旧WindowProc的价值,在你做完所有事情之后在NewWndProc中调用它。
最好以保存组件的形式为TMemo定义和分配NewWndProc
并存储旧的WindowProc
,这样您就不必混淆从{{1}创建新的继承组件}。因此,请在表单中定义TMemo
,然后将其放在例如TWndMethod OldWndProc
处理程序
OnCreate()
此外,您可以通过不将某些消息传递给OldWndProc来阻止触发预定义处理程序。请注意,如果您阻止处理合理的系统消息(如WM_CREATE),您将收到错误。
答案 1 :(得分:0)
TMemo
是标准Win32 API多行EDIT
控件的瘦包装器。您必须阅读MSDN文档以查看EDIT
控件本身处理哪些消息。 TMemo不直接处理EM_LINESCROLL
,但Windows会处理。{/ p>