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

系統托盤程式設計完全指南 (3):氣球提示 Balloon Tips 完整實作

     編輯:關於VC++

延續前兩篇(基本托盤圖示、TaskbarCreated 自動重建),本篇聚焦 Windows 2000/XP 引入的氣球提示。不同於傳統 ToolTip(滑鼠懸停才顯示),氣球提示由程式主動觸發、支援標題/圖示/自動超時關閉,適合非打斷式通知(新郵件、網路狀態變更、下載完成等)。

NOTIFYICONDATA 擴充欄位 (IE 5.0+ / _WIN32_IE >= 0x0500)


typedef struct _NOTIFYICONDATA {
    DWORD cbSize;
    HWND  hWnd;
    UINT  uID;
    UINT  uFlags;
    UINT  uCallbackMessage;
    HICON hIcon;
    WCHAR szTip[128];           // 傳統 ToolTip
    // --- 以下為 0x0500 新增 ---
    DWORD dwState;
    DWORD dwStateMask;
    WCHAR szInfo[256];          // 氣球提示內文
    union { UINT uTimeout; UINT uVersion; } DUMMYUNIONNAME;
    WCHAR szInfoTitle[64];      // 氣球標題
    DWORD dwInfoFlags;          // 圖示類型:NIIF_INFO/WARNING/ERROR/NONE
} NOTIFYICONDATA;

編譯時需包含新版 shellapi.h 並連結 shell32.lib,部署需確保目標機 shell32.dll 版本 >= 5.0(Win2000 內建)。

顯示氣球提示:Shell_NotifyIcon(NIM_MODIFY, &nid)

關鍵旗標:uFlags = NIF_INFO。szInfo 內文、szInfoTitle 標題、uTimeout 毫秒數(10~30 秒,系統會限制範圍)、dwInfoFlags 圖示。

CTrayIcon::ShowBalloonTip 封裝


BOOL CTrayIcon::ShowBalloonTip(LPCTSTR szMsg, LPCTSTR szTitle,
                               UINT uTimeout, DWORD dwInfoFlags)
{
    m_nid.cbSize = sizeof(NOTIFYICONDATA);
    m_nid.uFlags = NIF_INFO;
    m_nid.uTimeout = uTimeout;
    m_nid.dwInfoFlags = dwInfoFlags;
    _tcscpy_s(m_nid.szInfo, szMsg ? szMsg : _T(""));
    _tcscpy_s(m_nid.szInfoTitle, szTitle ? szTitle : _T(""));
    return Shell_NotifyIcon(NIM_MODIFY, &m_nid);
}

預設 dwInfoFlags = NIIF_INFO(藍色資訊圖示),亦可用 NIIF_WARNING(黃色驚嘆號)、NIIF_ERROR(紅色叉叉)、NIIF_NONE(無圖示)。

氣球提示生命週期通知訊息

托盤建立時指定 uCallbackMessage,Windows 會傳送下列通知:

通知訊息觸發時機
NIN_BALLOONSHOW氣球顯示瞬間
NIN_BALLOONHIDE氣球消失(圖示被刪除時);超時/點關閉不送此訊息
NIN_BALLOONTIMEOUT超時自動關閉 或 使用者點右上角關閉鈕
NIN_BALLOONUSERCLICK使用者點擊氣球本體(非關閉鈕)

⚠️ 無法區分「超時」與「點關閉鈕」,兩者皆送 NIN_BALLOONTIMEOUT。

Windows XP 特殊行為:焦點阻擋超時

實測發現:XP 上,若托盤程式擁有前景焦點,氣球不會超時自動關閉。必須切換到其他視窗才會啟動計時器。Win2000 無此行為。此為 XP 設計決策,避免使用者正在操作時通知被強制關閉。

範例程式:TrayTest3

  • 雙擊托盤圖示開啟主視窗,顯示所有收到的托盤通知訊息(含上述四種 Balloon 事件)。
  • 選單「檢視 → 顯示氣球提示」觸發 ShowBalloonTip。
  • 可觀察 Win2000 無關閉鈕、XP 有關閉鈕的差異(圖一、圖二)。

最佳實務建議

  • ✅ 僅在真正需要使用者注意時顯示(新訊息、錯誤警告、狀態變更)。
  • ✅ 提供使用者關閉選項(設定視窗勾選「不再顯示氣球提示」)。
  • ❌ 避免頻繁彈出(每分鐘超過 1 次即屬騷擾)。
  • ❌ 切勿在氣球放入關鍵操作(如「點此安裝更新」),因使用者可能錯過或誤關。
  • ✅ 內文簡潔(< 256 字元),標題明確(< 64 字元)。

原始碼重點

  • CTrayIcon::ShowBalloonTip 兩個多載(字串/資源 ID)
  • CMainFrame::OnTrayNotification 處理 NIN_BALLOON* 並記錄 Log
  • 專案設定:#define _WIN32_IE 0x0500 確保結構定義正確

系列總結

  1. 第 1 篇:Shell_NotifyIcon 基礎、CTrayIcon 封裝、右鍵選單、雙擊預設命令、SetForegroundWindow 修正選單焦點問題。
  2. 第 2 篇:TaskbarCreated 廣播訊息、CSubclassWnd 攔截最上層視窗程序、自動重建托盤圖示。
  3. 第 3 篇 (本文):NIF_INFO 氣球提示、超時/點擊事件、XP 焦點行為差異、使用建議。

三篇結合,涵蓋托盤程式設計 90% 以上實務需求。完整原始碼請下載附件。

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