阅读背景:

DIY Delphi 半透明窗体 (1)

来源:互联网 

写这篇文章的时候脑子有点乱.. 


unit xDrawForm;

interface
  uses Windows, Messages, SysUtils, Classes, Controls, Forms, Menus,
  Graphics,GDIPOBJ,GDIPAPI,GDIPUTIL;


type

  TwwGDIImage = class
  public
    n_Pos_X : Integer;
    n_Pos_Y : Integer;
    n_Width : Integer;
    n_Height : Integer;
    GPImageNormal : TGPImage;

    procedure CreateImageNormal(wsFileName: WideString;nPosX,nPosY,nW,nH:Integer);
  end;

  TwwGDIButton = class(TwwGDIImage)
  public
    GPImageHot : TGPImage;
    GPImageDown : TGPImage;
  end;


  TwwCanvas = class(TObject)
  private
    m_hdcMemory: HDC;
    hdcScreen: HDC;
    hBMP: HBITMAP;
    m_Blend: BLENDFUNCTION;
    // 事件
    FGPGraph: TGPGraphics;
    FOnDrawImage: TNotifyEvent;

    procedure BeginDraw(); // 绘图前置工作
    procedure EndDraw(Handle:THandle);   // 绘图收尾工作
   public
    sizeWindow: SIZE;
    ptSrc: TPOINT;
    n_Handle : THandle;
    procedure RePaint(h:THandle);
    procedure InitCanvas(nx,ny:Integer);
    procedure wwDrawImage(wwGDIImage :TwwGDIImage);
    property GPGraph: TGPGraphics read FGPGraph write FGPGraph;
    property OnDrawImage: TNotifyEvent read FOnDrawImage write FOnDrawImage;
  end;


implementation

{ TwwCanvas }

procedure TwwCanvas.BeginDraw;
begin
  // 获取桌面屏幕设备
  hdcScreen := GetDC(0);
  // 创建一个与指定设备兼容的内存设备上下文环境(DC)
  m_hdcMemory := CreateCompatibleDC(hdcScreen);
  // 创建与指定的设备环境相关的设备兼容的位图
  hBMP := CreateCompatibleBitmap(hdcScreen, sizeWindow.cx, sizeWindow.cy );
  // 选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象
  SelectObject(m_hdcMemory, hBMP);
  // 创建画布
  GPGraph := TGPGraphics.Create(m_hdcMemory);
end;

procedure TwwCanvas.wwDrawImage(wwGDIImage: TwwGDIImage);
begin
  GPGraph.DrawImage(
  wwGDIImage.GPImageNormal,
  wwGDIImage.n_Pos_X,
  wwGDIImage.n_Pos_Y,
  wwGDIImage.n_Width,
  wwGDIImage.n_Height)
end;

procedure TwwCanvas.EndDraw(Handle:THandle);
begin
  //  设置窗体风格
  SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
  //  执行透明混合
  UpdateLayeredWindow(Handle, hdcScreen, nil,@sizeWindow, m_hdcMemory, @ptSrc, 0, @m_Blend, ULW_ALPHA);
  //  设置窗体位置
  SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);

  // 各种释放就对了.. 不然画起来会糊
  GPGraph.ReleaseHDC(m_hdcMemory);
  ReleaseDC(0, hdcScreen);
  hdcScreen := 0;
  DeleteObject(hBMP);
  DeleteDC(m_hdcMemory);
  m_hdcMemory := 0;
  GPGraph.Free;
end;

procedure TwwCanvas.RePaint(h:THandle);
begin
  if Assigned(FOnDrawImage) then
  begin
    BeginDraw();
    FOnDrawImage(Self);
    EndDraw(h);
  end;
end;

procedure TwwCanvas.InitCanvas(nx, ny: Integer);
begin
  m_Blend.BlendOp := AC_SRC_OVER; //   the   only   BlendOp   defined   in   Windows   2000
  m_Blend.BlendFlags := 0; //   Must   be   zero
  m_Blend.AlphaFormat := AC_SRC_ALPHA; //This   flag   is   set   when   the   bitmap   has   an   Alpha   channel
  m_Blend.SourceConstantAlpha := 255;

  sizeWindow.cx := nx;
  sizeWindow.cy := ny;
  ptSrc := Point(0,0);
end;

{ TwwGDIImage }

procedure TwwGDIImage.CreateImageNormal(wsFileName: WideString;nPosX,nPosY,nW,nH:Integer);
begin
  Self.GPImageNormal := TGPImage.Create(wsFileName);
  Self.n_Pos_X := nPosX;
  Self.n_Pos_Y := nPosY;
  Self.n_Width := nW;
  Self.n_Height:= nH;
end;

end.
unit xDrawForm;

inter



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: