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

Windows 任務列系統托盤圖標程式設計完整教學

     編輯:關於C++

許多常駐應用程式(輸入法、防毒軟體、下載工具)會在任務列通知區域(系統托盤)放置專屬圖標,提供狀態指示與快捷操作。本文以 C++ Builder 為例,詳細說明如何建立、顯示、隱藏、回應托盤圖標事件,並實現「關閉視窗最小化到托盤、雙擊圖標還原、右鍵選單」等經典行為。

一、核心資料結構與 API

NOTIFYICONDATA 結構定義托盤圖標屬性:

typedef struct _NOTIFYICONDATA {
    DWORD cbSize;           // 結構大小
    HWND  hWnd;             // 接收回呼訊息的視窗句柄
    UINT  uID;              // 圖標識別碼
    UINT  uFlags;           // 有效欄位旗標:NIF_MESSAGE|NIF_ICON|NIF_TIP
    UINT  uCallbackMessage; // 自訂回呼訊息編號
    HICON hIcon;            // 圖標控制代碼
    TCHAR szTip[128];       // 滑鼠懸停提示文字
} NOTIFYICONDATA;

關鍵 API:Shell_NotifyIcon(dwMessage, &data)

  • NIM_ADD:新增圖標
  • NIM_DELETE:移除圖標
  • NIM_MODIFY:修改圖標/提示/回呼訊息

二、C++ Builder 實作步驟

1. 表單類別宣告 (Unit1.h)

class TForm1 : public TForm {
__published:
    TButton *OKButton, *CancelButton;
    TLabel *Label1;
    void __fastcall FormCreate(TObject *Sender);
    void __fastcall FormDestroy(TObject *Sender);
    void __fastcall OKButtonClick(TObject *Sender);
    void __fastcall CancelButtonClick(TObject *Sender);
private:
    unsigned uIconMessage;          // 自訂回呼訊息編號
    void AddTray();                 // 建立托盤圖標
    void DeleteTray();              // 移除托盤圖標
protected:
    virtual void __fastcall WndProc(Messages::TMessage &Message); // 重寫視窗程序
public:
    __fastcall TForm1(TComponent* Owner);
};

2. 托盤操作函數實作 (Unit1.cpp)

void TForm1::AddTray() {
    NOTIFYICONDATA nid = {0};
    nid.cbSize = sizeof(nid);
    nid.hWnd = Handle;
    nid.uID = 1;
    nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
    nid.uCallbackMessage = uIconMessage;
    strncpy(nid.szTip, "我的任務", sizeof(nid.szTip));
    Application->Icon->LoadFromFile("e:\\yxg\\map\\system\\ico\\yxg.ico");
    nid.hIcon = Application->Icon->Handle;
    Shell_NotifyIcon(NIM_ADD, &nid);
}

void TForm1::DeleteTray() {
    NOTIFYICONDATA nid = {0};
    nid.cbSize = sizeof(nid);
    nid.hWnd = Handle;
    nid.uID = 1;
    Shell_NotifyIcon(NIM_DELETE, &nid);
}

3. 視窗程序處理托盤訊息

void __fastcall TForm1::WndProc(Messages::TMessage &Message) {
    if (Message.Msg == uIconMessage) {
        switch (Message.LParam) {
            case WM_LBUTTONDBLCLK: // 左鍵雙擊:結束程式
                Application->Terminate();
                break;
            case WM_RBUTTONDBLCLK: // 右鍵雙擊:顯示主視窗
                ShowWindow(Application->Handle, SW_SHOW);
                Application->ShowMainForm = true;
                Visible = true;
                break;
        }
        return;
    }
    TForm::WndProc(Message); // 其他訊息交給基類處理
}

4. 表單生命週期管理

void __fastcall TForm1::FormCreate(TObject *Sender) {
    uIconMessage = RegisterWindowMessage("IconNotify"); // 取得唯一訊息編號
    AddTray();
    Visible = false; // 啟動時隱藏主視窗
}

void __fastcall TForm1::FormDestroy(TObject *Sender) {
    DeleteTray(); // 程式結束前移除圖標
}

5. 按鈕操作:隱藏/結束

void __fastcall TForm1::OKButtonClick(TObject *Sender) {
    Visible = false;
    ShowWindow(Application->Handle, SW_HIDE);
    Application->ShowMainForm = false;
}

void __fastcall TForm1::CancelButtonClick(TObject *Sender) {
    Application->Terminate();
}

6. WinMain 進入點調整(專案原始碼)

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
    try {
        Application->Initialize();
        Application->CreateForm(__classid(TForm1), &Form1);
        ShowWindow(Application->Handle, SW_HIDE); // 隱藏應用程式主視窗
        Application->ShowMainForm = false;
        Application->Run();
    } catch (Exception &exception) {
        Application->ShowException(&exception);
    }
    return 0;
}

三、關鍵技術點總結

技術點說明
RegisterWindowMessage產生系統唯一訊息編號,避免與其他程式衝突
WndProc 重寫攔截托盤回呼訊息(WM_LBUTTONDBLCLK 等),實現自訂行為
NIM_MODIFY可動態更換圖標、更新提示文字、修改回呼訊息
WinMain 隱藏主視窗確保程式啟動即駐留托盤,不顯示工作列按鈕
Application->ShowMainForm = false配合 SW_HIDE 徹底隱藏 VCL 主視窗機制

四、常見擴展功能

  • 右鍵選單:在 WM_RBUTTONUP 顯示 TPopupMenu,提供「開啟、設定、退出」選項。
  • 動態圖標:搭配 Timer 週期性呼叫 NIM_MODIFY 更換圖標,實現動畫效果(見文章 ID 7864)。
  • 氣球提示:Windows 2000+ 支援 NIF_INFO、szInfo、szInfoTitle、dwInfoFlags 顯示豐富通知。
  • 高 DPI 支援:載入多尺寸圖標(16x16, 32x32, 48x48)或使用向量圖標資源。

掌握托盤程式設計,是開發常駐背景應用、系統工具的基本功。

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