Отображаем текст в System Tray.
Отображаем текст в System Tray.
Автор: Ruslan Abu Zant
Данный код сперва конвертирует Ваш текст в DIB, а затем DIB в иконку и далее в ресурс. После этого изображение иконки отображается в System Tray.
Вызов просходит следующим образом....
StringToIcon('This Is Made By Ruslan K. Abu Zant');
N.B>> Не забудьте удалить объект HIcon, после вызова функции...
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
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 = 8 then
begin
Move(lpSource.bmiColors, lpTarget.bmiColors, 256 * sizeof(RGBQUAD));
result := True
end
else
begin
dc := GetDC(0);
if dc <> 0 then
try
hPal := CreateHalftonePalette(dc);
if hPal <> 0 then
try
if GetPaletteEntries(hPal, 0, 256, pe) <> 0 then
begin
for i := 0 to 255 do
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 = 4 then
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 := 0 to 15 do
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) shr 5) shl 2
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 <> 0 then
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);
// Select DIBSections into DCs
hOldSourceBitmap := SelectObject(hSourceDC, hSourceBitmap);
hOldTargetBitmap := SelectObject(hTargetDC, hTargetBitmap);
try
if (hOldSourceBitmap <> 0) and (hOldTargetBitmap <> 0) then
begin
// Устанавливаем таблицу цветов для DIBSections
if lpSrcDIB.bmiHeader.biBitCount <= 8 then
SetDIBColorTable(hSourceDC, 0, 1 shl lpSrcDIB.bmiHeader.biBitCount, lpSrcDIB.bmiColors);
if lpbmi^.bmiHeader.biBitCount <= 8 then
SetDIBColorTable(hTargetDC, 0, 1 shl
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)
else if 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);
GDIFlush;
GetMem(result, Integer(dwTargetHeaderSize + dwTargetBitsSize));
Move(lpbmi^, result^, dwTargetHeaderSize);
Move(lpTargetBits^, FindDIBBits(result^)^, dwTargetBitsSize)
end
finally
if hOldSourceBitmap <> 0 then SelectObject(hSourceDC, hOldSourceBitmap);
if hOldTargetBitmap <> 0 then SelectObject(hTargetDC, hOldTargetBitmap);
end
end
finally
if hSourceDC <> 0 then DeleteDC(hSourceDC);
if hTargetDC <> 0 then
DeleteDC(hTargetDC)
end
end;
finally
if hTargetBitmap <> 0 then DeleteObject(hTargetBitmap);
if hSourceBitmap <> 0 then DeleteObject(hSourceBitmap);
if dc <> 0 then
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 <> nil then
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;
lpii.lpXOR := FindDIBBits(PBitmapInfo(lpii.lpbi)^);
Move(FindDIBBits(lpNewDIB^)^, lpii.lpXOR^, lpii.Height * BytesPerLine
(lpNewDIB^.bmiHeader));
lpii.lpAND := lpii.lpXOR + lpii.Height * BytesPerLine
(lpNewDIB^.bmiHeader);
Fillchar(lpii.lpAnd^, lpii.Height * WIDTHBYTES(lpii.Width), $00);
result := True
finally
FreeMem(lpNewDIB)
end
end;
function TForm1.StringToIcon(const st: string): HIcon;
var
memDC: HDC;
bmp: HBITMAP;
oldObj: HGDIOBJ;
rect: TRect;
size: TSize;
infoHeaderSize: DWORD;
imageSize: DWORD;
infoHeader: PBitmapInfo;
icon: IconImage;
oldFont: HFONT;
begin
result := 0;
memDC := CreateCompatibleDC(0);
if memDC <> 0 then
try
bmp := CreateCompatibleBitmap(Canvas.Handle, 16, 16);
if bmp <> 0 then
try
oldObj := SelectObject(memDC, bmp);
if oldObj <> 0 then
try
rect.Left := 0;
rect.top := 0;
rect.Right := 16;
rect.Bottom := 16;
SetTextColor(memDC, RGB(255, 0, 0));
SetBkColor(memDC, RGB(128, 128, 128));
oldFont := SelectObject(memDC, font.Handle);
GetTextExtentPoint32(memDC, PChar(st), Length(st), size);
ExtTextOut(memDC, (rect.Right - size.cx) div 2, (rect.Bottom - size.cy) div 2, ETO_OPAQUE, @rect, PChar(st), Length(st), nil);
SelectObject(memDC, oldFont);
GDIFlush;
GetDibSizes(bmp, infoHeaderSize, imageSize);
GetMem(infoHeader, infoHeaderSize + ImageSize);
try
GetDib(bmp, SystemPalette16, infoHeader^, PChar(DWORD(infoHeader) + infoHeaderSize)^);
icon.Colors := 4;
icon.Width := 32;
icon.Height := 32;
icon.lpBits := nil;
if DibToIconImage(icon, infoHeader^, True) then
try
result := CreateIconFromResource(PByte(icon.lpBits), icon.dwNumBytes, True, $00030000);
finally
FreeMem(icon.lpBits)
end
finally
FreeMem(infoHeader)
end
finally
SelectObject(memDC, oldOBJ)
end
finally
DeleteObject(bmp)
end
finally
DeleteDC(memDC)
end
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Application.Icon.Handle := StringToIcon('0');
Timer1.Enabled := True;
Button1.Enabled := False;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
const i: Integer = 0;
begin
Inc(i);
if i = 100 then i := 1;
Application.Icon.Handle := StringToIcon(IntToStr(i));
end;
end.
Взято с Исходников.ru