“異形”按鈕非常有趣,就是按鈕的形狀不是標(biāo)準(zhǔn)的長方形或正方形,而有一絲“叛逆”——“異形”嘛,是不是?怎樣才能實(shí)現(xiàn)“異形”按鈕呢?由于window 95增加了對窗口區(qū)域概念的支持,使得窗口區(qū)域就是所定義的窗口看上去的形狀,窗口區(qū)域作為窗口的實(shí)際邊界區(qū)域,這樣窗口區(qū)域不僅定義了窗口的可畫區(qū)域,而且定義了窗口下隱含區(qū)域和響應(yīng)鼠標(biāo)擊鍵事件的響應(yīng)窗口區(qū)域。
按鈕的各種形狀是在運(yùn)行時(shí)設(shè)置的而不是在設(shè)計(jì)時(shí)設(shè)置。設(shè)計(jì)時(shí)按鈕的形狀仍然是長方形或正方形。
按鈕形狀的設(shè)計(jì)分成兩個(gè)步驟:
第一步創(chuàng)建按鈕的外形,即定義窗口區(qū)域。使用api的區(qū)域創(chuàng)建函數(shù)就可達(dá)到目的。區(qū)域創(chuàng)建函數(shù)很多,主要有createellipticrgn 、createpolygonrgn、 createrectrgn、 createroundrectrgn,用于創(chuàng)建不同類型的區(qū)域顯示。如果需要一個(gè)復(fù)雜區(qū)域形狀,那么可以分別使用不同的區(qū)域函數(shù)創(chuàng)建不同的區(qū)域,然后調(diào)用combinergn api函數(shù)把它們組合起來。所以說,不僅可以創(chuàng)建出圓形、三角形的按鈕,而且還可以創(chuàng)建出其它各種形狀的按鈕。
第二步將區(qū)域顯示應(yīng)用到窗口上。一旦使用區(qū)域函數(shù)創(chuàng)建了一個(gè)新的區(qū)域顯示,就可以使用setwindowsrgn函數(shù)將這個(gè)區(qū)域應(yīng)用到窗口上。
下面給出圓形、三角形按鈕實(shí)現(xiàn)的具體代碼。為了直觀顯示效果,將窗體的背景色設(shè)置為了黑色(color設(shè)置為clbtntext),并將兩個(gè)按鈕的cursor設(shè)置crcross。在窗體放置兩個(gè)button按鈕,分別定義為rbutton、tbutton。實(shí)現(xiàn)窗口區(qū)域的時(shí)機(jī)是在窗體首次創(chuàng)建時(shí),所以將處理程序放在oncreate事件中。
void __fastcall tform1::formcreate(tobject *sender)
{
//創(chuàng)建園形按鈕
hrgn hrgnr = createellipticrgn(0,0,rbutton→width,rbutton→height);
setwindowrgn(rbutton→handle,hrgnr,true);
//創(chuàng)建三角形按鈕
trpoint[0].x=tbutton→width/2;
trpoint[0].y=0;
trpoint[1].x=0;
trpoint[1].y=tbutton→height;
trpoint[2].x=tbutton→width;
trpoint[2].y=tbutton→height;
hrgn hrgnt = createpolygonrgn(trpoint,3,alternate);
setwindowrgn(tbutton→handle,hrgnt,true);
}
其中trpoint在unit.h頭文件中定義如下:
private: // user declarations
point trpoint[3];
上面的代碼在按鈕的邊界內(nèi)分別創(chuàng)建了一個(gè)園形區(qū)域和一個(gè)三角形區(qū)域,然后作為新的窗口區(qū)域把它賦給各自的按鈕。在創(chuàng)建園形按鈕時(shí)使用了橢圓形區(qū)域創(chuàng)建函數(shù),要使按鈕為園形在設(shè)計(jì)時(shí)該按鈕應(yīng)設(shè)計(jì)為正方形。另外區(qū)域是以按鈕坐標(biāo)的形式定義的,而不是用屏幕坐標(biāo)。(0,0)點(diǎn)是按鈕的最左上角,而(寬,高)點(diǎn)是按鈕的最右下角。
應(yīng)該注意的是,一旦將區(qū)域句柄賦給按鈕,就不能再對區(qū)域句柄作任何操作。如果將區(qū)域句柄賦給按鈕后,修改或刪除這個(gè)句柄將導(dǎo)致程序崩潰,所以……千萬不要這樣做,否則,你的程序雖然花哨了一些,但卻是“拾了芝麻丟了西瓜”而因小失大!說到這里,考試大提示程序設(shè)計(jì)首先要注意“穩(wěn)定性”,至于其它的都次要。
按鈕的各種形狀是在運(yùn)行時(shí)設(shè)置的而不是在設(shè)計(jì)時(shí)設(shè)置。設(shè)計(jì)時(shí)按鈕的形狀仍然是長方形或正方形。
按鈕形狀的設(shè)計(jì)分成兩個(gè)步驟:
第一步創(chuàng)建按鈕的外形,即定義窗口區(qū)域。使用api的區(qū)域創(chuàng)建函數(shù)就可達(dá)到目的。區(qū)域創(chuàng)建函數(shù)很多,主要有createellipticrgn 、createpolygonrgn、 createrectrgn、 createroundrectrgn,用于創(chuàng)建不同類型的區(qū)域顯示。如果需要一個(gè)復(fù)雜區(qū)域形狀,那么可以分別使用不同的區(qū)域函數(shù)創(chuàng)建不同的區(qū)域,然后調(diào)用combinergn api函數(shù)把它們組合起來。所以說,不僅可以創(chuàng)建出圓形、三角形的按鈕,而且還可以創(chuàng)建出其它各種形狀的按鈕。
第二步將區(qū)域顯示應(yīng)用到窗口上。一旦使用區(qū)域函數(shù)創(chuàng)建了一個(gè)新的區(qū)域顯示,就可以使用setwindowsrgn函數(shù)將這個(gè)區(qū)域應(yīng)用到窗口上。
下面給出圓形、三角形按鈕實(shí)現(xiàn)的具體代碼。為了直觀顯示效果,將窗體的背景色設(shè)置為了黑色(color設(shè)置為clbtntext),并將兩個(gè)按鈕的cursor設(shè)置crcross。在窗體放置兩個(gè)button按鈕,分別定義為rbutton、tbutton。實(shí)現(xiàn)窗口區(qū)域的時(shí)機(jī)是在窗體首次創(chuàng)建時(shí),所以將處理程序放在oncreate事件中。
void __fastcall tform1::formcreate(tobject *sender)
{
//創(chuàng)建園形按鈕
hrgn hrgnr = createellipticrgn(0,0,rbutton→width,rbutton→height);
setwindowrgn(rbutton→handle,hrgnr,true);
//創(chuàng)建三角形按鈕
trpoint[0].x=tbutton→width/2;
trpoint[0].y=0;
trpoint[1].x=0;
trpoint[1].y=tbutton→height;
trpoint[2].x=tbutton→width;
trpoint[2].y=tbutton→height;
hrgn hrgnt = createpolygonrgn(trpoint,3,alternate);
setwindowrgn(tbutton→handle,hrgnt,true);
}
其中trpoint在unit.h頭文件中定義如下:
private: // user declarations
point trpoint[3];
上面的代碼在按鈕的邊界內(nèi)分別創(chuàng)建了一個(gè)園形區(qū)域和一個(gè)三角形區(qū)域,然后作為新的窗口區(qū)域把它賦給各自的按鈕。在創(chuàng)建園形按鈕時(shí)使用了橢圓形區(qū)域創(chuàng)建函數(shù),要使按鈕為園形在設(shè)計(jì)時(shí)該按鈕應(yīng)設(shè)計(jì)為正方形。另外區(qū)域是以按鈕坐標(biāo)的形式定義的,而不是用屏幕坐標(biāo)。(0,0)點(diǎn)是按鈕的最左上角,而(寬,高)點(diǎn)是按鈕的最右下角。
應(yīng)該注意的是,一旦將區(qū)域句柄賦給按鈕,就不能再對區(qū)域句柄作任何操作。如果將區(qū)域句柄賦給按鈕后,修改或刪除這個(gè)句柄將導(dǎo)致程序崩潰,所以……千萬不要這樣做,否則,你的程序雖然花哨了一些,但卻是“拾了芝麻丟了西瓜”而因小失大!說到這里,考試大提示程序設(shè)計(jì)首先要注意“穩(wěn)定性”,至于其它的都次要。