开发者

How Do I Create a 32-bit Tray Icon With Transparency (using GDI)?

I'm trying to create an icon that displays a piece of text in the system tray. (Obviously, it won't be longer than a couple of characters.)

So far I've tried:

#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 };
    开发者_如何学C                            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;
}

with this code:

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); }
    }
}

but all I get is a monochrome bitmap that says Hi in white text on a black background. (If I change the RGB(255, 255, 255) even slightly, say to RGB(255, 255, 254), it becomes black, so it's monochrome.)

Any ideas?

(*Note: I'm not looking for MFC, ATL, or any other library solutions, just Win32/GDI calls.)


Edit:

Here's what it looks like currently:

How Do I Create a 32-bit Tray Icon With Transparency (using GDI)?


If I recall correctly, a partially transparent icon (which I think is what want) has a monochrome bitmap for its mask. This mask happens to be ignored but you still have to supply it. You aren't creating a monochrome bitmap, you appear to be creating a 32bpp bitmap. I also don't see anywhere where you initialise the alpha values for you main bitmap so that the areas which you don't write to are transparent.

An example with code is provided here: How To Create an Alpha Blended Cursor or Icon in Windows XP

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜