【问题标题】:what kind of messages VCL accept ?/VCL 接受什么样的消息?/
【发布时间】:2011-10-18 06:39:13
【问题描述】:

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

【问题讨论】:

    标签: delphi c++builder vcl


    【解决方案1】:

    所有组件都接受所有消息,但如果一个组件没有指定的消息处理程序,它什么也不做

    如果你想发现 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 :-)

    顺便说一句。在我的 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 存储在包含您的组件的表单中,这样您就不需要从 TMemo 制作新的继承组件。因此,在表单中定义TWndMethod OldWndProc 并在表单中添加以下内容,例如OnCreate() 处理程序

    TWndMethod OldWndProc = MyMemo->WindowProc;
    MyMemo->WindowProc = NewWndProc;
    

    您还可以通过不将某些消息传递给 OldWndProc 来防止触发预定义的处理程序。请注意,如果您阻止处理敏感的系统消息(如 WM_CREATE),您将收到错误。

    【讨论】:

    • 感谢 Sergey 的详细回答!将来我会通过查看 VCL 的源代码来发现这一点!
    【解决方案2】:

    TMemo 是标准 Win32 API 多行 EDIT 控件的薄包装器。您必须阅读 MSDN 文档以查看 EDIT 控件本机处理哪些消息。 TMemo 不会直接处理EM_LINESCROLL,但 Windows 会。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-22
      • 2022-01-14
      • 2010-12-20
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多