Как мне создать 32-битный значок в трее с прозрачностью (используя GDI)? - PullRequest
4 голосов
/ 08 мая 2011

Я пытаюсь создать иконку, которая отображает фрагмент текста в системном трее.(Очевидно, он не будет длиннее пары символов.)

Пока я пробовал:

#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 Ответ

4 голосов
/ 08 мая 2011

Если я правильно помню, частично прозрачный значок (который, я думаю, это то, что нужно) имеет монохромное растровое изображение для своей маски.Эта маска игнорируется, но вы все равно должны предоставить ее.Вы не создаете монохромное растровое изображение, вы, кажется, создаете растровое изображение 32bpp.Я также нигде не вижу, где вы инициализируете альфа-значения для вашего основного растрового изображения, чтобы области, в которые вы не пишете, были прозрачными.

Пример с кодом приведен здесь: Как сделатьСоздание альфа-смешанного курсора или значка в Windows XP

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...