⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unitexicon.pas

📁 灰鸽子VIP1.2经典源代码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  try
                                         // Get a bitmap with the required format
    src := CreateMappedBitmap (source, Palette, PixelFormat, Width, height);

    maskBmp.Assign (source);             // Get mask bitmap - White where the transparent color
                                         // occurs - otherwise black.

    if source is TBitmap then
      maskBmp.Mask (TBitmap (source).transparentColor)
    else
      if Source is TExIconCursor then
        maskBmp.Mask (TExIconCursor(source).transparentColor)
      else
        maskBmp.Mask (clBlack);

                                      // Get size for mask bits buffer
    maskImageSize := BytesPerScanLine (Width, 1, 32) * Height;

                                      // Get size for color bits buffer
    InternalGetDibSizes (src.Handle, infoHeaderSize, imageSize, PixelFormat);

                                      // Create a memory stream to assemble the icon image
    image := TExIconImage.Create;
    try
      image.Reference;
      image.FMemoryImage := TMemoryStream.Create;
      image.FIsIcon := Self is TExIcon;

      if image.FIsIcon then
        offset := 0
      else
        offset := sizeof (DWORD);

      image.FMemoryImage.Size := infoHeaderSize + imageSize + maskImageSize + offset;

      info := PBitmapInfo (PChar (image.FMemoryImage.Memory) + offset);
      colorBits := PChar (info) + infoHeaderSize;
      maskBits := colorBits + imageSize;

      InternalGetDib (src.Handle, Palette, info, colorBits^, PixelFormat);
                                       // Get the bitmap header, palette & bits


      maskInfo := nil;
      dc := CreateCompatibleDC (0);
      try
        GetMem (maskInfo, SizeOf (TBitmapInfoHeader) + 2 * SizeOf (RGBQUAD));
                                      // Get mask bits

        with maskInfo^.bmiHeader do  // Set the 1st six members of info header, according
        begin                        // to the docs.

          biSize := SizeOf (TBitmapInfoHeader);
          biWidth := Width;
          biHeight := Height;
          biBitCount := 1;
          biPlanes := 1;
          biCompression := BI_RGB;
        end;

        if GetDIBits (dc, maskBmp.Handle, 0, Height, maskBits, maskInfo^, DIB_RGB_COLORS) = 0 then
          RaiseLastOSError;
      finally
        DeleteDC (dc);
        FreeMem (maskInfo)
      end;

      MaskBitmapBits (colorBits, PixelFormat, maskBits, Width, Height, Palette);

      image.FWidth := info^.bmiHeader.biWidth;
      image.FHeight := info^.bmiHeader.biHeight;

      info^.bmiHeader.biHeight := info^.bmiHeader.biHeight * 2;
                                        // Adjust height for funky icon Height thing.

      image.FPixelFormat := src.PixelFormat;

      image.FGotPalette := False;  // ie.  we need to get it later if required.

      if Self is TExCursor then
        PDWORD (image.FMemoryImage.Memory)^ := TExCursor (Self).HotSpot;

      Images [fCurrentImage].Release;
      fImages [fCurrentImage] := Image;
      Changed (self);
    except
      image.Free;
      raise
    end;
  finally
    maskBmp.Free;
    src.Free
  end
end;

(*----------------------------------------------------------------------------*
 | procedure TExIconCursor.AssignTo                                           |
 |                                                                            |
 | Allow assigning to bitmap                                                  |
 *----------------------------------------------------------------------------*)
procedure TExIconCursor.AssignTo(dest: TPersistent);
var
  bmp : TBitmap;
begin
  if dest is TBitmap then
  begin
    bmp := TBitmap (dest);
    bmp.Assign (nil);           // You gotta do this, otherwise transparency goes nuts!
    bmp.PixelFormat := pf24Bit; // Always assign to 24-bit Bitmap so we don't lose colors

    bmp.Width := Width;
    bmp.Height := Height;

    bmp.Transparent := True;
    bmp.TransparentColor := TransparentColor;
    bmp.Canvas.Brush.Color := TransparentColor;
    bmp.Canvas.FillRect (RECT (0, 0, Width, Height));
    bmp.Canvas.Draw (0, 0, self);
  end
  else
    inherited AssignTo (dest)
end;

(*----------------------------------------------------------------------------*
 | constructor TExIconCursor.Create                                           |
 |                                                                            |
 | Constructor for TExICon                                                    |
 *----------------------------------------------------------------------------*)
constructor TExIconCursor.Create;
begin
  inherited Create;
  FTransparentColor := RGB ($fe, $e6, $f8);
  SetLength (FImages, 1);
  FImages [0] := TExIconImage.Create;
  FImages [0].FIsIcon := self is TExIcon;
  Images [0].Reference;
end;

(*----------------------------------------------------------------------------*
 | destructor TExIconCursor.Destroy                                           |
 |                                                                            |
 | destructor for TExIconCursor                                               |
 *----------------------------------------------------------------------------*)
destructor TExIconCursor.Destroy;
begin
  ReleaseImages;
  inherited Destroy
end;

(*----------------------------------------------------------------------------*
 | procedure TExIconCursor.Draw                                               |
 |                                                                            |
 | We should be able to do HandleNeeded/DrawIconEx, however we don't want to  |
 | call 'HandleNeeded' because of NT bugs, so jump through hoops to draw      |
 | direct from the memory image instead.                                      |
 *----------------------------------------------------------------------------*)
procedure TExIconCursor.Draw(ACanvas: TCanvas; const Rect: TRect);
var
  monoBmp, oldMonoBmp : HBITMAP;
  colorBmp, oldColorBmp : HBITMAP;
  colorDC, monoDC, dc : HDC;
  bitsOffset, bitsSize : DWORD;
  info : PBitmapInfo;
  hdr : PBitmapInfoHeader;
  monoInfo : PBitmapInfo;
  bits : PChar;

begin
  with fImages [fCurrentImage] do
    if Assigned (fMemoryImage) then
    begin
      info := GetBitmapInfo;
      hdr := @info^.bmiHeader;

      colorBmp := 0;
      monoBmp := 0;
      oldColorBmp := 0;
      oldMonoBmp := 0;
      monoDC := 0;
      colorDC := 0;
      monoInfo := Nil;

      dc := GDICheck (GetDC (0));
      try
        hdr^.biHeight := hdr^.biHeight div 2;  // Adjust memory image for funky Icon Height thing.

        GetBitmapInfoSizes (hdr^, bitsOffset, bitsSize, False);

                                                // Create Color Bitmap from Color bits & ColorTable
        colorBmp := GDICheck (CreateDIBitmap (dc, info^.bmiHeader, CBM_INIT, PChar (info) + bitsOffset, info^, DIB_RGB_COLORS));
        colorDC := GDICheck (CreateCompatibleDC (0));
        oldColorBmp := GDICheck (SelectObject(colorDC, colorBmp));

                                                // Create mono bitmap.  For some reason, CreateBitmap
                                                // creates it upside down if you give it the bits - so
                                                // you have to do CreateBitmap followed by SetDIBtes

        GetMem (monoInfo, sizeof (TBitmapInfoHeader) + 2 * sizeof (RGBQUAD));
        Move (hdr^, monoInfo^, sizeof (TBitmapInfoHeader));
        monoInfo^.bmiHeader.biBitCount := 1;
        monoInfo^.bmiHeader.biCompression := 0;
        with PRGBQUAD (PChar (monoInfo) + sizeof (TBitmapInfoHeader) + sizeof (RGBQUAD))^ do
        begin
          rgbRed := $ff;
          rgbGreen := $ff;
          rgbBlue := $ff;
          rgbReserved := 0;
        end;

        monoBmp := GDICheck (CreateBitmap (hdr^.biWidth, hdr^.biHeight, 1, 1, Nil));
        bits := PChar (info) + bitsOffset + bitsSize;
        monoDC := GDICheck (CreateCompatibleDC (0));
        GDICheck (SetDIBits (monoDC, monoBmp, 0, hdr^.biHeight, bits, monoInfo^, DIB_RGB_COLORS));
        oldMonoBmp := GDICheck (SelectObject(monoDC, monoBmp));

                                                // Draw the masked bitmap

        with rect do TransparentStretchBlt (ACanvas.Handle,
                               left, top, right - left, bottom - top,
                               colorDC, 0, 0,
                               hdr^.biWidth, hdr^.biHeight, monoDC, 0, 0);

      finally
        hdr^.biHeight := hdr^.biHeight * 2;

        if oldMonoBmp <> 0 then SelectObject (monoDC, oldMonoBmp);
        if monoDC <> 0 then DeleteDC (monoDC);

        if oldColorBmp <> 0 then SelectObject (colorDC, oldColorBmp);
        if colorDC <> 0 then DeleteDC (colorDC);

        if colorBmp <> 0 then DeleteObject (colorBmp);
        if monoBmp <> 0 then DeleteObject (monoBmp);
        ReleaseDC (0, dc);
        if monoInfo <> Nil then FreeMem (monoInfo)
      end
   end
    else
    begin

    // If you've fed an HICON in directly to the handle property you'll get here.
    // DrawIconEx seems to work - it's CreateIconFromresourceex that blows up...

      if Handle <> 0 then
        with rect do DrawIconEx (ACanvas.Handle, left, top, Handle, right - left, bottom - top, 0, 0, DI_NORMAL)
    end
end;

(*----------------------------------------------------------------------------*
 | function TExIconCursor.GetEmpty                                            |
 |                                                                            |
 | Returns true if the TExIconCursor's current image  has neither a handle or |
 | an image                                                                   |
 *----------------------------------------------------------------------------*)
function TExIconCursor.GetEmpty: Boolean;
begin
  with FImages [fCurrentImage] do
    Result := (FHandle = 0) and (FMemoryImage = nil);
end;

(*----------------------------------------------------------------------------*
 | function TExIconCursor.GetHandle                                           |
 |                                                                            |
 | Returns the current image's icon handle.  Calls HandleNeeded which may not |
 | be reliable under NT.                                                      |
 *----------------------------------------------------------------------------*)
function TExIconCursor.GetHandle: HICON;
begin
  HandleNeeded;
  result := Images [fCurrentImage].Handle
end;

(*----------------------------------------------------------------------------*
 | function TExIconCursor.GetHeight                                           |
 |                                                                            |
 | Returns the current image's height in pixels                               |
 *----------------------------------------------------------------------------*)
function TExIconCursor.GetHeight: Integer;
begin
  result := FImages [fCurrentImage].FHeight;
end;

(*----------------------------------------------------------------------------*
 | function TExIconCursor.GetImage                                            |
 |                                                                            |
 | Get the current image TExIconImage instance                                |
 *----------------------------------------------------------------------------*)
function TExIconCursor.GetImage(index: Integer): TExIconImage;
begin
  result := fImages [index]
end;

(*----------------------------------------------------------------------------*
 | function TExIconCursor.GetImageCount                                       |
 |                                                                            |
 | Get the nuber of images in the current icon or cursor                      |
 *----------------------------------------------------------------------------*)
function TExIconCursor.GetImageCount: Integer;
begin
  result := Length (fImages);
end;

(*----------------------------------------------------------------------------*
 | function TExIconCursor.GetPalette                                          |
 |                                                                            |
 | Get the palette handle for the current image                               |
 *----------------------------------------------------------------------------*)
function TExIconCursor.GetPalette: HPALETTE;
begin
  PaletteNeeded;
  result := FImages [fCurrentImage].fPalette;
end;

(*----------------------------------------------------------------------------*
 | function TExIconCursor.GetPixelFormat : TPixelFormat                       |
 |                                                                            |
 | Get the pixel format for the current image                                 |
 *----------------------------------------------------------------------------*)
function TExIconCursor.GetPixelFormat: TPixelFormat;
begin
  result := FImages [fCurrentImage].fPixelFormat
end;

(*----------------------------------------------------------------------------*
 | function TExIconCursor.GetTransparent : boolean                            |
 |                                                                            |
 | Overrides TGraphic method to always return TRUE                            |
 *----------------------------------------------------------------------------*)
function TExIconCursor.GetTransparent: boolean;
begin
  result := True
end;

(*----------------------------------------------------------------------------*
 | function TExIconCursor.GetWidth : Integer                                  |
 |                                                                            |
 | Returns the current image's width in pixels                                |
 *----------------------------------------------------------------------------*)
function TExIconCursor.GetWidth: Integer;
begin
  result := FImages [fCurrentImage].FWidth;
end;

(*----------------------------------------------------------------------------*
 | procedure TExIconCursor.HandleNeeded                                       |
 |                                                                            |
 | Ensure that an HICON handle exists for the current image.  Don't use this  |
 | unless strictly necessary.  It may bugger up in NT4                        |
 *----------------------------------------------------------------------------*)
procedure TExIconCursor.HandleNeeded;
begin
  FImages [FCurrentImage].HandleNeeded;
end;

(*----------------------------------------------------------------------------*
 | procedure TExIconCursor.ImageNeeded                                        |
 |                                                                            |
 | Ensure that a memory image exists for the current image.                   |
 *----------------------------------------------------------------------------*)
procedure TExIconCursor.ImageNeeded;
begin

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -