線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2434
推到 Plurk!
推到 Facebook!

直接自訂TApplication的WndProc來處理Messages(在沒有Form 的情況下)

 
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-07-16 15:07:29 IP:218.16.xxx.xxx 未訂閱
TApplication 不是 TControl 所以處理 Windows Message 與 Form 及其他 TControl 稍有不同 而且不可能承繼 TApplication 及 override TApplication.WndProc 來直接自訂處理 Message    剛才看見 【問題】無 Form 程式僅有工作列狀態區圖示, 如何處理訊息?  http://delphi.ktop.com.tw/topic.php?TOPIC_ID=33976    花了點時間來試驗,結果有點成績,在這裡分享一下給大家。    不過我對自訂處理 Message 是新手所以可能有簡單直接的方法去做,請各高手指教。    
program sysTray;
{$R *.res}    uses
Forms, windows, SysUtils, Messages, Classes, ShellAPI, Dialogs;    const
WN_TRAYICON = WM_USER   1;    var
NotifyIconData : TNotifyIconData;
OldWndProc, NewWndProc : Pointer;    function ProcToMethod(Proc : Pointer; Obj : TObject) : TMethod;
begin
  result.Code := Proc;
  result.Data := Obj;
end;    procedure MyWndProc(self : TApplication; var Message: TMessage);
begin
  if Message.Msg = WN_TRAYICON then
  begin
    Case Message.LParam of
      512 : StrPCopy(NotifyIconData.szTip, 'This is Icon Message - Mouse Over'); // Mouse Over
      513 : if MessageBox(0,'Left Button Clicked.  Quit?','Icon Test',MB_YESNO) = IDYES then self.Terminate; // Left Mouse Down
      516 : MessageBox(0,'Right Button Clicked.','Icon Test',0); // Right Mouse Down
      514,515,517,518 : //Mouse up / Mouse Click -- No Action
    else
      MessageBox(0,PChar(Format('Unknow Message : %d:%d',[Message.WParam,Message.LParam])),'Icon Test',0);
    end;
    Shell_NotifyIcon(NIM_MODIFY, @NotifyIconData);
  end;
  // Call Original WndProc to handle other messages;
  Message.Result := CallWindowProc(OldWndProc,Application.Handle,Message.Msg,Message.WParam,Message.LParam);
end;    begin
  // 1. Convert Standalone Procedure to Class Method TWndMethod
  // 2. Convert the TWndMethod to WndProc Style to be used in SetWindowLong
  NewWndProc := MakeObjectInstance(TWndMethod(ProcToMethod(@MyWndProc,Application)));
  // 1. Use MyWndProc to replace the original WndProc to handle message
  // 2. Record the orignal WndProc for handling other messages
  OldWndProc := Pointer(SetWindowLong(Application.Handle,GWL_WNDPROC,LongInt(NewWndProc)));      With NotifyIconData do
  begin
    cbSize := sizeof(TNotifyIconData);
    Wnd := Application.Handle;
    uID := 1000;
    uFlags := NIF_MESSAGE   NIF_ICON   NIF_TIP;
    uCallbackMessage := WN_TRAYICON;
    hIcon := application.Icon.Handle;
    StrPCopy(szTip, 'TrayIcon Start');
  end;      Shell_NotifyIcon(NIM_ADD, @NotifyIconData);
  while not Application.Terminated do Application.ProcessMessages;
  Shell_NotifyIcon(NIM_DELETE, @NotifyIconData);
end.
註一 : 部份程式碼源自上述發問之文章 註二 : 將獨立 Procedure 轉做 Class Method 請參閱拙作 : 如何欺騙 Delphi 將一般獨立 procedure 指給 Event http://delphi.ktop.com.tw/topic.php?TOPIC_ID=30573 1. 更改 MyWndProc 的 Self 為 TApplication 可 直接使用 Self.Terminate 2. 修正將 Message 結果存入 Message.Result 發表人 - Justmade 於 2003/07/16 17:36:08
Justmade
版主


發表:94
回覆:1934
積分:2030
註冊:2003-03-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-07-16 17:18:08 IP:218.16.xxx.xxx 未訂閱
剛再試了一下,這是直接使用 WindowProc 格式來做的方法,會簡化一點但程式碼跟 Application.WndProc 或 TControl.WndProc 真接使用 TMessage 做 Parameter 的格式不一樣    要用那種方式就要看大家的習慣了。    
program sysTray2;
{$R *.res}    uses
Forms, windows, SysUtils, Messages, Classes, ShellAPI, Dialogs;    const
WN_TRAYICON = WM_USER   1;    var
NotifyIconData : TNotifyIconData;
OldWndProc : Pointer;    function NewWndProc(WindowHandle : hWnd; Msg : LongInt; ParamW : WParam; ParamL : LParam) : LongInt ; stdcall;
begin
  if Msg = WN_TRAYICON then
  begin
    Case ParamL of
      512 : StrPCopy(NotifyIconData.szTip, 'This is Icon Message - Mouse Over'); // Mouse Over
      513 : if MessageBox(0,'Left Button Clicked.  Quit?','Icon Test',MB_YESNO) = IDYES then Application.Terminate; // Left Mouse Down
      516 : MessageBox(0,'Right Button Clicked.','Icon Test',0); // Right Mouse Down
      514,515,517,518 : //Mouse up / Mouse Click -- No Action
    else
      MessageBox(0,PChar(Format('Unknow Message : %d:%d',[ParamW,ParamL])),'Icon Test',0);
    end;
    Shell_NotifyIcon(NIM_MODIFY, @NotifyIconData);
  end;
  result := CallWindowProc(OldWndProc,WindowHandle,Msg,ParamW,ParamL);
end;    begin
  OldWndProc := Pointer(SetWindowLong(Application.Handle,GWL_WNDPROC,LongInt(@NewWndProc)));      With NotifyIconData do
  begin
    cbSize := sizeof(TNotifyIconData);
    Wnd := Application.Handle;
    uID := 1000;
    uFlags := NIF_MESSAGE   NIF_ICON   NIF_TIP;
    uCallbackMessage := WN_TRAYICON;
    hIcon := application.Icon.Handle;
    StrPCopy(szTip, 'TrayIcon Start');
  end;      Shell_NotifyIcon(NIM_ADD, @NotifyIconData);
  while not Application.Terminated do Application.ProcessMessages;
  Shell_NotifyIcon(NIM_DELETE, @NotifyIconData);
end.
系統時間:2024-04-28 18:56:14
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!