自定義接收消息的類

原理:該效果的實現主要是使用AllocateHwnd函數(能夠查閱Delphi的幫助)生成一個非可視的窗口來響應消息,該函數的返回值既是非可視窗口的句柄。而後就能夠在你的類中響應Windows的消息了。該函數只有一個參數就是要建立的非可視窗口的WinProc函數(就是處理該窗口消息的函數),固然你也能夠在這個函數中處理你要處理的消息了。最後在類銷燬時必定要DeallocateHWnd這個非可視窗口。
   
    這些在翻看Delphi ScktComp單元的Socket類時獲得。緣由在於好奇這些類如何能獲得Windows發給它們的關於Socket的消息。ide

如下是從TCustomWinSocket類摘出來源碼(能夠響應消息):函數

unit uClass;測試

interfacespa

uses Messages, Classes, Dialogs;orm

const
  WM_MYTEST = WM_USER + $1000;           // 測試用繼承

type
  TMyClass = class
  private
    FHandle: THandle;
    procedure WinProc(var Msg: TMessage);
    procedure WMMyTest(var Msg: TMessage); message WM_MYTEST;   // 測試用
  public
    constructor Create;
    destructor Destroy; override;
    property Handle: THandle read FHandle;
  end;get

implementation源碼

{ TMyClass }it

constructor TMyClass.Create;
begin
  if FHandle = 0 then
    FHandle := AllocateHwnd(WinProc);
end;io

destructor TMyClass.Destroy;
begin
  if FHandle <> 0 then
    DeallocateHWnd(FHandle);
end;

procedure TMyClass.WinProc(var Msg: TMessage);
begin
  try
    //if Msg.Msg = WM_MYTEST then
    //  ShowMessage('I''m the first get the message "WM_MYTEST"');
    Dispatch(Msg);
  except
    if Assigned(ApplicationHandleException) then
      ApplicationHandleException(Self);
  end;
end;

procedure TMyClass.WMMyTest(var Msg: TMessage);
begin
  ShowMessage('Test OK!' + #10
    + 'I''m coming from Class "TMyClass" with message "WM_MYTEST"!');
end;

end.

   後記:這樣,這個類就具備了一個句柄,發個消息WM_MYTEST看看。還能執行。呵呵,之後再寫須要響應消息的類的時候,直接繼承它就能夠了,記得要把 WMMyTest過程刪掉,它只是一個測試。

測試:
   var
     mc: TMyClass;
   begin
     mc := TMyClass.Create;  
     PostMessage(mc.Handle, WM_MYTEST, 0, 0);    
   end;

個人程序以下     unit   Unit1;         interface         uses         Windows,   Messages,   SysUtils,   Variants,   Classes,   Graphics,   Controls,   Forms,         Dialogs,   ExtCtrls,   Unit2,   StdCtrls;         type         TForm1   =   class(TForm)             Button1:   TButton;             procedure   FormCreate(Sender:   TObject);             procedure   Button1Click(Sender:   TObject);         private             {   Private   declarations   }             FPluginRegistry   :   TPluginRegistry;         public             {   Public   declarations   }         end;         var         Form1:   TForm1;         implementation         {$R   *.dfm}         procedure   TForm1.FormCreate(Sender:   TObject);     begin           FPluginRegistry   :=   TPluginRegistry.Create;           RegisterWindowMessage('WM_DESERIALIZATION');     end;         procedure   TForm1.Button1Click(Sender:   TObject);     begin         //若是我用這句就能夠接收到自定義的消息     //     PostMessage(FPluginRegistry.WindowHandle,WM_DESERIALIZATION,0,0);         //若是用這句就不行,怎麼樣才能實現廣播呢?         PostMessage(HWND_BROADCAST,WM_DESERIALIZATION,0,0);     end;         end.             unit   Unit2;         interface         uses   Classes,   Windows,   Messages,Dialogs;         const         WM_DESERIALIZATION   =   WM_USER   +   100;           type         TPluginRegistry   =   class(TPersistent)         private             FWindowHandle:   HWND;             procedure   WndProc(var   Msg:   TMessage);         protected             procedure   ProcessSaveProperty;   virtual;         public             constructor   Create;             destructor   Destroy;   override;             property   WindowHandle   :   HWND   read   FWindowHandle;         end;         implementation         uses   Forms;     {   TPluginRegistry   }         constructor   TPluginRegistry.Create;     begin         inherited   Create;         FWindowHandle   :=   Classes.AllocateHWnd(WndProc);     end;         destructor   TPluginRegistry.Destroy;     begin         Classes.DeallocateHWnd(FWindowHandle);         inherited;     end;             procedure   TPluginRegistry.ProcessSaveProperty;     begin         Showmessage('Received');     end;         procedure   TPluginRegistry.WndProc(var   Msg:   TMessage);     begin         with   Msg   do             if   Msg   =   WM_DESERIALIZATION   then                 try                     ProcessSaveProperty;                 except                     Application.HandleException(Self);                 end             else                 Result   :=   DefWindowProc(FWindowHandle,   Msg,   wParam,   lParam);     end;         end.  

相關文章
相關標籤/搜索