Suh*_*iev 0 delphi vcl c++builder
如何找出某个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);
Run Code Online (Sandbox Code Playgroud)
如何查找某些VCL comps是否可以接受或不接受消息?
所有组件都接受所有消息,但如果组件没有分配的消息处理程序,则它什么都不做
如果要发现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);
}
Run Code Online (Sandbox Code Playgroud)
你需要做的只是保留旧WindowProc的价值,在你做完所有事情之后在NewWndProc中调用它.
最好以保存组件的形式为TMemo 定义,分配 NewWndProc和存储旧WindowProc的,这样你就不需要搞乱从中创建新的继承组件了TMemo.因此,TWndMethod OldWndProc在表单中定义并放置以下内容,例如,在表单OnCreate()处理程序中
TWndMethod OldWndProc = MyMemo->WindowProc;
MyMemo->WindowProc = NewWndProc;
Run Code Online (Sandbox Code Playgroud)
此外,您可以通过不将某些消息传递给OldWndProc来防止触发预定义处理程序.请注意,如果您阻止处理合理的系统消息(如WM_CREATE),您将收到错误.