一、引言
相信大家都見過一些桌面上的小寵物,如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);
varh, 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);
tryfor 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);
end;
說明:①findex所要顯示的點陣圖索引值,ownerform指定當前窗體;
②drawanimpic執行緒中動畫繪製窗體過程。
⑵ 執行緒的實現
constructor tanimthread.create (form: tform);
begin
ownerform := form;
findex := 0;
inherited create (false);
end;
procedure tanimthread.drawanimpic;
varbmp: 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;
以上變數均在窗體建立過程中賦值,在窗體銷毀前釋放。
五、結束語
通過本次學習,讓讀者初步了解delphi程式設計中線程的建立及使用,同時掌握如何在delphi程式設計過程中呼叫windows 的api函式,來建立個性化的應用程式。本文簡述了乙個動畫窗體的實現過程,當然要真正作為乙個寵物,它必須有自己的「思想」,會隨機地做出一些動作,這就需要在程式中可以隨機地調取一些動作序列,其程式過程讀者可根據自己的 興趣進一步完善。
Windows檔案操作的API函式
在vc中,大多數情況對檔案的操作都使用系統提供的 api 函式,但有的函式我們不是很熟悉,以下提供一些檔案操作 api 函式介紹 一般檔案操作 api createfile 開啟檔案 要對檔案進行讀寫等操作,首先必須獲得檔案控制代碼,通過該函式可以獲得檔案控制代碼,該函式是通向檔案世界的大門。rea...
windows路徑操作API函式
pathremoveargs 去除路徑的引數 pathremovebackslash 去除路徑最後的反斜槓 pathaddbackslash 在路徑最後加上反斜槓 pathremoveblanks 去除路徑前後的空格 pathaddextension 在檔案路徑後面加上副檔名 pathremovee...
windows路徑操作API函式
windows 路徑操作 api函式 路徑截斷與合併函式 pathremoveargs 去除路徑的引數 pathremovebackslash 去除路徑最後的反斜槓 pathaddbackslash 在路徑最後加上反斜槓 pathremoveblanks 去除路徑前後的空格 pathaddexten...