Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Рисование иконки в рантайме


Автор: Straight 2.6.2009, 12:18
Хочу динамически создать иконку с изменяемым изображением
В GDI+ вроде все просто:
Код

    Bitmap bitmap(16,16);
    Pen whitePen(Color(255, 255, 255));
    Graphics *graph = Graphics::FromImage(&bitmap);
    //что-нибудь рисуем, напрмер
    graph->DrawLine(&whitePen, 0, 15, 15, 15);
    graph->DrawLine(&whitePen, 0,  0, 15,  0);
    bitmap.GetHICON(&hIcon);


Но к сожалению в приложении GDI+ использовать нельзя. Как сделать то же самое используя чистый GDI?

Автор: Andrey44 2.6.2009, 12:38
::DrawIconEx

Автор: Straight 2.6.2009, 12:48
Немного не то. В исходном коде создается битмап и из него создается иконка.

Автор: Andrey44 2.6.2009, 12:52
HICON CreateIconIndirect(
  PICONINFO piconinfo
);

Автор: Straight 2.6.2009, 12:59
Да это понятно, в MSDN не забанен.
Непонятно чем проинициализировать ICONINFO::hbmMask (черно-белый битмап) и  ICONINFO::hbmColor (цветной).
Заметил что если hbmMask == 0, то иконка полностью черная.

Автор: Andrey44 2.6.2009, 14:28
Вот есть у меня пример создания иконки из текста.
Я думаю не трудно будет переработать под свои нужды
Код

//THE CODE WAS WRITTEN BY jonie
    /*
  НЕ передавайте строку что больше 3-х символов
  (качество будет отврат + см. код)
  По аналогии рисуем _что_ хотите.
*/
HICON CreateIconFromText(LPCTSTR text,COLORREF color)
{
int cxIcon = GetSystemMetrics(SM_CXSMICON);
int cyIcon = GetSystemMetrics(SM_CYSMICON);
HDC hdcDisplay = GetDC(NULL);
if (!hdcDisplay){
    return NULL;
}
HDC hdcXOR = CreateCompatibleDC(hdcDisplay);
if (!hdcXOR){
    ReleaseDC(NULL, hdcDisplay);
    return NULL;
}
HDC hdcAND = CreateCompatibleDC(hdcXOR);
if (!hdcAND){
    DeleteDC(hdcXOR);
    ReleaseDC(NULL, hdcDisplay);
    return NULL;
}
ICONINFO iconinfo;
ZeroMemory(&iconinfo,sizeof(ICONINFO));
iconinfo.fIcon = TRUE;
iconinfo.hbmMask = CreateCompatibleBitmap(hdcDisplay,cxIcon, cyIcon);
if (!iconinfo.hbmMask){
    DeleteDC(hdcAND);
    DeleteDC(hdcXOR);
    ReleaseDC(NULL, hdcDisplay);
    return NULL;
}
iconinfo.hbmColor = CreateCompatibleBitmap(hdcDisplay, cxIcon, cyIcon);
if (!iconinfo.hbmColor){
    DeleteObject(iconinfo.hbmMask);
    DeleteDC(hdcAND);
    DeleteDC(hdcXOR);
    ReleaseDC(NULL, hdcDisplay);
    return NULL;
}
ReleaseDC(NULL, hdcDisplay);
HBITMAP hbmMaskOld  = (HBITMAP)SelectObject(hdcAND, iconinfo.hbmMask);
PatBlt(hdcAND, 0, 0, cxIcon, cyIcon, WHITENESS);
HBITMAP hbmColorOld = (HBITMAP)SelectObject(hdcXOR, iconinfo.hbmColor);
PatBlt(hdcXOR, 0, 0, cxIcon, cyIcon, BLACKNESS);
LOGFONT lf;
ZeroMemory(&lf,sizeof(LOGFONT));
lf.lfCharSet            = ANSI_CHARSET;
lf.lfOutPrecision       = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision      = CLIP_DEFAULT_PRECIS;
lf.lfQuality            = ANTIALIASED_QUALITY; //DEFAULT_QUALITY;
lf.lfPitchAndFamily     = DEFAULT_PITCH;
lf.lfHeight                = cyIcon;
lf.lfWidth                = cxIcon / 3; //делим на кол-во букв (3 макс для читабельного текста)
lf.lfWeight                = FW_NORMAL;
strcpy_s(lf.lfFaceName,_countof(lf.lfFaceName),TEXT("Arial"));
HFONT hfontXOROld  = NULL;
HFONT hfontANDOld  = NULL;
HFONT hfont = CreateFontIndirect(&lf);
if (hfont){
    hfontXOROld  = (HFONT)SelectObject(hdcAND, hfont);
    hfontANDOld  = (HFONT)SelectObject(hdcXOR, hfont);
}
COLORREF rgbOld        = SetTextColor(hdcXOR, color);
int nBkModeXOROld   = SetBkMode(hdcAND,  TRANSPARENT);
int nBkModeANDOld   = SetBkMode(hdcXOR, TRANSPARENT);
RECT rc; rc.left = 0; rc.top = 0; rc.right = cxIcon; rc.bottom = cyIcon;
DrawText(hdcAND,  text, -1, &rc,  DT_CENTER | DT_VCENTER | DT_SINGLELINE);
DrawText(hdcXOR, text, -1, &rc,  DT_CENTER | DT_VCENTER | DT_SINGLELINE);
SetBkMode(hdcAND,  nBkModeXOROld);
SetBkMode(hdcXOR, nBkModeANDOld);
SetTextColor(hdcXOR, rgbOld);
if (hfontXOROld)
    SelectObject(hdcAND, hfontXOROld);
if (hfontANDOld)
    SelectObject(hdcXOR, hfontANDOld);
if (hfont)
    DeleteObject(hfont);
if (hbmMaskOld)
    SelectObject(hdcAND, hbmMaskOld);
if (hbmColorOld)
    SelectObject(hdcXOR, hbmColorOld);
DeleteDC(hdcAND);
DeleteDC(hdcXOR);
HICON hIcon = CreateIconIndirect(&iconinfo);
DeleteObject(iconinfo.hbmColor);
DeleteObject(iconinfo.hbmMask);
return hIcon;
}

Автор: jonie 2.6.2009, 15:42
Ы мой код.http://forum.vingrad.ru/forum/topic-62015/unread-1/hl/createiconfromtext/index.html
но там есть бага, у меня иногда после "выключения" из 3D игр например фон становится черным 8-(
я так и не решил ту проблему ... а потом забил.

Автор: Andrey44 3.6.2009, 07:05
jonie, да, точно, я взял этот код на форуме, но уже забыл где и кто написал. smile 
Я подправил свой предыдущий пост. Спасибо за код.
Я правда его потом переделал под картинку и все нормально рботает.

Автор: Straight 3.6.2009, 11:36
Спасибо, хорошее решение.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)