我有一个使用系统托盘中“标准”图标的MFC C++(非托管)Windows应用程序。这个图标是使用Visual Studio编辑的&创建的,只有4位颜色的32x32像素(根据VS的资源编辑器)。如何在从非托管C程序在Windows系统托盘图标上书写文本时保持透明
使用Visual Studio,我还设置了透明背景(在“之前”图像中显示为白色)。
我希望通过在上面写入2位数字(1-99)来动态更改图标。
使用下面的代码(系基于这样一个问题:How to draw text with transparency using GDI?)叠加“55”,在黄色的图标,它的工作原理不同之处在于透明度消失(出现黑色图像“之后”,并在系统托盘)。我的实际代码与字体大小(20),字体名称(Courier New),文本颜色(黄色--RGB(255,255,0))和数字值(55)之间的差异非常小,而非运行时变量比固定值。
有关如何使背景保持透明的任何建议,只要感谢系统托盘的关注。
这些图像已使用MS的剪切工具捕获,并且在MS Paint中打开该图像,因为32x32图标不会非常明显。
图像之前:
图像后:
代码:
void CreateNewIcon(HICON &hNewIcon, HICON hBackgroundIcon)
{
::DestroyIcon(hNewIcon);
// First create font
LOGFONT lf = { 0 };
lf.lfHeight = -20;
lf.lfWeight = FW_BOLD;
lf.lfOutPrecision = OUT_TT_PRECIS;
lf.lfQuality = CLEARTYPE_QUALITY;
wmemset(lf.lfFaceName, 0, LF_FACESIZE);
lstrcpy(lf.lfFaceName, L"Courier New");
HFONT hFont = ::CreateFontIndirect(&lf);
ICONINFO ii = { 0 };
::GetIconInfo(hBackgroundIcon, &ii);
BITMAP bm = { 0 };
::GetObject(ii.hbmColor, sizeof(bm), &bm);
SIZE szBmp = { bm.bmWidth, bm.bmHeight };
HDC hDc = ::GetDC(NULL);
HDC hMemDC = ::CreateCompatibleDC(hDc);
HGDIOBJ hOldBmp = ::SelectObject(hMemDC, ii.hbmColor);
HGDIOBJ hOldFont = ::SelectObject(hMemDC, hFont);
::SetBkMode(hMemDC, TRANSPARENT);
::SetTextColor(hMemDC, RGB(255, 255, 0));
::TextOut(hMemDC, 0, 8, L"55", 2);
::SelectObject(hMemDC, hOldFont);
::SelectObject(hMemDC, hOldBmp);
// We need a simple mask bitmap for the icon
HBITMAP hBmpMsk = ::CreateBitmap(szBmp.cx, szBmp.cy, 1, 1, NULL);
ICONINFO ii2 = { 0 };
ii2.fIcon = TRUE;
ii2.hbmColor = ii.hbmColor;
ii2.hbmMask = hBmpMsk;
// Create updated icon
hNewIcon = ::CreateIconIndirect(&ii2);
// Cleanup
::DeleteObject(hBmpMsk);
::DeleteDC(hMemDC);
::ReleaseDC(NULL, hDc);
::DeleteObject(ii.hbmColor);
::DeleteObject(ii.hbmMask);
::DeleteObject(hFont);
}
带图标这个小的质量(32×32),我并不需要明确的字体类型,所以我现在已经commentted了两个“lf.lfOutPrecision”和“lf.lfQuality”。但我该如何“适当地填充此掩码位图”? – DDK
实际上,托盘图标大小取决于系统设置,可能会有所不同,因此您应该使用[GetSystemMetrics with SM_CXSMICON and SM_CYSMICON](https://msdn.microsoft.com/en-us/library/windows/desktop/ms724385(v = vs.85)的.aspx)。注释掉'lf.lfQuality'使其包含DEFAULT_QUALITY(0),这不一定意味着没有明文类型。无论如何,我已经编辑了我的原始答案,因为我的评论空间不足了。 – VTT
任何机会的一些模板代码我修改,因为我不知道你的建议是什么?至于图标大小,这个应用程序已经运行了多年,从XP到W10使用当前的System Tray图标,我只是在运行时修改它,所以我认为我会保持它的当前大小。我也可以改变这一点,一旦这是32x32的工作。刚刚测试过:SM_CXICON = 32和SM_CXSMICON = 16。 – DDK