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

C++ Builder 系統匣圖示程式開發全攻略:Shell_NotifyIcon 實戰

     編輯:關於C++

系統匣是 Windows 任務列上的特殊區域(技術名稱:「任務列通知區域」),許多常駐程式(如輸入法、防毒軟體)會在此放置圖示,讓使用者一眼知曉程式正在背景執行,並能快速喚醒。系統匣程式開發屬於 Shell 程式設計範疇,核心在於 Shell_NotifyIcon API 函數。

核心結構與 API

NOTIFYICONDATA 結構

typedef struct _NOTIFYICONDATA {
    DWORD cbSize;           // 結構大小,必須初始化
    HWND hWnd;              // 接收訊息的視窗控制代碼
    UINT uID;               // 應用程式定義的圖示 ID
    UINT uFlags;            // 有效欄位標誌:NIF_ICON、NIF_MESSAGE、NIF_TIP
    UINT uCallbackMessage;  // 自訂回呼訊息
    HICON hIcon;            // 圖示控制代碼
    char szTip[64];         // 工具提示文字
} NOTIFYICONDATA;

Shell_NotifyIcon 函數

BOOL WINAPI Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA pnid);

dwMessage 操作類型:NIM_ADD(新增)、NIM_DELETE(刪除)、NIM_MODIFY(修改圖示或提示)。

完整實作範例:雙擊圖示關閉程式

1. 表單標頭檔宣告

#include <shellapi.h>
// ...
private:
    unsigned int iconMessage;        // 自訂訊息編號
    void AddTrayIcon();              // 新增匣圖示
    void RemoveTrayIcon();           // 移除匣圖示
protected:
    virtual void __fastcall WndProc(Messages::TMessage &Message); // 重載視窗程序

2. 新增與移除圖示實作

void TForm1::AddTrayIcon() {
    NOTIFYICONDATA icondata;
    memset(&icondata, 0, sizeof(icondata));
    icondata.cbSize = sizeof(icondata);
    icondata.hWnd = Handle;
    strncpy(icondata.szTip, "未知狀態", sizeof(icondata.szTip));
    icondata.hIcon = Application->Icon->Handle;
    icondata.uCallbackMessage = iconMessage;
    icondata.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
    Shell_NotifyIcon(NIM_ADD, &icondata);
}

void TForm1::RemoveTrayIcon() {
    NOTIFYICONDATA icondata;
    memset(&icondata, 0, sizeof(icondata));
    icondata.cbSize = sizeof(icondata);
    icondata.hWnd = Handle;
    Shell_NotifyIcon(NIM_DELETE, &icondata);
}

3. 重載 WndProc 處理自訂訊息

void __fastcall TForm1::WndProc(Messages::TMessage &Message) {
    if (Message.Msg == iconMessage) {
        if (Message.LParam == WM_LBUTTONDBLCLK) {
            Application->Terminate(); // 雙擊關閉程式
        }
        return;
    }
    TForm::WndProc(Message); // 其他訊息交給基底類別處理
}

4. 表單生命週期事件

void __fastcall TForm1::FormCreate(TObject *Sender) {
    iconMessage = RegisterWindowMessage("IconNotify"); // 註冊唯一訊息
    AddTrayIcon();
}

void __fastcall TForm1::FormDestroy(TObject *Sender) {
    RemoveTrayIcon(); // 關閉時移除匣圖示
}

5. 動態更新工具提示(Timer 事件)

void __fastcall TForm1::Timer1Timer(TObject *Sender) {
    NOTIFYICONDATA icondata;
    memset(&icondata, 0, sizeof(icondata));
    icondata.cbSize = sizeof(icondata);
    icondata.hWnd = Handle;
    String s = "我的圖示!";
    strncpy(icondata.szTip, s.c_str(), sizeof(icondata.szTip));
    icondata.uFlags = NIF_TIP;
    Shell_NotifyIcon(NIM_MODIFY, &icondata);
}

6. 隱藏主視窗,僅顯示匣圖示

在專案原始碼 WinMain 中 Application->Initialize() 之後加入:

ShowWindow(Application->Handle, SW_HIDE);
Application->ShowMainForm = false;

關鍵技術要點總結

  • 使用 RegisterWindowMessage 取得唯一訊息編號,避免衝突。
  • 重載 WndProc 攔截 uCallbackMessage,處理滑鼠事件(WM_LBUTTONDBLCLK、WM_RBUTTONDOWN 等)。
  • 程式結束時務必呼叫 NIM_DELETE 清理匣圖示,否則會留下「殭屍圖示」。
  • 圖示資源可使用應用程式圖示 (Application->Icon->Handle) 或載入自訂 .ico 檔。

掌握 Shell_NotifyIcon 機制,即可開發出專業級的常駐系統匣應用程式,提升使用者體驗與程式可見性。

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