Advanced member
Статус: Не в сети Регистрация: 09.06.2003 Откуда: USSR
Наверное не только я сталкивался с тем, что иногда надо динамически создавать иконки. Чаще всего это надо для системного трея где показывается скажем температуры . Лично я видел две процедуры по переводу текста в иконку, первая была слабая не давала создавать иконки с прозрачным фоном.
Вторую я доработал, но она использует прибамбасы Delphi (что не есть хорошо если пишеш на чистом API). Вот сегодня сделал третий вариант на чистом API.
Выкладываю сюда так как многим может понадобится.
Функция StringToIcon создает 16х16 иконку, если надо другой размер то сами можете модифицировать.
Код:
unit strtoicon;
interface uses Windows;
function StringToIcon (const st : string;textcolor:dword) : HIcon; procedure GetMaskBitmaps(hSourceBitmap:HBITMAP;clrTransparent:dword; var hAndMaskBitmap:HBitmap;var hXorMaskBitmap:HBitmap); function CreateIconFromBitmap(hSourceBitmap:HBITMAP;clrTransparent:DWORD):HICON;
implementation
procedure GetMaskBitmaps(hSourceBitmap: HBITMAP; clrTransparent: dword; var hAndMaskBitmap, hXorMaskBitmap: HBitmap); var dc:HDC; hMainDC:HDC; hAndMaskDC:HDC; hXorMaskDC:HDC; bm:BITMAP; hOldMainBitmap:HBitmap; hOldAndMaskBitmap:HBitmap; hOldXorMaskBitmap:HBitmap; MainBitPixel:DWORD; x,y:longint; begin DC:=GetDC(0); hMainDC:=CreateCompatibleDC(DC); hAndMaskDC:=CreateCompatibleDC(DC); hXorMaskDC:=CreateCompatibleDC(DC);
for x:=0 to bm.bmWidth-1 do begin for y:=0 to bm.bmHeight-1 do begin MainBitPixel := GetPixel(hMainDC,x,y); if(MainBitPixel = clrTransparent) then begin SetPixel(hAndMaskDC,x,y,RGB(255,255,255)); SetPixel(hXorMaskDC,x,y,RGB(0,0,0)); end else begin SetPixel(hAndMaskDC,x,y,RGB(0,0,0)); SetPixel(hXorMaskDC,x,y,MainBitPixel); end; end; end;
function CreateIconFromBitmap(hSourceBitmap: HBITMAP; clrTransparent: DWORD): HICON; var hAndMask:HBITMAP; hXorMask:HBITMAP; iconinfo:TICONINFO; begin GetMaskBitmaps(hSourceBitmap,clrTransparent,hAndMask,hXorMask); if(hAndMask=0) or (hXorMask=0) then begin result:=0; exit; end;
result := CreateIconIndirect(iconinfo); DeleteObject(hAndMask); DeleteObject(hXorMask); end;
function StringToIcon (const st : string;textcolor:dword) : HIcon; var bm:HBitmap; dc:HDC; hb,font:THandle; brush:TLogBrush; r:TRect; begin bm:=CreateBitmap(16,16,1,32,nil); dc:=CreateCompatibleDC(0); DeleteObject(SelectObject(dc,bm));
Member
Статус: Не в сети Регистрация: 23.09.2003 Откуда: South Ural
Ray Adams
Цитата:
Зачем? При неудачном DeleteObject ничего не произойдет
имелся в виду конечно же try-finally а ты попробуй убрать освобождение хоть одного объекта и повыводи иконку в трей - гарантировано через некоторое время (в зависимости от интенсивности обновления иконки) твоя программа сожрет все gdi-ресурсы
Цитата:
Хмм, а теперь твой код пашет. Так почему до этого не пахал?
потому что "до этого" был ТВОЙ код обрати внимание на TransparentBkColor
Member
Статус: Не в сети Регистрация: 23.09.2003 Откуда: South Ural
Ray Adams замерь
Добавлено спустя 5 минут, 32 секунды: хотя можно проанализировать код
Код:
int WINAPI ImageList_AddMaskedHelper(IMAGELIST* piml, HBITMAP hbmImage, COLORREF crMask) { COLORREF crbO, crtO; HBITMAP hbmMask; int cImage; int retval; int n,i; BITMAP bm; DWORD ColorTableSave[256]; DWORD ColorTable[256];
if (GetObject(hbmImage, sizeof(bm), &bm) != sizeof(bm)) return -1;
hbmMask = CreateMonoBitmap(bm.bmWidth, bm.bmHeight); if (!hbmMask) return -1;
ENTERCRITICAL;
// copy color to mono, with crMask turning 1 and all others 0, then // punch all crMask pixels in color to 0 ImageList_SelectSrcBitmap(hbmImage); ImageList_SelectDstBitmap(hbmMask);
// crMask == CLR_DEFAULT, means use the pixel in the upper left // if (crMask == CLR_DEFAULT) crMask = GetPixel(g_hdcSrc, 0, 0);
// DIBSections dont do color->mono like DDBs do, so we have to do it. // this only works for <=8bpp DIBSections, this method does not work // for HiColor DIBSections. // // Please note, this code has an endianship problems the comparision in the if statement // below is sensitive to endianship // ----> if (ColorTableSave[i] == RGB(GetBValue(crMask),GetGValue(crMask),GetRValue(crMask)) // if (bm.bmBits != NULL && bm.bmBitsPixel <= 8) { n = GetDIBColorTable(g_hdcSrc, 0, 256, (RGBQUAD*)ColorTableSave);
for (i=0; i<n; i++) { if (ColorTableSave[i] == RGB(GetBValue(crMask),GetGValue(crMask),GetRValue(crMask))) ColorTable[i] = 0x00FFFFFF; else ColorTable[i] = 0x00000000; }
SetDIBColorTable(g_hdcSrc, 0, n, (RGBQUAD*)ColorTable); } else if (bm.bmBits != NULL && bm.bmBitsPixel > 8) { RIPMSG(0, "ImageList_AddMask on a bmp with more than 256 colors is not supported\r\nFix your bmp to use fewer colors"); }
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения