Автор: Ruslan Abu Zant Данный код сперва конвертирует Ваш текст в DIB, а затем DIB в иконку и далее в ресурс. После этого изображение иконки отображается в System Tray.
Вызов просходит следующим образом....
StringToIcon('This Is Made By Ruslan K. Abu Zant');
N.B>> Не забудьте удалить объект HIcon, после вызова функции...
type TForm1 = class(TForm) Button1: TButton; Image1: TImage; Timer1: TTimer; procedure Button1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); private function StringToIcon(const st: string): HIcon; public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.DFM}
type ICONIMAGE = record Width, Height, Colors: DWORD; // Ширина, Высота и кол-во цветов lpBits: PChar; // указатель на DIB биты dwNumBytes: DWORD; // Сколько байт? lpbi: PBitmapInfoHeader; // указатель на заголовок lpXOR: PChar; // указатель на XOR биты изображения lpAND: PChar; // указатель на AND биты изображения end;
function CopyColorTable(var lpTarget: BITMAPINFO; const lpSource: BITMAPINFO): boolean; var dc: HDC; hPal: HPALETTE; pe: array[0..255] of PALETTEENTRY; i: Integer; begin result := False; case (lpTarget.bmiHeader.biBitCount) of 8: if lpSource.bmiHeader.biBitCount = 8then begin Move(lpSource.bmiColors, lpTarget.bmiColors, 256 * sizeof(RGBQUAD)); result := True end else begin dc := GetDC(0); if dc <> 0then try hPal := CreateHalftonePalette(dc); if hPal <> 0then try if GetPaletteEntries(hPal, 0, 256, pe) <> 0then begin for i := 0to255do begin lpTarget.bmiColors[i].rgbRed := pe[i].peRed; lpTarget.bmiColors[i].rgbGreen := pe[i].peGreen; lpTarget.bmiColors[i].rgbBlue := pe[i].peBlue; lpTarget.bmiColors[i].rgbReserved := pe[i].peFlags end; result := True end finally DeleteObject(hPal) end finally ReleaseDC(0, dc) end end;
4: if lpSource.bmiHeader.biBitCount = 4then begin Move(lpSource.bmiColors, lpTarget.bmiColors, 16 * sizeof(RGBQUAD)); result := True end else begin hPal := GetStockObject(DEFAULT_PALETTE); if (hPal <> 0) and (GetPaletteEntries(hPal, 0, 16, pe) <> 0) then begin for i := 0to15do begin lpTarget.bmiColors[i].rgbRed := pe[i].peRed; lpTarget.bmiColors[i].rgbGreen := pe[i].peGreen; lpTarget.bmiColors[i].rgbBlue := pe[i].peBlue; lpTarget.bmiColors[i].rgbReserved := pe[i].peFlags end; result := True end end; 1: begin i := 0; lpTarget.bmiColors[i].rgbRed := 0; lpTarget.bmiColors[i].rgbGreen := 0; lpTarget.bmiColors[i].rgbBlue := 0; lpTarget.bmiColors[i].rgbReserved := 0; i := 1; lpTarget.bmiColors[i].rgbRed := 255; lpTarget.bmiColors[i].rgbGreen := 255; lpTarget.bmiColors[i].rgbBlue := 255; lpTarget.bmiColors[i].rgbReserved := 0; result := True end; else result := True end end;
function WidthBytes(bits: DWORD): DWORD; begin result := ((bits + 31) shr5) shl2 end;
function BytesPerLine(const bmih: BITMAPINFOHEADER): DWORD; begin result := WidthBytes(bmih.biWidth * bmih.biPlanes * bmih.biBitCount) end;
function DIBNumColors(const lpbi: BitmapInfoHeader): word; var dwClrUsed: DWORD; begin dwClrUsed := lpbi.biClrUsed; if dwClrUsed <> 0then result := Word(dwClrUsed) else case lpbi.biBitCount of 1: result := 2; 4: result := 16; 8: result := 256 else result := 0 end end;
function PaletteSize(const lpbi: BitmapInfoHeader): word; begin result := DIBNumColors(lpbi) * sizeof(RGBQUAD) end;
function FindDIBBits(const lpbi: BitmapInfo): PChar; begin result := @lpbi; result := result + lpbi.bmiHeader.biSize + PaletteSize(lpbi.bmiHeader) end;
function ConvertDIBFormat(var lpSrcDIB: BITMAPINFO; nWidth, nHeight, nbpp: DWORD; bStretch: boolean): PBitmapInfo; var lpbmi: PBITMAPINFO; lpSourceBits, lpTargetBits: Pointer; DC, hSourceDC, hTargetDC: HDC; hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap: HBITMAP; dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize: DWORD; begin result := nil; // Располагаем и заполняем структуру BITMAPINFO для нового DIB // Обеспечиваем достаточно места для 256-цветной таблицы dwTargetHeaderSize := sizeof(BITMAPINFO) + (256 * sizeof(RGBQUAD)); GetMem(lpbmi, dwTargetHeaderSize); try lpbmi^.bmiHeader.biSize := sizeof(BITMAPINFOHEADER); lpbmi^.bmiHeader.biWidth := nWidth; lpbmi^.bmiHeader.biHeight := nHeight; lpbmi^.bmiHeader.biPlanes := 1; lpbmi^.bmiHeader.biBitCount := nbpp; lpbmi^.bmiHeader.biCompression := BI_RGB; lpbmi^.bmiHeader.biSizeImage := 0; lpbmi^.bmiHeader.biXPelsPerMeter := 0; lpbmi^.bmiHeader.biYPelsPerMeter := 0; lpbmi^.bmiHeader.biClrUsed := 0; lpbmi^.bmiHeader.biClrImportant := 0; // Заполняем в таблице цветов if CopyColorTable(lpbmi^, lpSrcDIB) then begin DC := GetDC(0); hTargetBitmap := CreateDIBSection(DC, lpbmi^, DIB_RGB_COLORS, lpTargetBits, 0, 0); hSourceBitmap := CreateDIBSection(DC, lpSrcDIB, DIB_RGB_COLORS, lpSourceBits, 0, 0);
try if (dc <> 0) and (hTargetBitmap <> 0) and (hSourceBitmap <> 0) then begin hSourceDC := CreateCompatibleDC(DC); hTargetDC := CreateCompatibleDC(DC); try if (hSourceDC <> 0) and (hTargetDC <> 0) then begin // Flip the bits on the source DIBSection to match the source DIB dwSourceBitsSize := DWORD(lpSrcDIB.bmiHeader.biHeight) * BytesPerLine(lpSrcDIB.bmiHeader); dwTargetBitsSize := DWORD(lpbmi^.bmiHeader.biHeight) * BytesPerLine(lpbmi^.bmiHeader); Move(FindDIBBits(lpSrcDIB)^, lpSourceBits^, dwSourceBitsSize);
try if (hOldSourceBitmap <> 0) and (hOldTargetBitmap <> 0) then begin // Устанавливаем таблицу цветов для DIBSections if lpSrcDIB.bmiHeader.biBitCount <= 8then SetDIBColorTable(hSourceDC, 0, 1shl lpSrcDIB.bmiHeader.biBitCount, lpSrcDIB.bmiColors);
if lpbmi^.bmiHeader.biBitCount <= 8then SetDIBColorTable(hTargetDC, 0, 1shl lpbmi^.bmiHeader.biBitCount, lpbmi^.bmiColors);
// If we are asking for a straight copy, do it if (lpSrcDIB.bmiHeader.biWidth = lpbmi^.bmiHeader.biWidth) and (lpSrcDIB.bmiHeader.biHeight = lpbmi^.bmiHeader.biHeight) then BitBlt(hTargetDC, 0, 0, lpbmi^.bmiHeader.biWidth, lpbmi^.bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY) elseif bStretch then begin SetStretchBltMode(hTargetDC, COLORONCOLOR); StretchBlt(hTargetDC, 0, 0, lpbmi^.bmiHeader.biWidth, lpbmi^.bmiHeader.biHeight, hSourceDC, 0, 0, lpSrcDIB.bmiHeader.biWidth, lpSrcDIB.bmiHeader.biHeight, SRCCOPY) end else BitBlt(hTargetDC, 0, 0, lpbmi^.bmiHeader.biWidth, lpbmi^.bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY);
Move(lpbmi^, result^, dwTargetHeaderSize); Move(lpTargetBits^, FindDIBBits(result^)^, dwTargetBitsSize) end finally if hOldSourceBitmap <> 0then SelectObject(hSourceDC, hOldSourceBitmap); if hOldTargetBitmap <> 0then SelectObject(hTargetDC, hOldTargetBitmap); end end finally if hSourceDC <> 0then DeleteDC(hSourceDC); if hTargetDC <> 0then DeleteDC(hTargetDC) end end; finally if hTargetBitmap <> 0then DeleteObject(hTargetBitmap); if hSourceBitmap <> 0then DeleteObject(hSourceBitmap); if dc <> 0then ReleaseDC(0, dc) end end finally FreeMem(lpbmi) end end;
function DIBToIconImage(var lpii: ICONIMAGE; var lpDIB: BitmapInfo; bStretch: boolean): boolean; var lpNewDIB: PBitmapInfo; begin result := False; lpNewDIB := ConvertDIBFormat(lpDIB, lpii.Width, lpii.Height, lpii.Colors, bStretch); if Assigned(lpNewDIB) then try
lpii.dwNumBytes := sizeof(BITMAPINFOHEADER) // Заголовок + PaletteSize(lpNewDIB^.bmiHeader) // Палитра + lpii.Height * BytesPerLine(lpNewDIB^.bmiHeader) // XOR маска + lpii.Height * WIDTHBYTES(lpii.Width); // AND маска // Если здесь уже картинка, то освобождаем её if lpii.lpBits <> nilthen FreeMem(lpii.lpBits);
GetMem(lpii.lpBits, lpii.dwNumBytes); Move(lpNewDib^, lpii.lpBits^, sizeof(BITMAPINFOHEADER) + PaletteSize (lpNewDIB^.bmiHeader)); // Выравниваем внутренние указатели/переменные для новой картинки lpii.lpbi := PBITMAPINFOHEADER(lpii.lpBits); lpii.lpbi^.biHeight := lpii.lpbi^.biHeight * 2;
procedure TForm1.Timer1Timer(Sender: TObject); const i: Integer = 0; begin Inc(i); if i = 100then i := 1; Application.Icon.Handle := StringToIcon(IntToStr(i));