調用Windows的API函數製作桌面寵物 |
|
conundrum
尊榮會員 發表:893 回覆:1272 積分:643 註冊:2004-01-06 發送簡訊給我 |
調用Windows的API函數製作桌面寵物 http://www.ccw.com.cn/applic/prog/htm2003/20031113_10AST.asp 一、引言 相信大家都見過一些桌面上的小寵物,如Office中的小助手等,小寵物們活潑可愛,還可幫助主人完成一定的事件,為應用程式添色不少,那我們自己也能否製作出這樣的小寵物表單呢?答案是肯定的。說到底其實就是對表單顯示區域的操作,使得表單具有多種多樣的外形,然後在表單上繪製相應的圖案。 二、支援區域操作的編程介面 在Windows的API函數中有一組用於區域操作的函數,可以用來生成區域、合併區域、獲取區域資料、根據資料生成區域、把區域和表單聯繫等,其中常用的幾個函數有:生成矩形區域的CreateRectRgn函數,生成橢圓區域的CreateEllipticRgn函數,合併兩個區域的CombinetRgn函數,從記憶體區域資料生成區域的ExCreateRegion函數,獲得區域資料的GetRegionData函數,把區域和表單聯繫的SetWindowRgn函數。 在Delphi中,這些常用的區域函數都被封裝到了Windows單元中,在實際應用中,只須在單元檔中引用Windows單元(默認),即可直接使用這些函數。 三、多態表單的生成原理 1、不規則表單的生成 在實際操作過程中,可以直接利用CreateEllipticRgn函數直接生成圓形表單,也可以利用CreatePolygonRgn函數生成任意非矩形表單。如果目標區域過於複雜,可以把目標劃分成規則的多個小區域分別建立,再把各區域合併,即可得到目標區域。 對於要生成基於點陣圖圖案的表單,可以首先將點陣圖背景色設為單一色,再按點陣圖圖案上的色彩進行行掃描,每掃描到非背景色,則產生一個圖元寬的矩形區域,併入已形成的區域。這樣當整個圖案掃描完畢,以點陣圖輪廓構成的區域形成,然後把點陣圖圖案繪入表單,可以得到一個圖形表單。 2、動畫的生成 在表單創建時,建立起相對於每個點陣圖圖案的區域資料,在程式運行時,通過線程輪換調用資料產生區域,並在表單上顯示相應的點陣圖圖案,以達到動畫效果。 四、點陣圖圖案表單的創建 1、點陣圖圖案區域資料的生成函數GetRgnData procedure GetRgnData (Bmp: TBitmap; var nCount: Cardinal; var lpRgnData: PRgnData); var h, w, i, j: Integer; tc: TColor; hrgn1, hrgn2: HRGN; begin h := Bmp.Height; w := Bmp.Width; //獲取點陣圖第一象素點的顏色值,背景顏色 tc := Bmp.Canvas.Pixels[0, 0]; //生成矩形區域 hrgn1 := CreateRectRgn (0, 0, w, h); try for i := 0 to h-1 do begin for j := 0 to w-1 do begin //判斷當前象素點的顏色值是否與背景色相同 if Bmp.Canvas.Pixels[j, i] = tc then begin hrgn2 := CreateRectRgn (j, i, j 1, i 1); if hrgn2 <> 0 then //摳去hrgn2資料區域 CombineRgn (hrgn1, hrgn1, hrgn2, RGN_DIFF); DeleteObject (hrgn2); end; end; end; //獲取hrgn1資料區域大小 nCount := GetRegionData (hrgn1, 0, nil); //分配記憶體空間給臨時區域指標lpRgnData GetMem (lpRgnData, nCount * sizeof(TRgnData)); //獲取資料 GetRegionData (hrgn1, nCount, lpRgnData); except ShowMessage ('區域資料生成出錯'); end; DeleteObject (hrgn1); end; 2、動畫線程的實現 ⑴ 線程的定義 TAnimThread = class (TThread) private FIndex: Integer; OwnerForm: TForm; procedure DrawAnimPic; protected procedure Execute; override; public constructor Create (Form: TForm); {override;} end; 說明:①FIndex所要顯示的點陣圖索引值,OwnerForm指定當前表單; ②DrawAnimPic線程中動畫繪製表單過程。 ⑵ 線程的實現 constructor TAnimThread.Create (Form: TForm); begin OwnerForm := Form; FIndex := 0; inherited Create (False); end; procedure TAnimThread.DrawAnimPic; var Bmp: TBitmap; w, h: Integer; rgn: HRGN; begin Bmp := AnimBmp[FIndex]; w := Bmp.Width; h := Bmp.Height; //重新設置表單的尺寸 OwnerForm.Width := w; OwnerForm.Height := h; //從記憶體區域資料生成區域 rgn := ExtCreateRegion (nil, nCount[FIndex], TRData[FIndex]^); //把區域和表單聯繫起來 SetWindowRgn (OwnerForm.Handle, rgn, True); DeleteObject (rgn); //在表單畫布上繪製點陣圖圖案 BitBlt (OwnerForm.Canvas.Handle, 0, 0, w, h, Bmp.Canvas.Handle, 0, 0, SRCCOPY); end; procedure TAnimThread.Execute; begin inherited; //反復執行,直至線程終止 repeat FIndex := FIndex mod 6; //同步繪製過程DrawAnimPic Synchronize (DrawAnimPic); Sleep (300); Inc (FIndex); until Terminated; end; 說明:① 在繪製過程DrawAnimPic所使用到的變數定義在單元檔內,其定義: AnimBmp: array[0..5] of TBitmap; nCount: array[0..5] of Cardinal; TRData: array[0..5] of PRgnData; 以上變數均在表單創建過程中賦值,在表單銷毀前釋放。 ②線上程的執行(Execute)過程中,不能直接調用DrawAnimPic過程,以免產生VCL元件讀寫衝突,所以必須使用同步函數Synchronize進行協調。 五、結束語 通過本次學習,讓讀者初步瞭解Delphi編程中線程的創建及使用,同時掌握如何在Delphi編程過程中調用Windows 的API函數,來建立個性化的應用程式。本文簡述了一個動畫表單的實現過程,當然要真正作為一個寵物,它必須有自己的“思想”,會隨機地做出一些動作,這就需要在程式中可以隨機地調取一些動作序列,其程式過程讀者可根據自己的 興趣進一步完善。 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |