• <label id="pxtpz"><meter id="pxtpz"></meter></label>
      1. <span id="pxtpz"><optgroup id="pxtpz"></optgroup></span>

        當前位置:雨林木風下載站 > 技術開發教程 > 詳細頁面

        淺析桌面精靈的完成

        淺析桌面精靈的完成

        更新時間:2022-05-13 文章作者:未知 信息來源:網絡 閱讀次數:

        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)

        溫馨提示:喜歡本站的話,請收藏一下本站!

        本類教程下載

        系統下載排行

        主站蜘蛛池模板: 特级毛片A级毛片免费播放| 久久水蜜桃亚洲av无码精品麻豆 | 日韩在线永久免费播放| 亚洲无码视频在线| jizz18免费视频| 亚洲宅男天堂在线观看无病毒| 手机永久免费的AV在线电影网| 亚洲欧洲久久av| 中文永久免费观看网站| 久久精品国产精品亚洲精品| 免费看成人AA片无码视频吃奶| 久久久无码精品亚洲日韩蜜桃| 国产亚洲精品自在线观看| 一级日本高清视频免费观看| 久久久青草青青国产亚洲免观 | 一级一级毛片免费播放| 亚洲综合色视频在线观看| 久久久久久av无码免费看大片| 一本色道久久综合亚洲精品高清| 黄视频在线观看免费| 亚洲国产成人久久精品影视| 亚洲AV性色在线观看| 国产一区二区视频免费| 国产裸体美女永久免费无遮挡| 亚洲AV无一区二区三区久久| 特级aaaaaaaaa毛片免费视频| 国产偷国产偷亚洲高清日韩| 九九美女网站免费| 亚洲精品一二三区| 成人无码区免费A片视频WWW| 国产成人亚洲综合一区| 国产午夜亚洲精品国产成人小说| 久久久国产精品福利免费| 亚洲精品成人网站在线播放| 最新中文字幕免费视频| 亚洲一区二区三区免费观看| 国产一级高清免费观看| 免费视频精品一区二区三区| 亚洲一区二区三区在线网站| 亚洲国产精品无码久久久久久曰 | 亚洲网址在线观看你懂的|