VCL接受什么样的消息?/

时间:2011-10-18 06:39:14

标签: delphi c++builder vcl

如何找出某个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是否可以接受或不接受消息???

2 个答案:

答案 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: - )

顺便说一下。 Simpy在我的CBuilder5的VCL源目录中搜索任何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>