Win32 API 實現系統托盤程序

jopen 10年前發布 | 61K 次閱讀 系統托盤 C/C++開發

托盤程序就是運行在系統托盤區域的程序,顯示為桌面右下角顯示區域的一個小圖標。通常托盤程序帶有幾種功能:托盤菜單,托盤圖標,氣泡提示,托盤提示。例如QQ收到消息后,會在系統右下角顯示閃動QQ圖標。

主程序Tray.cpp

    #include <windows.h>

#include "resource.h"  

#define WM_TRAY (WM_USER + 100)  
#define WM_TASKBAR_CREATED RegisterWindowMessage(TEXT("TaskbarCreated"))  

#define APP_NAME    TEXT("托盤程序")  
#define APP_TIP     TEXT("Win32 API 實現系統托盤程序")  

NOTIFYICONDATA nid;     //托盤屬性  
HMENU hMenu;            //托盤菜單  

//實例化托盤  
void InitTray(HINSTANCE hInstance, HWND hWnd)  
{  
    nid.cbSize = sizeof(NOTIFYICONDATA);  
    nid.hWnd = hWnd;  
    nid.uID = IDI_TRAY;  
    nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;  
    nid.uCallbackMessage = WM_TRAY;  
    nid.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TRAY));  
    lstrcpy(nid.szTip, APP_NAME);  

    hMenu = CreatePopupMenu();//生成托盤菜單  
    //為托盤菜單添加兩個選項  
    AppendMenu(hMenu, MF_STRING, ID_SHOW, TEXT("提示"));  
    AppendMenu(hMenu, MF_STRING, ID_EXIT, TEXT("退出"));  

    Shell_NotifyIcon(NIM_ADD, &nid);  
}  

//演示托盤氣泡提醒  
void ShowTrayMsg()  
{  
    lstrcpy(nid.szInfoTitle, APP_NAME);  
    lstrcpy(nid.szInfo, TEXT("收到一條消息!"));  
    nid.uTimeout = 1000;  
    Shell_NotifyIcon(NIM_MODIFY, &nid);  
}  

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)  
{  
    switch (uMsg)  
    {  
    case WM_TRAY:  
        switch(lParam)  
        {  
        case WM_RBUTTONDOWN:  
            {  
                //獲取鼠標坐標  
                POINT pt; GetCursorPos(&pt);  

                //解決在菜單外單擊左鍵菜單不消失的問題  
                SetForegroundWindow(hWnd);  

                //使菜單某項變灰  
                //EnableMenuItem(hMenu, ID_SHOW, MF_GRAYED);      

                //顯示并獲取選中的菜單  
                int cmd = TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, NULL, hWnd,  
                     NULL);  
                if(cmd == ID_SHOW)  
                    MessageBox(hWnd, APP_TIP, APP_NAME, MB_OK);  
                if(cmd == ID_EXIT)   
                    PostMessage(hWnd, WM_DESTROY, NULL, NULL);  
            }  
            break;  
        case WM_LBUTTONDOWN:  
            MessageBox(hWnd, APP_TIP, APP_NAME, MB_OK);  
            break;  
        case WM_LBUTTONDBLCLK:  
            break;  
        }  
        break;  
    case WM_DESTROY:  
        //窗口銷毀時刪除托盤  
        Shell_NotifyIcon(NIM_DELETE, &nid);  
        PostQuitMessage(0);  
        break;  
    case WM_TIMER:  
        ShowTrayMsg();  
        KillTimer(hWnd, wParam);  
        break;  
    }  
    if (uMsg == WM_TASKBAR_CREATED)  
    {  
        //系統Explorer崩潰重啟時,重新加載托盤  
        Shell_NotifyIcon(NIM_ADD, &nid);  
    }  
    return DefWindowProc(hWnd, uMsg, wParam, lParam);  
}  

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,   
    LPSTR /*lpCmdLine*/, int iCmdShow)  
{  
    HWND hWnd;  
    MSG msg;  
    WNDCLASS wc = { 0 };  
    wc.style = NULL;  
    wc.hIcon = NULL;  
    wc.cbClsExtra = 0;  
    wc.cbWndExtra = 0;  
    wc.hInstance = hInstance;  
    wc.lpfnWndProc = WndProc;  
    wc.hbrBackground = NULL;  
    wc.lpszMenuName = NULL;  
    wc.lpszClassName = APP_NAME;  
    wc.hCursor = NULL;  

    if (!RegisterClass(&wc)) return 0;  

    hWnd = CreateWindowEx(WS_EX_TOOLWINDOW, APP_NAME, APP_NAME, WS_POPUP, CW_USEDEFAULT,  
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);  

    ShowWindow(hWnd, iCmdShow);  
    UpdateWindow(hWnd);  

    InitTray(hInstance, hWnd);          //實例化托盤  
    SetTimer(hWnd, 3, 1000, NULL);      //定時發消息,演示氣泡提示功能  

    while (GetMessage(&msg, NULL, 0, 0))  
    {  
        TranslateMessage(&msg);  
        DispatchMessage(&msg);  
    }  
    return msg.wParam;  
}  </pre><br />

資源頭文件 resource.h

    #define IDI_TRAY    101

#define ID_SHOW     40001  
#define ID_EXIT     40002  </pre><br />

資源文件 resource.rc

 
    #include "resource.h"

IDI_TRAY ICON DISCARDABLE "ico.ico"  </pre></b><a class="CopyToClipboard" title="copy" href="/misc/goto?guid=4959548943674414965"></a></div>

</div> </div>
編譯很簡單,使用 Visual Studio建立一個空項目,建好以上3個文件,再找一個ico圖標,保存為ico.ico,即可編譯。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!