<form id="hz9zz"></form>
  • <form id="hz9zz"></form>

      <nobr id="hz9zz"></nobr>

      <form id="hz9zz"></form>

    1. 明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

      淺析桌面精靈的完成

      [摘要]1. 軟件的開發目的想必大家對桌面精靈很熟悉吧,想不想自己編一個?筆者非常想編一個,其目的居然是為了取得美眉的喜歡,由此引出了我開發本軟件的目的。如果讀者有我同樣的需求,那么請繼續看下去,我將...
      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;



      interface



      uses



        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函數TransparentBlt



      procedure 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)


      日韩精品一区二区三区高清