システムトレイにアイコンを追加


システムトレイにアイコンを追加するには Shell_NotifyIcon 関数を使用します。

WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA pnid);

パラメータ

dwMessage 送信するメッセージの値。
以下の値のいずれかを指定します。
意味
NIM_ADD ステータスエリアにアイコンを追加する。
NIM_DELETE ステータスエリアからアイコンを削除する。
NIM_MODIFY ステータスエリアのアイコンを変更する。
pnid NOTIFYICONDATA 構造体へのポインタ
内容はdwMessageの値に依存します。

戻り値
   成功したとき0以外の値が返ります。
   そうでないとき0が返ります。


Sample code
#include <windows.h>
#include <tchar.h>

#define TRAY_ID  1
#define WM_TRAY  WM_USER + 1
#define IDM_EXIT 401

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

HINSTANCE hInst;
LPCTSTR lpszAppName   = TEXT("MyApp");
LPCTSTR lpszAppTitle  = TEXT("MyApp");

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    MSG        msg = {0};
    HWND       hWnd;
    WNDCLASSEX wc = {0};
    
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    UNREFERENCED_PARAMETER(nCmdShow);

    //2重起動の防止
    HANDLE hMutex = CreateMutex(FALSE, 0, lpszAppName);
    if(GetLastError() == ERROR_ALREADY_EXISTS) {
        CloseHandle(hMutex);
        return 0;
    }
    
    //メインウィンドウクラス登録
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = lpszAppName;
    wc.hIconSm       = NULL;
    if(RegisterClassEx(&wc) == 0) {
        return 0;
    }
    
    hInst = hInstance;
    
    //メインウインドウ作成
    hWnd = CreateWindow(lpszAppName, lpszAppTitle, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL
    );
    if(hWnd == NULL) {
        return 0;
    }
    
    //メイン メッセージ ループ
    while(GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg); 
        DispatchMessage(&msg);
    }
    CloseHandle(hMutex);
    return static_cast<int>(msg.wParam);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static NOTIFYICONDATA m_nid = {0};
    
    switch(uMsg) {
        case WM_COMMAND:
            switch(LOWORD(wParam)) {
                case IDM_EXIT: //終了
                    SendMessage(hWnd, WM_CLOSE, 0, 0);
                    break;
            }
            break;
        case WM_CREATE:
            {
                //システムトレイにアイコンを追加します
                m_nid.cbSize           = sizeof(NOTIFYICONDATA);
                m_nid.hWnd             = hWnd;
                m_nid.uID              = TRAY_ID;
                m_nid.uFlags           = NIF_ICON | NIF_MESSAGE | NIF_TIP;
                m_nid.uCallbackMessage = WM_TRAY;
                m_nid.hIcon            = LoadIcon(NULL, MAKEINTRESOURCE(IDI_EXCLAMATION));
                lstrcpy(m_nid.szTip, lpszAppTitle);
                if(!Shell_NotifyIcon(NIM_ADD, &m_nid)) {
                    return -1;
                }
            }
            break;
        case WM_TRAY:
            {
                if(wParam == TRAY_ID) {
                    if(lParam == WM_RBUTTONUP) {
                        //アイコンが右クリックされたら
                        //ポップアップ メニューを表示します
                        POINT pt;
                        GetCursorPos(&pt);
                        
                        HMENU hMenuPop = CreatePopupMenu();
                        AppendMenu(hMenuPop, MF_BYCOMMAND | MF_STRING, IDM_EXIT, TEXT("終了(&X)"));
                        SetForegroundWindow(hWnd);
                        TrackPopupMenu(hMenuPop, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hWnd, NULL);
                        MSG msg;
                        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
                            TranslateMessage(&msg);
                            DispatchMessage(&msg);
                        }
                        DestroyMenu(hMenuPop);
                    }
                }
            }
            break;
        case WM_DESTROY:
            {
                //システムトレイからアイコンを削除します
                Shell_NotifyIcon(NIM_DELETE, &m_nid);
                PostQuitMessage(0);
            }
            break;
        default:
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    
    return 0;
}

一覧メニューへ