Как отобразить текст в значке в системном трее с Win32 API C++ - часть 2
У меня есть вопрос, подобный этому, Как отобразить текст в значке в системном трее с Win32 API?
Я попробовал его решение, но оно не работает для меня. Я получаю маленькое белое изображение 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;
}
2 ответа
У меня не установлены окна в настоящее время, поэтому я не могу проверить, будет ли это работать лучше, но я обнаружил потенциальную проблему - из документации MSDN функции CreateIconIndirect:
Приложение должно продолжать управлять исходными растровыми изображениями и удалять их, когда они больше не нужны.
Похоже, вы удаляете растровые изображения слишком рано.
Вам нужно установить фон и, возможно, цвета переднего плана:
SetTextColor( hdcMem, 0x00FF0000 ); // 0x00bbggrr, not rrggbb !!
SetBkMode( hdcMem, TRANSPARENT ); // VERY IMPORTANT
Я думаю DeleteDC ( hdc );
здесь не нужно, как вы использовали GetDC()
,