2011-09-18 25 views
1

我有一個類似的問題,How to display text in system tray icon with win32 API?如何使用Win32 API的C++顯示系統托盤圖標的文字 - 第2部分

我想他的解決方案,但它不是爲我工作。我得到一個小的4x16白色圖像作爲系統圖標而不是文本,我不明白爲什麼。

我不使用MFC/.NET只是win32 api。

void UpdateIcon(HWND hWnd){ 
    NOTIFYICONDATA nid; 
    nid.cbSize = sizeof(NOTIFYICONDATA); 
    nid.hWnd = hWnd; 
    nid.uID = 100; 
    nid.hIcon = CreateSmallIcon(hWnd); 
    nid.uFlags = NIF_ICON; 
    Shell_NotifyIcon(NIM_MODIFY, &nid); 
} 

HICON CreateSmallIcon(HWND hWnd) 
{ 
    static TCHAR *szText = TEXT ("100"); 
    HDC hdc, hdcMem; 
    HBITMAP hBitmap = NULL; 
    HBITMAP hOldBitMap = NULL; 
    HBITMAP hBitmapMask = NULL; 
    ICONINFO iconInfo; 
    HFONT hFont; 
    HICON hIcon; 

    hdc = GetDC (hWnd); 
    hdcMem = CreateCompatibleDC (hdc); 
    hBitmap = CreateCompatibleBitmap (hdc, 16, 16); 
    hBitmapMask = CreateCompatibleBitmap (hdc, 16, 16); 
    ReleaseDC (hWnd, hdc); 
    hOldBitMap = (HBITMAP) SelectObject (hdcMem, hBitmap); 
    PatBlt (hdcMem, 0, 0, 16, 16, WHITENESS); 

    // Draw percentage 
    hFont = CreateFont (12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        TEXT ("Arial")); 
    hFont = (HFONT) SelectObject (hdcMem, hFont); 
    TextOut (hdcMem, 0, 0, szText, lstrlen (szText)); 

    SelectObject (hdc, hOldBitMap); 
    hOldBitMap = NULL; 

    iconInfo.fIcon = TRUE; 
    iconInfo.xHotspot = 0; 
    iconInfo.yHotspot = 0; 
    iconInfo.hbmMask = hBitmapMask; 
    iconInfo.hbmColor = hBitmap; 

    hIcon = CreateIconIndirect (&iconInfo); 

    DeleteObject (SelectObject (hdcMem, hFont)); 
    DeleteDC (hdcMem); 
    DeleteDC (hdc); 
    DeleteObject (hBitmap); 
    DeleteObject (hBitmapMask); 

    return hIcon; 
} 

回答

1

我沒有當前安裝的窗口,所以我不能檢查,如果這樣會更好地工作,但我發現潛在的問題 - 從CreateIconIndirect function MSDN文檔:

應用程序必須繼續管理原始位圖並在不再需要時刪除它們。

看起來像你過早刪​​除位圖。

+0

也許調用DuplicateIcon(NULL,hIcon),銷燬hIcon,然後返回重複的圖標。沒有嘗試過,但可能值得一試。 – pezcode

+0

我寧願推薦 - 因爲它被提及 - 只是存儲somwhere那些位圖和掩碼,直到新圖標被創建。 –

0

您需要設置背景和可能的前景顏色:

SetTextColor(hdcMem, 0x00FF0000); // 0x00bbggrr, not rrggbb !! 
SetBkMode(hdcMem, TRANSPARENT); // VERY IMPORTANT 

我想你使用GetDC()這裏不需要DeleteDC (hdc);

+0

沒有必要使用'DeleteDC',因爲應該使用'ReleaseDC'來代替。 –

+0

'ReleasedDC'實際上用在@ stack356的代碼片段中的'hdc'(由'GetDC'提供)。 'hdcMem'(由'CreateCompatibleDC'提供)是'DeleteDC''。唯一的問題是這裏多餘的'DeleteDC(hdc)'。 – foudfou