首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 自訂訊息機制實戰:攔截 WM_SYSCOMMAND 實現最小化到系統托盤圖示 (Shell_NotifyIcon)

     編輯:Delphi

應用場景

類似 FoxMail、迅雷等:點擊最小化按鈕 → 視窗隱藏 → 系統托盤區顯示圖示 → 點擊圖示 → 視窗還原。

核心 API:Shell_NotifyIcon


function Shell_NotifyIcon(dwMessage: DWORD; lpData: PNotifyIconData): BOOL; stdcall;
  • dwMessage:NIM_ADD (新增)、NIM_DELETE (移除)、NIM_MODIFY (修改)
  • lpData:TNotifyIconData 結構 (圖示、提示、回調訊息、視窗控制代碼)

自訂訊息宣告與處理


const
  WM_TRAYICON = WM_USER + 200; // 自訂回調訊息

type
  TForm1 = class(TForm)
  private
    procedure WMSysCommand(var Msg: TMessage); message WM_SYSCOMMAND;
    procedure WMTrayIcon(var Msg: TMessage); message WM_TRAYICON;
  end;

攔截最小化:WM_SYSCOMMAND


procedure TForm1.WMSysCommand(var Msg: TMessage);
var
  NID: PNotifyIconData;
begin
  if Msg.WParam = SC_MINIMIZE then begin // 或 SC_ICON (舊版常數)
    // 建立托盤圖示資料
    New(NID);
    NID.cbSize := SizeOf(TNotifyIconData);
    NID.Wnd := Handle;
    NID.uID := 0;
    NID.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
    NID.uCallbackMessage := WM_TRAYICON;
    NID.hIcon := Application.Icon.Handle; // 或 Form1.Icon.Handle
    StrCopy(NID.szTip, 'My Application');
    Shell_NotifyIcon(NIM_ADD, NID);
    Dispose(NID);
    Visible := False; // 隱藏主視窗
  end else
    inherited; // 其他系統命令交給預設處理
end;

處理托盤互動:WM_TRAYICON


procedure TForm1.WMTrayIcon(var Msg: TMessage);
var
  NID: PNotifyIconData;
begin
  if Msg.LParam = WM_LBUTTONDOWN then begin // 左鍵點擊
    New(NID);
    NID.cbSize := SizeOf(TNotifyIconData);
    NID.Wnd := Handle;
    NID.uID := 0;
    NID.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
    Shell_NotifyIcon(NIM_DELETE, NID); // 移除圖示
    Dispose(NID);
    Visible := True; // 還原視窗
    SetForegroundWindow(Handle); // 置前
  end
  else if Msg.LParam = WM_RBUTTONDOWN then begin // 右鍵可彈出選單
    // PopupMenu1.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
  end;
end;

表單銷毀時清理


procedure TForm1.FormDestroy(Sender: TObject);
var NID: TNotifyIconData;
begin
  // 確保圖示被移除
  FillChar(NID, SizeOf(NID), 0);
  NID.cbSize := SizeOf(NID);
  NID.Wnd := Handle;
  NID.uID := 0;
  Shell_NotifyIcon(NIM_DELETE, @NID);
end;

關鍵點總結

關鍵點說明
自訂訊息常數WM_USER + $xxxx 避免衝突
message 指令詞將方法綁定至特定訊息,編譯器自動生成 Dispatch 邏輯
SC_MINIMIZE vs SC_ICONDelphi 不同版本常數名稱不同,建議同時判斷
cbSize 必須正確結構大小錯誤導致 API 失敗 (Vista+ 嚴格檢查)
圖示控制代碼使用 Application.Icon.Handle 或載入 .ico 資源
雙重 Null 結尾szTip 需正確結尾,StrCopy 自動處理

現代改良建議

  • 使用 TApplicationEvents.OnMinimize 替代攔截 WM_SYSCOMMAND
  • 封裝為 TTrayIcon 元件 (Delphi 2009+ 內建),自動管理生命週期
  • 支援 NIM_SETVERSION 設定版本行為 (Vista+ 工具提示、氣球提示)

總結

Delphi message 指令詞提供優雅的自訂訊息處理機制。結合 Shell_NotifyIcon 實現「最小化到托盤」經典功能,核心在於:攔截 SC_MINIMIZE → NIM_ADD 隱藏視窗 → 回調訊息處理 LButtonDown → NIM_DELETE 還原視窗。掌握此模式,可輕鬆擴充氣球提示、右鍵選單、狀態動態圖示等豐富互動。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved