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

VC++ 系統托盤圖標程式設計完整實作

     編輯:VC 教學

核心結構與 API

NOTIFYICONDATA 結構

typedef struct _NOTIFYICONDATA {
    DWORD cbSize;           // 結構大小
    HWND  hWnd;             // 接收回調訊息的視窗
    UINT  uID;              // 圖標識別碼
    UINT  uFlags;           // 有效欄位標誌:NIF_ICON | NIF_MESSAGE | NIF_TIP
    UINT  uCallbackMessage; // 自訂回調訊息 (如 WM_USER+1)
    HICON hIcon;            // 圖標句柄
    char  szTip[64];        // 滑鼠懸停提示文字
} NOTIFYICONDATA;

Shell_NotifyIcon 函數

BOOL Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA pnid);
// dwMessage: NIM_ADD (新增), NIM_DELETE (刪除), NIM_MODIFY (修改)

實作步驟 (SDI/對話框專案)

1. 隱藏主視窗啟動

在 CWinApp::InitInstance 或主框架 OnCreate 註解:

// pFrame->ActivateFrame();
// pFrame->ShowWindow(SW_SHOW);

2. 主框架成員變數與建立圖標

// MainFrm.h
protected:
    NOTIFYICONDATA m_tnid;
    #define MYWM_NOTIFYICON (WM_USER + 1)

// MainFrm.cpp OnCreate 尾部
m_tnid.cbSize = sizeof(NOTIFYICONDATA);
m_tnid.hWnd = m_hWnd;
m_tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
m_tnid.uCallbackMessage = MYWM_NOTIFYICON;
m_tnid.uID = IDR_MAINFRAME;
_tcscpy_s(m_tnid.szTip, _T("托盤程式範例"));
m_tnid.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
Shell_NotifyIcon(NIM_ADD, &m_tnid);

3. 訊息映射與處理 (WindowProc 覆寫)

// MainFrm.h
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);

// MainFrm.cpp
LRESULT CMainFrame::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) {
    case MYWM_NOTIFYICON:
        switch (lParam) { // lParam 為實際滑鼠訊息
        case WM_LBUTTONDBLCLK: // 雙擊左鍵:顯示主視窗
            AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOW);
            break;
        case WM_RBUTTONDOWN: { // 右鍵:彈出選單
            CMenu menu; menu.LoadMenu(IDR_TRAY_MENU);
            CMenu* pPopup = menu.GetSubMenu(0);
            CPoint pt; GetCursorPos(&pt);
            pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this);
            break;
        }
        }
        break;
    case WM_SYSCOMMAND:
        if (wParam == SC_MINIMIZE) { // 最小化時隱藏主視窗,僅留托盤
            ShowWindow(SW_HIDE);
            return 0; // 不傳遞給基類,阻止預設最小化動畫
        }
        break;
    case WM_DESTROY:
        Shell_NotifyIcon(NIM_DELETE, &m_tnid); // 程式結束移除圖標
        break;
    }
    return CFrameWnd::WindowProc(message, wParam, lParam);
}

4. 選單資源 (IDR_TRAY_MENU)

資源檢視 → 選單 → 新增:項目「顯示主視窗」(ID_TRAY_SHOW)、「結束程式」(ID_TRAY_EXIT)。在主框架用 ClassWizard 為這兩個命令加入處理函數。

關鍵細節

  • uCallbackMessage 必須在 WM_USER 以上避免衝突。
  • TrackPopupMenu 需傳入 this (主框架) 作為擁有者,否則選單可能閃退。
  • 最小化攔截在 WM_SYSCOMMAND SC_MINIMIZE,非 WM_SIZE。
  • 圖標資源建議包含 16x16、32x32 兩種尺寸適應不同 DPI。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved