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

C++Builder 任務列圖示管理:最小化到托盤與前端顯示切換

     編輯:VC 教學

核心 API:Shell_NotifyIcon

同系統托盤開發,關鍵在於 **NIM_ADD 新增**、**NIM_MODIFY 修改**、**NIM_DELETE 移除** 三操作,配合自訂回呼訊息處理滑鼠事件。

封裝函式:加入/修改/移除托盤圖示


// 自訂回呼訊息
#define WM_MYTRAYICON (WM_APP + 100)

void PutToTaskBar(HWND hwnd, UINT uId, HICON hIcon, LPCTSTR tip) {
    NOTIFYICONDATA nid = { sizeof(nid) };
    nid.hWnd = hwnd; nid.uID = uId; nid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
    nid.uCallbackMessage = WM_MYTRAYICON; nid.hIcon = hIcon;
    lstrcpyn(nid.szTip, tip, 128);
    Shell_NotifyIcon(NIM_ADD, &nid);      // 新增
    Shell_NotifyIcon(NIM_MODIFY, &nid);   // 確保圖示/提示生效
}

BOOL TrayMessage(HWND hwnd, DWORD msg, UINT uId, HICON hIcon, LPCTSTR tip) {
    NOTIFYICONDATA nid = { sizeof(nid) };
    nid.hWnd = hwnd; nid.uID = uId; nid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
    nid.uCallbackMessage = WM_MYTRAYICON; nid.hIcon = hIcon;
    lstrcpyn(nid.szTip, tip, 128);
    BOOL res = Shell_NotifyIcon(msg, &nid);
    if (hIcon) DestroyIcon(hIcon);  // 圖示控制代碼由呼叫端管理
    return res;
}

視窗程序處理滑鼠事件


LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    if (msg == WM_MYTRAYICON) {
        switch (lp) {
            case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
                // 雙擊還原主視窗
                ShowWindow(hwnd, SW_RESTORE);
                SetForegroundWindow(hwnd);
                break;
            case WM_RBUTTONDOWN:
                // 右鍵彈出選單
                POINT pt; GetCursorPos(&pt);
                SetForegroundWindow(hwnd);
                TrackPopupMenu(hPopupMenu, 0, pt.x, pt.y, 0, hwnd, NULL);
                break;
        }
        return 0;
    }
    // ... 其他訊息
    return DefWindowProc(hwnd, msg, wp, lp);
}

最小化時隱藏主視窗、只留托盤圖示


void __fastcall TForm1::FormResize(TObject* Sender) {
    if (WindowState == wsMinimized) {
        ShowWindow(Handle, SW_HIDE);  // 隱藏任務列按鈕
        PutToTaskBar(Handle, 1, Application->Icon->Handle, "我的程式");
    }
}

void __fastcall TForm1::OnTrayRestore(TObject* Sender) {
    ShowWindow(Handle, SW_RESTORE);
    WindowState = wsNormal;
    TrayMessage(Handle, NIM_DELETE, 1, NULL, NULL); // 移除托盤圖示
}

進階:視窗樣式 WS_EX_TOOLWINDOW

  • 建立視窗時指定 WS_EX_TOOLWINDOW:**不在任務列顯示按鈕**,Alt+Tab 不切換,適合純托盤程式。
  • 或運行時修改:SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_TOOLWINDOW)。

C++Builder 元件化方案:TTrayIcon

  • 拖放 TTrayIcon 到表單。
  • 設定 Icons、Hint、Animate、PopupMenu。
  • 事件:OnClick (單擊)、OnDblClick (雙擊還原)、OnMouseDown (右鍵選單)。
  • 強烈建議新專案直接使用 TTrayIcon,封裝所有 Shell_NotifyIcon 細節、自動處理視窗生命週期。

常見問題

總結

任務列圖示管理核心是 **Shell_NotifyIcon 生命週期管理 + 自訂訊息回呼**。C++Builder 開發者請**直接使用 TTrayIcon 元件**,專注業務邏輯。手動封裝時務必處理:視窗隱藏/顯示同步、圖示資源釋放、Explorer 重啟重建、高 DPI 圖示載入、右鍵選單焦點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題解決
最小化後無法還原檢查 FormResize 邏輯、托盤雙擊事件是否正確 ShowWindow/Restore
托盤圖示重複/殘留確保 FormDestroy/關閉時呼叫 NIM_DELETE,處理 WM_TASKBARCREATED 重建
右鍵選單不消失/失焦TrackPopupMenu/PopupMenu->Popup 前呼叫 SetForegroundWindow(Handle)
管理員權限下托盤不顯示高完整性進程托盤圖示需在相同會話,或用服務+UI 分離架構