zoukankan      html  css  js  c++  java
  • 自定义一个消息

    定义一个消息需要两个步骤: 1.声明一个消息标识符 2.声明一个消息记录类型

    一个消息标识符是一个整数大小的常数。Windows自用低于1024的消息,所以当你声明你自己的消息,你应该开始高于这一数字。 常数WM_APP代表了用户定义的消息开始编号。当定义消息标识符,你应该基于WM_APP它们。(这是因为WM_USER所代表1024以后的消息编号,有一些已经被Windows标准组件占用了,为了避免冲突,使用WM_APP) 如果你想给你的消息一个有用的参数名,你需要声明该消息的消息记录类型。消息记录是传递给消息处理方法的参数类型。如果你不使用消息的参数,或者如果你想使用旧风格的参数表示法(wParam参数,lParam参数,等等),你可以使用默认的消息记录,TMessage,其原型如下:

      TMessage = packed record    
      Msg: Cardinal;    
      case Integer of
          0:
       (WParam: Longint;
            LParam: Longint;
            Result: Longint);
          1: (
            WParamLo: Word;
            WParamHi: Word;
            LParamLo: Word;
            LParamHi: Word;
            ResultLo: Word;
            ResultHi: Word);
      end;

    要声明一个消息记录类型,请按照下列约定: 1.命名消息记录类型,以T开头 2.第一个字段为Msg,为对应的消息 3.定义接下来的两个字节对应Word参数,接下来的两个字节为未使用。 或 接下来的四个字节定义对应于Longint型参数。 4.最后字段添加一个类型为Longint型的Result。 如Delphi源码里面:

      TWMCharToItem = packed record
        Msg: Cardinal;
        Key: Word;
        CaretPos: Word;
        ListBox: HWND;
        Result: Longint;
      end;  
    TWMCompacting = packed record
        Msg: Cardinal;
        CompactRatio: Longint;
        Unused: Longint;
        Result: Longint;
      end;

    有不同的方式来发送一个Windows消息,经常使用的是SendMessage和PostMessage,它们原型如下:

    function SendMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
    function PostMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall

    其中WPARAM和LPARAM都是Longint。这两个函数参数一样,返回值不同。SendMessage()返回被处理的消息的结果值,但是PostMessage()返回的只是一个布尔值,表示是否该消息被放入到目标窗口队列中。另外一个方面,SendMessage()是同步调用的,PostMessage()是异步调用的。


    下面一个例子来说明,如何自定义消息。示例功能为应用程序调用计算器类,当计算器类计算完毕,就发带计算结果的消息给应用程序: 1.新建Delphi 7应用程序,单击菜单栏→File→New→Unit,在弹出的单元文件,输入以下代码:

    unit Unit2;
    interface
    uses
      Classes, Windows, Messages;
    const   WM_CALCOK = WM_APP + 100;   //定义消息
    type   TCalc = class(TObject)
      private     FFormHandle: HWND;     //接受者的句柄
        FOne,FAnother: Integer;
      public
        constructor Create(AHandle: HWND;AOne,AAnother: Integer);
        procedure StartCalc;
      end;
    implementation
    constructor TCalc.Create(AHandle: HWND;AOne,AAnother: Integer);
    begin
      inherited Create;
      FFormHandle := AHandle;
      FOne := AOne;
      FAnother := AAnother;
    end;
    procedure TCalc.StartCalc;
    var   s: string;
    begin
      s := '计算结果:';
      SendMessage(FFormHandle,WM_CALCOK,FOne + FAnother,LongInt(s));  //进程内发送字符串   //PostMessage(FFormHandle,WM_CALCOK,FOne + FAnother,0);   //不可发送字符串
    end;
    end.

    2.主窗体上放置2个编辑框和一个按钮,主单元文件代码如下:

    unit Unit1;
    interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCtrls, Unit2;
    const   WM_CALCOK = WM_APP + 100;
    type   TForm1 = class(TForm)
        btn1: TButton;
        edt1: TEdit;
        edt2: TEdit;
        procedure btn1Click(Sender: TObject);
      private     FCalc: TCalc;
        procedure calcOk(var Msg: TMessage);message WM_CALCOK;
      public
        { Public declarations }
      end;
    var   Form1: TForm1;
    implementation
    {$R *.dfm}
    procedure TForm1.btn1Click(Sender: TObject);
    begin   FCalc := TCalc.Create(Self.Handle,StrToInt(edt1.Text),StrToInt(edt2.Text));
      try
        FCalc.StartCalc;
      finally
        FCalc.Free;
      end;
    end;
    procedure TForm1.calcOk(var Msg: TMessage);
    begin
      ShowMessage(string(Msg.LParam) + IntToStr(Msg.WParam));
    end;
    end.

    3.运行程序,结果如下所示:

  • 相关阅读:
    四则运算
    读书计划
    典型用户和场景分析
    课堂练习--电梯调度
    重力解锁--用户需求调研
    书籍促销活动优惠问题
    小组开发项目--NABC分析
    梦断代码读后感之终结篇
    结对开发-求环状二维数组最大子数组
    结对开发之大数溢出
  • 原文地址:https://www.cnblogs.com/leonkin/p/3183573.html
Copyright © 2011-2022 走看看