DELPHI FAQ: Отображаем текст в System Tray.


Отображаем текст в System Tray.
Previous  Home  Next


Автор: 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..255of 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, 0256, 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 <> 0and (GetPaletteEntries(hPal, 016, pe) <> 0then
            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 5shl 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 <> 0and (hTargetBitmap <> 0and (hSourceBitmap <> 0then
            begin

              hSourceDC := CreateCompatibleDC(DC);
              hTargetDC := CreateCompatibleDC(DC);
              try

                if
 (hSourceDC <> 0and (hTargetDC <> 0then
                  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 <> 0and (hOldTargetBitmap <> 0then
                        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, 00, 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, 00, 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
00));
        SetBkColor(memDC, RGB(128
128128));
        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 http://www.sources.ru





DELPHI FAQ




EOMY TOP 100      Рейтинг@Mail.ru      Rambler's Top100