我才接触消息机制,看了书后,觉得很迷茫!怎样使用自定义的消息!高手门能句个例子吗?举的例子如果通俗易懂的话!我还可以另外给分!我希望能在大家的帮助下解决这个问题!希望大家不要献我苯哦!

解决方案 »

  1.   

    给你看一个关于消息的比较完整的例子
    unit CIMain;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, ExtCtrls;const
      SX_MYMESSAGE=WM_USER;     //自定义消息值
      MessString='%s message now in %s.';   //String to alert user of messagetype
      TfrmMain = class(TForm)
        GroupBox1: TGroupBox;
        chkAppMsg: TCheckBox;
        chkWinProc: TCheckBox;
        chkMsgProc: TCheckBox;
        chkDefHandler: TCheckBox;
        chkEatMsg: TCheckBox;
        btnPostMessage: TButton;
        btnSendMessage: TButton;
        grbEatMsg: TGroupBox;
        rdbOnMsg: TRadioButton;
        rdbWinProc: TRadioButton;
        rdbMsgProc: TRadioButton;
        rdbDefHandler: TRadioButton;
        procedure FormCreate(Sender: TObject);
        procedure btnPostMessageClick(Sender: TObject);
        procedure btnSendMessageClick(Sender: TObject);
        procedure chkAppMsgClick(Sender: TObject);
        procedure chkEatMsgClick(Sender: TObject);
      private
        { Private declarations }
        {在应用程序层处理消息}
        procedure OnAppMessage(var Msg:TMsg;var Handled:Boolean);
        {在窗体过程层处理消息}
        procedure WndProc(var Msg:TMessage);override;
        {在消息分发(dispatch)后处理消息}
        procedure SXMyMessage(var Msg:TMessage);message SX_MYMESSAGE;
        {缺省的消息处理函数}
        procedure DefaultHandler(var Msg);override;
      public
        { Public declarations }
      end;var
      frmMain: TfrmMain;implementation{$R *.DFM}const
      //用于显示消息是被sent还是被posted
      SendPostString:array[0..1] of string=('Sent','Posted');procedure TfrmMain.FormCreate(Sender: TObject);
    begin
      //用OnAppMessage方法设置应用程序的OnMessage属性
      Application.OnMessage:=OnAppMessage;
      //使用CheckBox的Tag属性来存储与之相关的Radio按钮的引用
      chkAppMsg.Tag:=Longint(rdbOnMsg);
      chkWinProc.Tag:=Longint(rdbWinProc);
      chkMsgProc.Tag:=Longint(rdbMsgProc);
      chkDefHandler.Tag:=Longint(rdbDefHandler);
      //使用Radio的Tag属性来存储与之相关的CheckBox按钮的引用
      rdbOnMsg.Tag:=Longint(chkAppMsg);
      rdbWinProc.Tag:=Longint(chkWinProc);
      rdbMsgProc.Tag:=Longint(chkMsgProc);
      rdbDefHandler.Tag:=Longint(chkDefHandler);
    end;procedure TfrmMain.OnAppMessage(var Msg:TMsg;var Handled:Boolean);
    {应用程序的OnMessage处理函数}
    begin
      //检查是否是用户自定义的消息
      if Msg.message=SX_MYMESSAGE then
      begin
        if chkAppMsg.Checked then
        begin
          ShowMessage(Format(MessString,[SendPostString[Msg.WParam],
              'Application.OnMessage']));
          Handled:=rdbOnMsg.Checked;
        end;
      end;
    end;procedure TfrmMain.WndProc(var Msg:TMessage);
    {Form窗口过程的WndProc函数}
    var
      CallInherited:Boolean;
    begin
      CallInherited:=true;   //假设我们已经调用了继承的处理
      if Msg.Msg=SX_MYMESSAGE then   //检查是否为用户自定义的消息
      begin
        if chkWinProc.Checked then
        begin
          ShowMessage(Format(MessString,[SendPostString[Msg.WParam],
              'WndProc']));
          CallInherited:=not rdbWinProc.Checked;
        end;
      end;
      if CallInherited then
        inherited WndProc(Msg);
    end;procedure TfrmMain.SXMyMessage(var Msg:TMessage);
    {用户自定义的消息处理函数}
    var
      CallInherited:Boolean;
    begin
      CallInherited:=true;
      if chkMsgProc.Checked then
      begin
        ShowMessage(Format(MessString,[SendPostString[Msg.WParam],
              'Message Procdure']));
        CallInherited:=not rdbMsgProc.Checked;
      end;
      if CallInherited then
        inherited;
    end;procedure TfrmMain.DefaultHandler(var Msg);
    {缺省的消息处理函数}
    var
      CallInherited:Boolean;
    begin
      CallInherited:=true;
      if TMessage(Msg).Msg=SX_MYMESSAGE then
      begin
        if chkDefHandler.Checked then
        begin
          ShowMessage(Format(MessString,[SendPostString[TMessage(Msg).WParam],
              'DefaultHandler']));
          CallInherited:=not rdbDefHandler.checked;
        end;
      end;
      if CallInherited then
        inherited DefaultHandler(Msg);
    end;procedure TfrmMain.btnPostMessageClick(Sender: TObject);
    {向窗体Post消息}
    begin
      PostMessage(Handle,SX_MYMESSAGE,1,0);
    end;procedure TfrmMain.btnSendMessageClick(Sender: TObject);
    {向窗体发送消息}
    begin
      SendMessage(Handle,SX_MYMESSAGE,0,0);
    end;procedure TfrmMain.chkAppMsgClick(Sender: TObject);
    {当单击CheckBox时使适当的radio按钮有效或失效}
    begin
      if chkEatMsg.Checked then
      begin
        with TRadioButton((Sender as TCheckBox).Tag) do
        begin
          Enabled:=TCheckBox(Sender).Checked;
          if not Enabled then
            Checked:=false;
        end;
      end;end;procedure TfrmMain.chkEatMsgClick(Sender: TObject);
    {在适当的时候使radio按钮有效或无效}
    var
      i:integer;
      DoEnable, EatEnabled:Boolean;
    begin
      //获取有效/无效标志
      EatEnabled:= chkEatMsg.Checked;
      for i:=0 to grbEatMsg.ControlCount-1 do
      begin
        with grbEatMsg.Controls[i] as TRadioButton do
        begin
          DoEnable:=EatEnabled;
          if DoEnable then
            DoEnable:=TCheckBox(Tag).Checked;
          if not DoEnable then Checked:=false;
            Enabled:=DoEnable;
        end;
      end;
    end;end.
      

  2.   

    消息是由操作系统发给应用程序的,保存在一个消息队列中(由操作系统维护),消息处理函数实际上是由操作系统来调用的(所以叫回调)。在Delphi中,拦截消息一般有两种方法:一个是使用message关键字来定义方法。另一个是重载控件(或窗体)的WndProc(就像经典的C程序那样)。
      

  3.   

    以前看到的不知道对你有没有启发,希望顺利
    Delphi自定义消息应用一例
    现在很多的应用程序都有这样一种功能,当用户选择最小化窗口时,窗口不是象平常那样最小化到任务栏上,而是“最小化”成一个任务栏图标。象FoxMail 3.0 NetVampire 3.0等都提供了这样的功能。实现这样的功能实际上并不复杂,在窗口最小化时,窗口会发出WM_SYSCOMMAND消息,你只要需要截取Windows的WM_SYSCOMMAND消息,在窗口最小化时隐藏窗口并调用WindowsAPI函数Shell_NotifyIcon将定义的图标添加到任务栏上,Shell_NotifyIcon的函数定义是这样的:function Shell_NotifyIcon(dwMessage:DWORD; lpData: PNotifyIconData): BOOL; stdcall; 其中的参数dwMessage指定Shell_NotifyIcon函数的操作,可以是NIM_ADD NIM_DELETE NIM_MODIFY三个值中的一个,分别对应添加图标、删除图标、修改图标的动作。
    参数lpData指向的PNotifyIconData结构的定义如下:
    _NOTIFYICONDATAW = recordcbSize: DWORD;Wnd: HWND;uID: UINT;uFlags: UINT;uCallbackMessage: UINT;hIcon: HICON;szTip: array [0..63] of WideChar;end;
    TNotifyIconData = _NOTIFYICONDATAW;
    在这个结构中Wnd指明所属的窗口,UCallbackMessage指明回调消息,如果指明了Wnd和 uCallbackMessage,则当用户对任务栏图标有动作(如点击图标,在图标上移动光标等)。系统都会发送uCallbackMessage消息给Wnd指定的窗口。hIcon是要添加的图标的句柄,szTip 是图标的提示行(就是当移动光标到图标上,出现的一个小黄方框内出现的文字)。消息。实现上面的功能,最主要的是要处理WM_SYSCOMMAND消息和自定义的图标消息,这些消息在Delphi中并没有相应的事件。这里就需要使用到Delphi的自定义消息处理功能来截取并处理这些消息。
    首先看下面的程序。在执行程序之前,首先要改变Form1的Icon属性,给Form1装入一个图标,否则在任务栏上会出现一块空白。
    unit Unit1;interfaceusesWindowsMessagesSysUtils
    ClassesGraphicsControlsForms
    DialogsShellAPI;
    constWM_BARICON=WM_USER+200;
    typeTForm1 = class(TForm)privateprocedure WMSysCommand(varMessage: TMessage); message WM_SYSCOMMAND;procedure WMBarIcon(varMessage:TMessage);message WM_BARICON;{ Private declarations }public{ Public declarations }end;
    varForm1: TForm1;
    implementation
    {$R *.DFM}procedure TForm1.WMSysCommand(var Message:TMessage);varlpData:PNotifyIconData;beginif Message.WParam = SC_ICON thenbegin//如果用户最小化窗口则将窗口隐藏并在任务栏上添加图标lpData := new(PNotifyIconDataA);lpData.cbSize := 88;//SizeOf(PNotifyIconDataA);lpData.Wnd := Form1.Handle;lpData.hIcon := Form1.Icon.Handle;lpData.uCallbackMessage := WM_BARICON;lpData.uID :=0;lpData.szTip := 'Samples';lpData.uFlags := NIF_ICONor NIF_MESSAGE or NIF_TIP;Shell_NotifyIcon(NIM_ADDlpData);dispose(lpData);Form1.Visible := False;endelsebegin//如果是其它的SystemCommand消息则调用系统缺省处理函数处理之。DefWindowProc(Form1.HandleMessage.MsgMessage.WParamMessage.LParam);end;//end;
    procedure TForm1.WMBarIcon(var Message:TMessage);varlpData:PNotifyIconData;beginif (Message.LParam = WM_LBUTTONDOWN) thenbegin//如果用户点击任务栏图标则将图标删除并回复窗口。lpData := new(PNotifyIconDataA);lpData.cbSize := 88;//SizeOf(PNotifyIconDataA);lpData.Wnd := Form1.Handle;lpData.hIcon := Form1.Icon.Handle;lpData.uCallbackMessage := WM_BARICON;lpData.uID :=0;lpData.szTip := 'Samples';lpData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;Shell_NotifyIcon(NIM_DELETElpData);dispose(lpData);Form1.Visible := True;end;end;
    end.
    运行上面的程序,点击程序窗口标题栏上的最小化按钮,你就可以看到窗口被“最小化”成了一个任务栏图标,点击图标,窗口又会恢复原来的状态。
    从上面的程序可以看到,Delphi的自定义消息处理功能的实现也是十分简单的,首先在Form类的Private定义中加入自定义消息处理函数的定义,定义的描述如下:
    procedure UserPro(Var Message:TMessage):message WindowsMessage其中UserPro是用户自定义消息处理函数的名称,WindowsMessage是Windows消息常量或自定义消息常量。
    然后在程序中加入消息处理函数,函数的一般格式如下:
    Procedure UserClass.UserPro(Var Message:TMessage);var//加入定义Begin//加入程序语句End;其中UserClass是封装自定义消息处理函数的类的名称。
    最后,Delphi的自定义消息处理函数要涉及到Windows的消息的结构,在这里我就不多说了,大家可以参考Windows API帮助和Delphi的相关帮助信息。相信大家如果掌握了Delphi的自定义消息处理函数,一定可以编写出象VB一样简洁,象C++一样功能强大的程序来的。
      

  4.   

    一般的使用:const
      WM_MYMSG = WM_USER + $1001;在程序当中SendMessage或PostMessage就可以了
      

  5.   

    上面的方法,都可以用。不过,我在思考一个问题,这就是消息的唯一性问题。
    在一个系统中,如果都使用上述方法,多个程序之间难免会出现消息冲突。故
    我个人觉得,应该使用RegisterWindowMessage函数,以保证消息的唯一性。
    这一点很多资料中都忽视了。算是一个补充吧!