如何创建具有透明度的32位托盘图标(使用GDI)?

时间:2011-05-08 08:57:37

标签: winapi gdi system-tray trayicon

我正在尝试创建一个在系统托盘中显示一段文字的图标。 (显然,它不会超过几个字符。)

到目前为止,我已经尝试过:

#include <tchar.h>
#include <Windows.h>
#include <Windowsx.h>

static HICON CreateIcon(LPCTSTR txt) {
    HICON hIcon = NULL;
    HDC hDC = NULL; {
        HDC hDCScreen = GetDC(NULL);
        if (hDCScreen != NULL) {
            __try { hDC = CreateCompatibleDC(hDCScreen); }
            __finally { ReleaseDC(NULL, hDCScreen); }
        }
    }
    if (hDC != NULL) {
        __try {
            HFONT hFont = CreateFontIndirect(&ncm.lfMessageFont);
            if (hFont != NULL) {
                __try { SelectFont(hDC, hFont); }
                __finally { DeleteFont(hFont); }
            }
            int width = GetSystemMetrics(SM_CXSMICON),
                height = GetSystemMetrics(SM_CYSMICON);
            HBITMAP hBmp = CreateCompatibleBitmap(hDC, width, height);
            if (hBmp != NULL) {
                __try {
                    HBITMAP hMonoBmp =
                        CreateCompatibleBitmap(hDC, width, height);
                    if (hMonoBmp != NULL) {
                        __try {
                            RECT rect = { 0, 0, width, height };
                            HGDIOBJ prev = SelectObject(hDC, hBmp);
                            __try {
                                SetBkMode(hDC, TRANSPARENT);
                                SetTextColor(hDC, RGB(255, 255, 255));
                                ICONINFO ii = { TRUE, 0, 0, hMonoBmp, hBmp };
                                int textHeight =
                                    DrawText(hDC, txt, _tcslen(txt), &rect, 0);
                                if (textHeight != 0) {
                                    hIcon = CreateIconIndirect(&ii);
                                }
                            } __finally { SelectObject(hDC, prev); }
                        } __finally { DeleteObject(hMonoBmp); }
                    }
                } __finally { DeleteObject(hBmp); }
            }
        } __finally { DeleteDC(hDC); }
    }
    return hIcon;
}

使用此代码:

static void _tmain(int argc, TCHAR* argv[]) {
    HICON hIcon = CreateIcon(_T("Hi"));
    if (hIcon != NULL) {
        __try {
            NOTIFYICONDATA nid = { sizeof(nid) };
            nid.hWnd = GetConsoleWindow();
            BOOL success = Shell_NotifyIcon(NIM_ADD, &nid);
            if (success) {
                nid.uFlags = NIF_ICON;
                nid.hIcon = hIcon;
                success = Shell_NotifyIcon(NIM_MODIFY, &nid);
            }
        } __finally { DestroyIcon(hIcon); }
    }
}

但我得到的是一个单色位图,在黑色背景上的白色文字中显示Hi。 (如果我稍微更改RGB(255, 255, 255),请说RGB(255, 255, 254),它变为黑色,因此它是单色的。)

有什么想法吗?

(*注意:我正在寻找MFC,ATL或任何其他库解决方案,只需要Win32 / GDI调用。)


修改

以下是目前的情况:

1 个答案:

答案 0 :(得分:4)

如果我没记错的话,部分透明的图标(我认为是想要的)有一个单色的位图作为其掩码。这个面具恰好被忽略了,但你仍然必须提供它。您没有创建单色位图,您似乎正在创建32bpp位图。我也没有看到你为主位图初始化alpha值的任何地方,以便你不写入的区域是透明的。

此处提供了代码示例:How To Create an Alpha Blended Cursor or Icon in Windows XP