Draw Image On Desktop with GDI Plus (D5)

Delphi 下的编程。需要IGDIPlus.pas 文件。部分自己编写,大部分来源于网络。

 


unit
Unit2; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, IGDIPlus, ExtCtrls, Menus, StdCtrls, ComCtrls,math; const//定义常量 WS_EX_LAYERED = $80000; AC_SRC_OVER = $0; AC_SRC_ALPHA = $1; ULW_ALPHA = $2; Nums=15; MoveX=10; MoveY=10; D=180; //图片大小 vk_key=27; //key Esc iIntval= 10; const ColorMatrix: TGPColorMatrix = ( //R G B A V (1.0, 0.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.3, 0.0), (0.0, 0.0, 0.0, 0.0, 1.0) ); type TForm1 = class(TForm) timer1: TTimer; Label1: TLabel; procedure FormCreate(Sender: TObject); procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure Timer1Timer(Sender: TObject); procedure MouseLeave(var Msg: TMessage);message WM_MOUSELEAVE; procedure FormClose(Sender: TObject; var Action: TCloseAction); private m_Kind: Integer; //当前第几行字符串 m_bBack: Boolean; //是否显示背景 hotkeyid :integer; //记录热键标识 Attr:IGPImageAttributes; Colors :Array[1..Nums,0..3] of single; bxx,byy,Addx,Addy :Array[1..Nums] of Integer; jishu,ssj:Word; function UpdateDisplay(bBack: Boolean = False;Transparent: Integer = 100):Boolean; procedure checkCollision(bub0, bub1:Word); procedure WMhotkeyhandle(var msg:Tmessage);message wm_hotkey; public { Public declarations } imgs :TGPImage; end; function UpdateLayeredWindow(Handle: THandle; hdcDest: HDC; pptDst: PPoint; _psize: PSize; hdcSrc: HDC; pptSrc: PPoint; crKey: COLORREF; pblend: PBLENDFUNCTION; dwFlags: DWORD): Boolean; stdcall; var Form1: TForm1; implementation function UpdateLayeredWindow; external 'user32.dll' name 'UpdateLayeredWindow'; {$R *.dfm} {------------------------------------------------------------------------------- 过程名: TForm1.UpdateDisplay 功能: 绘制桌面歌词 参数: pszbuf: WideString; 绘制的字符串 bBack: Boolean; 是否绘制背景 Transparent: Integer 透明程度 返回值: Boolean -------------------------------------------------------------------------------} function TForm1.UpdateDisplay(bBack: Boolean;Transparent: Integer):Boolean; var hdcTemp,hdcScreen,m_hdcMemory: HDC; hBitMap: Windows.HBITMAP; blend: BLENDFUNCTION; //这种结构的混合控制通过指定源和目标位图的混合功能 rct: TRect; ptWinPos,ptSrc: TPoint; graphics: IGPGraphics; //封装一个 GDI+ 绘图图面 image1: TGPImage; //使用这个类来创建和操作GDI+图像 i:Word; sizeWindow: SIZE; Iw,Ih:Word; //img :array[1..Nums] of TGPImage; //ColorMatrix: TGPColorMatrix; begin //---------------------开始:初始化操作-------------------------------------- hdcTemp := GetDC(Self.Handle); m_hdcMemory := CreateCompatibleDC(hdcTemp); hBitMap := CreateCompatibleBitmap(hdcTemp,Form1.Width,Form1.Height); SelectObject(m_hdcMemory,hBitMap); if (Transparent < 0) or (Transparent > 100) then Transparent := 100; with blend do begin BlendOp := AC_SRC_OVER; //把源图片覆盖到目标之上 BlendFlags := 0; AlphaFormat := AC_SRC_ALPHA;//每个像素有各自的alpha通道 SourceConstantAlpha :=Trunc(Transparent * 2.55); //源图片的透明度 end; hdcScreen := GetDC(Self.Handle); GetWindowRect(Self.Handle,rct); ptWinPos := Point(rct.Left,rct.Top); graphics := TGPGraphics.Create(m_hdcMemory); //image:=TGPImage.Create(ExtractFilePath(Application.Exename)+'popobluesmall.png'); Iw:=imgs.GetWidth(); Ih:=imgs.GetHeight(); For i:=1 to Nums do begin //attr.SetToIdentity(); // img[i]:=TGPImage.Create(ExtractFilePath(Application.Exename)+'popobluesmall.png');{测试文件要存在} //img[i]:=imgs.Clone(); image1:=imgs.Clone(); if Random(20)<3 then begin Colors[i,0]:= Random(20)/10-1; Colors[i,1]:= Random(20)/10-1; Colors[i,2]:= Random(20)/10-1; end; ColorMatrix[4, 0] :=Colors[i,0]; ColorMatrix[4, 1] :=Colors[i,1]; ColorMatrix[4, 2] :=Colors[i,2]; ColorMatrix[3, 3] :=Colors[i,3];//透明度 0-1 Attr.SetColorMatrix(ColorMatrix); //Attr.Reset(); Graphics.DrawImage(image1,MakeRect(Bxx[i],Byy[i],Iw,Ih),0,0,Iw,Ih,UnitPixel,attr); //Graphics.DrawImage(img[i],MakeRect(Bxx[i],Byy[i],Iw,Ih),0,0,Iw ,Ih,UnitPixel,attr); end; sizeWindow.cx := Form1.Width ; sizeWindow.cy := Form1.Height; ptSrc := Point(0,0); //---------------------开始:更新一个分层的窗口的位置,大小,形状,内容和半透明度--- Result := UpdateLayeredWindow(Self.Handle, //分层窗口的句柄 hdcScreen, //屏幕的DC句柄 @ptWinPos, //分层窗口新的屏幕坐标 @sizeWindow, //分层窗口新的大小 m_hdcMemory, //用来定义分层窗口的表面DC句柄 @ptSrc, //分层窗口在设备上下文的位置 $00008B, //合成分层窗口时使用指定颜色键值 @blend, //在分层窗口进行组合时的透明度值 ULW_ALPHA); //使用pblend为混合功能 //---------------------开始:释放和删除-------------------------------------- ReleaseDC(Self.Handle,hdcScreen); ReleaseDC(Self.Handle,hdcTemp); DeleteObject(hBitMap); DeleteDC(m_hdcMemory); end; {------------------------------------------------------------------------------- 功能: 窗体创建初始化 -------------------------------------------------------------------------------} procedure TForm1.FormCreate(Sender: TObject); var i :Word; begin hotkeyid:=GlobalAddAtom(pchar('UserDefineHotKey'))-$C000; //注册ctrl+alt+key registerhotkey(handle,hotkeyid,0,vk_key); //MOD_CONTROL or mod_Shift Attr:= TGPImageAttributes.Create; randomize; imgs:=TGPImage.Create(ExtractFilePath(Application.Exename)+'popobluesmall.png');{测试文件要存在} For i:=1 to Nums do begin Bxx[i]:=0; Byy[i]:=0; Addx[i]:=0; Addy[i]:=0; Colors[i,0]:=Random(20)/10-1; Colors[i,1]:=Random(20)/10-1; Colors[i,2]:=Random(20)/10-1; Colors[i,3]:=0; end; Addx[1]:=MoveX; Addy[1]:=MoveY; Colors[1,3]:=1; jishu:=0; ssj:=1; Form1.Left:=0; Form1.Top:=0; Form1.Resize; Label1.Caption:=inttostr(Form1.width)+' '+inttostr(Form1.height); //设置窗体属性 SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle,GWL_EXSTYLE) or WS_EX_TOOLWINDOW); //不在任务栏出现 SetWindowLong(Self.Handle, GWL_EXSTYLE, GetWindowLong(Self.Handle,GWL_EXSTYLE) or WS_EX_LAYERED //层次窗口 or WS_EX_TOOLWINDOW); //不在alt+tab中出现 //初始化变量等等 m_kind := 0; m_bBack := False; Self.Cursor := crHandPoint; SetWindowPos(Self.Handle,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE or SWP_NOMOVE); //窗口置顶 SetWindowLong(Self.Handle,GWL_EXSTYLE,GetWindowLong(Self.Handle,GWL_EXSTYLE) or WS_EX_TRANSPARENT);//穿透 UpdateDisplay(m_bBack); end; {------------------------------------------------------------------------------- 功能: 鼠标按下移动窗体 -------------------------------------------------------------------------------} procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin ReleaseCapture; SendMessage(Self.Handle,WM_SYSCOMMAND,SC_MOVE or HTCAPTION,0); end; {------------------------------------------------------------------------------- 功能: 鼠标移过窗体 -------------------------------------------------------------------------------} procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var xh: TTrackMouseEvent; begin m_bBack := True; UpdateDisplay(m_bBack); with xh do begin cbSize := SizeOf(xh); dwFlags := TME_LEAVE; hwndTrack := Self.Handle; dwHoverTime := 0; end; TrackMouseEvent(xh); end; {------------------------------------------------------------------------------- 功能: 鼠标移出窗体时,去掉背景 -------------------------------------------------------------------------------} procedure TForm1.MouseLeave(var Msg: TMessage); begin m_bBack := False; UpdateDisplay(m_bBack); Msg.Result := 0; end; {------------------------------------------------------------------------------- 功能: 定时器切换字符串 -------------------------------------------------------------------------------} procedure TForm1.timer1Timer(Sender: TObject); var i,j:Word; begin if ssj<Nums then begin Inc(jishu); if jishu>=10 then begin jishu:= 0;Inc(ssj);Addx[ssj]:=MoveX;Addy[ssj]:=MoveY;Colors[ssj,3]:=1;end end; // UpdateDisplay(m_pszbuf[m_kind],m_bBack);} For i:=1 to Nums do begin Addx[i]:=Round(Addx[i]*(1-0.3/50/iIntval)); Addy[i]:=Round(Addy[i]*(1-0.3/50/iIntval)); if Bxx[i]<0 then begin Bxx[i]:=0; Addx[i]:= -Addx[i]; end else if Bxx[i] >Form1.Width-D then begin Bxx[i]:=Form1.Width-D; Addx[i]:= -Addx[i]; end; if Byy[i] < 0 Then begin Byy[i]:=0; Addy[i]:=-Addy[i]; end else if Byy[i] > Form1.Height-D then begin Byy[i]:=Form1.Height-D; Addy[i]:=-Addy[i]; end; Bxx[i]:=Bxx[i]+Addx[i]; Byy[i]:=Byy[i]+Addy[i]; end; if ssj>=Nums then for i:=1 to Nums-1 do For j:=i+1 to Nums do checkCollision(i,j); UpdateDisplay(m_bBack); //Sleep(50); Application.ProcessMessages; //end; end; {------------------------------------------------------------------------------- 功能: 退出 -------------------------------------------------------------------------------} procedure TForm1.checkCollision(bub0, bub1:Word); Var dx,dy,Dist,px1,px2,py1,py2,dx2,dy2,d2:Integer; begin dx:=Abs(Bxx[bub1]-Bxx[bub0]); dy:=Abs(Byy[bub1]-Byy[bub0]); dist:=Trunc(SQRT(dx*dx+dy*dy)); if dist = 0 then dist:= 1; D2:=D-Dist; if(d2>=0 ) then begin // p的速度的交换分 py1:=trunc((dy* dy) *Addy[bub1]/dist / dist +(dy * dx)*Addx[Bub1]/dist /dist); px1:=trunc((dx* dx) *Addx[Bub1]/dist / dist +(dx * dy)*Addy[Bub1]/dist /dist); // this的速度的交换分量 py2:=trunc((dy* dy) *Addy[Bub0]/dist /dist +(dy * dx)*Addx[Bub0]/dist /dist); px2:=trunc((dx* dx) *Addx[Bub0]/dist /dist +(dx * dy)*Addy[Bub0]/dist /dist); Addx[Bub0]:=Addx[Bub0]+px1-px2; Addy[Bub0]:=Addy[Bub0]+py1-py2; Addx[Bub1]:=Addx[Bub1]-px1+px2; Addy[Bub1]:=Addy[Bub0]-py1+py2; end; if (d2>0) then begin //移动第二个圆到延长线上去。 dx2:=Trunc(D2 * (Bxx[Bub1] -Bxx[Bub0]) / Dist); dy2:=Trunc(D2 * (Byy[Bub1] -Byy[Bub0]) / Dist); Bxx[Bub1]:=Bxx[Bub1]+dx2; Byy[Bub1]:=Byy[Bub1]+dy2; //this._pCenter.X -= (float)(dx2 / 2.0); //this._pCenter.Y -= (float)(dy2 / 2.0); end; end; procedure TForm1.Wmhotkeyhandle(var msg:Tmessage); begin //判断是否是ctrl+Shift+Vk_key if (msg.LParamHi=vk_key)then //and //(msg.lparamLo=MOD_CONTROL or mod_Shift) then begin Form1.Close; end; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin UnregisterHotKey(Handle,HotKeyId); //注销HotKey,释放资源 end; end.

 

posted @ 2022-11-27 16:46  PBlover  阅读(55)  评论(0编辑  收藏  举报