时间: 2021-07-31 作者:daque
1. 软硬件的开拓手段想必大师对桌面精灵很熟习吧,想不想本人编一个?笔者特殊想编一个,其手段果然是为了博得美眉的爱好,由此引出了我开拓本软硬件的手段。即使读者群有我同样的需要,那么请连接看下来,我将和你共通商量这个题目。提防以次示例代码均用delphi刻画。2. 实行道理本来桌面精灵的道理很大略,重要分以次几步:1.获得桌面窗口的hdc。 api 设置如次: getdc因变量用来获得指定窗口的图形摆设刻画表 hdc getdc( hwnd hwnd // 窗口句柄 ); 比方: desktopdc:hdc;//设置桌面窗口的图形摆设刻画表句柄 desktopdc:=getdc(0); 大概desktopdc:=getdc(getdesktopwindow());2.创造一个外存位图,把桌面中将要画图的地区,生存到外存位图中去,再不画图实行时回复桌面。为此我设置了一个因变量: procedure savebackground(bkcanvas :tcanvas;//外存位图的画布东西 sp_w:integer;//要生存地区的宽窄 sp_h :integer ;//要生存地区的莫大 nx:integer;//要生存地区的x坐标 ny:integer);//要生存地区的y坐标3.将动画东西通明地正片到桌面包车型的士画图地区,笔者用了一个gdiapi因变量简单地实行了此功效。 设置如次: bool transparentblt(hdc hdcdest,//目的图形摆设刻画表句柄 int nxorigindest,//画图矩形的x坐标 int nyorigindest,//画图矩形的y坐标 int nwidthdest,//画图矩形的宽窄 int hheightdest,//画图矩形的莫大 hdc hdcsrc,//源图形摆设刻画表句柄 int nxoriginsrc,//源画图矩形的x坐标 int nyoriginsrc,//源画图矩形的y坐标 int nwidthsrc,//源画图矩形的宽窄 int nheightsrc,//源画图矩形的莫大 uint crtransparent//树立通明色rgb(r,g,b) ); 提防: windows nt: 须要5.0或之上本子 windows: 须要 windows 98 或 之上本子 其它低本子不扶助。 此因变量包括在msimg32.dll. 笔者设置了一个tranbit因变量来动静挪用transparentblt因变量,简直设置见第三节。4.将第二步天生的外存位图正片到桌面。如许一帧动画就表露实行。连接轮回1-4步,你就能看到贯串的动画场景了。3.简直代码以次是一个演练步调,在delphi5.0+windows2000p中调节和测试经过。创造一个窗体form1,放上两个image控件,定名为image1,image2,再放上一个timer控件,定名为timer1。筹备两张位图,一张放入image1,另一张放入image2。笔者用了如次款式的位图(截取了一局部),你不妨本人画动画东西,也不妨滥用旁人的,笔者即是用微软画的图片。从图片你不妨看出,图片中囊括了很多贯串的动画帧,一张图片实行一个举措,如回旋一周等,每帧动画巨细实足一律,除去动画东西其它像素用一种通明色弥补。好了你不妨看简直的代码了。unit unitmain;interfaceuses windows, messages, sysutils, classes, graphics, controls, forms, dialogs, extctrls, stdctrls,mmsystem;type tform1 = class(tform) timer1: ttimer;//爆裂准时器 image1: timage;//积聚爆裂的图片 image2: timage;//积聚遨游器的图片 procedure timer1timer(sender: tobject); procedure formcreate(sender: tobject); procedure formclose(sender: tobject; var action: tcloseaction); private { private declarations } desktopdc:hdc;//桌面窗口的图形摆设刻画表句柄 stop:boolean;//遏制轮回的变量 expnum:integer;//爆裂的暂时度数 procedure explode(x:integer;y:integer);//爆裂因变量 procedure shipmove(x:integer;y:integer);//遨游器因变量 public { public declarations } end;var form1: tform1;implementation{$r *.dfm}//生存桌面后台procedure savebackground(bkcanvas :tcanvas; sp_w:integer; sp_h :integer ; nx:integer; ny:integer);var sc:tcanvas;begin sc:=tcanvas.create; try sc.handle:=getdc(0); bkcanvas.copyrect( rect(0,0,sp_w, sp_h), sc,rect(nx, ny, nx+sp_w, ny+sp_h)); releasedc(0, sc.handle); finally sc.free; end;end;//通明正片图像因变量//静态挪用api因变量transparentbltprocedure tranbit(hdcdest:hdc; nxorigindest:integer; nyorigindest:integer; nwidthdest:integer; hheightdest:integer; hdcsrc:hdc; nxoriginsrc:integer; nyoriginsrc:integer; nwidthsrc:integer; nheightsrc:integer; crtransparent:uint) ;var libhandle:hwnd;//动静贯穿库句柄 //因变量原形设置 dllname:procedure(hdcdest:hdc; nxorigindest:integer; nyorigindest:integer; nwidthdest:integer; hheightdest:integer; hdcsrc:hdc; nxoriginsrc:integer; nyoriginsrc:integer; nwidthsrc:integer; nheightsrc:integer; crtransparent:uint);stdcall;begin //以次是静态挪用dll中因变量的官样文章 libhandle:=loadlibrary('msimg32.dll'); if libhandle<32 then begin messagebox(form1.handle,'not found msimg32.dll','error',0); exit; end; @dllname:=getprocaddress(libhandle,'transparentblt'); if @dllname=nil then begin messagebox(form1.handle,'not found transparentblt in msimg32.dll','error',0); freelibrary(libhandle); exit; end; try transparentblt(hdcdest, nxorigindest, nyorigindest, nwidthdest, hheightdest, hdcsrc, nxoriginsrc, nyoriginsrc, nwidthsrc, nheightsrc, crtransparent); finally freelibrary(libhandle); end;end;//爆裂因变量//在桌面包车型的士x,y坐标处爆发爆裂procedure tform1.explode(x:integer;y:integer);var bitmapb : tbitmap;//生存桌面指定地区的外存位图 w:integer;//一帧动画的宽窄 h:integer;//一帧动画的莫大 i:integer; j:integer;begin bitmapb:=tbitmap.create; try //动画位图为4*5=20帧 w:=image1.width div 4;//计划每帧的宽窄 h:=image1.height div 5;//计划每帧的莫大 //初始化外存为图的巨细 bitmapb.height :=h; bitmapb.width :=w; //生存桌面上指定地区的位图 //提防,因为爆裂是在同一场所实行的,以是只有生存爆裂地区一次就行了。 savebackground(bitmapb.canvas,w,h,x,y); for i:=0 to 4 do begin for j:=0 to 3 do begin //把相映帧画到桌面上 tranbit(desktopdc ,x,y,w,h, image1.canvas.handle,j*w,i*h,w,h,rgb(208,2,178)); sleep(20);//表露速率太快,中断20毫秒 //回复桌面 bitblt(desktopdc,x,y,w,h,bitmapb.canvas.handle,0,0,srccopy); end; end; finally bitmapb.free; end;end;//遨游器的遨游因变量//参数x,y指定遨游器遨游的手段地procedure tform1.shipmove(x:integer;y:integer);var w:integer; h:integer; i:integer; j:integer; k:integer; l:integer; bitmapb : tbitmap;begin randomize(); bitmapb:=tbitmap.create; try //动画位图为4*16-3帧空帧=61帧 w:=image2.width div 4; h:=image2.height div 16; bitmapb.height :=h; bitmapb.width :=w; k:=0; l:=0; while not stop do for i:=0 to 15 do for j:=0 to 3 do begin if (i=15) and (i>0) then break;//即使是空帧就不画了 //生存桌面上指定地区的位图 //提防,因为遨游是在各别场所实行的,以是要生存行将被画图的桌面地区 savebackground(bitmapb.canvas,w,h,k,l); tranbit(desktopdc ,k,l,w,h,image2.canvas.handle,j*w,i*h,w,h,rgb(208,2,178)); sleep(10); bitblt(desktopdc,k,l,w,h,bitmapb.canvas.handle,0,0,srccopy); if(k<x)then k:=k+1; if(l<y)then l:=l+1; if timer1.enabled =false then if(k>x-10)then//达到手段地就遏止遨游,并引爆空包弹 begin stop:=true; timer1.enabled :=true;//空包弹引爆器 end; end; finally bitmapb.free; end;end;procedure tform1.timer1timer(sender: tobject);var x,y:integer;begin if(expnum = 0) then begin explode(screen.width div 2-20,screen.height div 2-20); sndplaysound('explosion.wav',snd_nostop); expnum:=expnum+1; end else if expnum<10 then//爆裂最多10次 begin //爆发随机场所 x:=random(screen.width-100); y:=random(screen.height-100); explode(x,y);//爆裂 sndplaysound('explosion.wav',snd_nostop);//播放爆裂声响 expnum:=expnum+1; end else begin stop:=true; timer1.enabled :=false; close(); end;end;procedure tform1.formcreate(sender: tobject);begin desktopdc:=getdc(0); chdir(extractfilepath(application.exename)); stop:=false; expnum:=0; //遨游器发端遨游,手段地为屏幕中心 self.shipmove(screen.width div 2,screen.height div 2);end;procedure tform1.formclose(sender: tobject; var action: tcloseaction);begin stop:=true; timer1.enabled :=false; releasedc(0, desktopdc);end;end.4.中断语正如咱们所蓄意的那么:一个遨游器飞入桌面,渐渐向屏幕中心邻近,当它达到手段地时就爆裂了,并引出延续串的爆裂。步调成功地实行了咱们的蓄意,然而步调再有很多不及,最佳用directx来实行动画,如许功效大概会更好。如谁对其感爱好的话,发e_mail给我,咱们一道商量。(e_mail:codehunter@sohu.com)