類似 FoxMail、迅雷等:點擊最小化按鈕 → 視窗隱藏 → 系統托盤區顯示圖示 → 點擊圖示 → 視窗還原。
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;
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;
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_ICON | Delphi 不同版本常數名稱不同,建議同時判斷 |
| cbSize 必須正確 | 結構大小錯誤導致 API 失敗 (Vista+ 嚴格檢查) |
| 圖示控制代碼 | 使用 Application.Icon.Handle 或載入 .ico 資源 |
| 雙重 Null 結尾 | szTip 需正確結尾,StrCopy 自動處理 |
TApplicationEvents.OnMinimize 替代攔截 WM_SYSCOMMANDTTrayIcon 元件 (Delphi 2009+ 內建),自動管理生命週期NIM_SETVERSION 設定版本行為 (Vista+ 工具提示、氣球提示)Delphi message 指令詞提供優雅的自訂訊息處理機制。結合 Shell_NotifyIcon 實現「最小化到托盤」經典功能,核心在於:攔截 SC_MINIMIZE → NIM_ADD 隱藏視窗 → 回調訊息處理 LButtonDown → NIM_DELETE 還原視窗。掌握此模式,可輕鬆擴充氣球提示、右鍵選單、狀態動態圖示等豐富互動。