C++Builder中異形按鈕的實現

字號:

“異形”按鈕非常有趣,就是按鈕的形狀不是標準的長方形或正方形,而有一絲“叛逆”——“異形”嘛,是不是?怎樣才能實現“異形”按鈕呢?由于window 95增加了對窗口區(qū)域概念的支持,使得窗口區(qū)域就是所定義的窗口看上去的形狀,窗口區(qū)域作為窗口的實際邊界區(qū)域,這樣窗口區(qū)域不僅定義了窗口的可畫區(qū)域,而且定義了窗口下隱含區(qū)域和響應鼠標擊鍵事件的響應窗口區(qū)域。
    按鈕的各種形狀是在運行時設置的而不是在設計時設置。設計時按鈕的形狀仍然是長方形或正方形。
    按鈕形狀的設計分成兩個步驟:
    第一步創(chuàng)建按鈕的外形,即定義窗口區(qū)域。使用api的區(qū)域創(chuàng)建函數就可達到目的。區(qū)域創(chuàng)建函數很多,主要有createellipticrgn 、createpolygonrgn、 createrectrgn、 createroundrectrgn,用于創(chuàng)建不同類型的區(qū)域顯示。如果需要一個復雜區(qū)域形狀,那么可以分別使用不同的區(qū)域函數創(chuàng)建不同的區(qū)域,然后調用combinergn api函數把它們組合起來。所以說,不僅可以創(chuàng)建出圓形、三角形的按鈕,而且還可以創(chuàng)建出其它各種形狀的按鈕。
    第二步將區(qū)域顯示應用到窗口上。一旦使用區(qū)域函數創(chuàng)建了一個新的區(qū)域顯示,就可以使用setwindowsrgn函數將這個區(qū)域應用到窗口上。
    下面給出圓形、三角形按鈕實現的具體代碼。為了直觀顯示效果,將窗體的背景色設置為了黑色(color設置為clbtntext),并將兩個按鈕的cursor設置crcross。在窗體放置兩個button按鈕,分別定義為rbutton、tbutton。實現窗口區(qū)域的時機是在窗體首次創(chuàng)建時,所以將處理程序放在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];
    上面的代碼在按鈕的邊界內分別創(chuàng)建了一個園形區(qū)域和一個三角形區(qū)域,考試大提示:然后作為新的窗口區(qū)域把它賦給各自的按鈕。在創(chuàng)建園形按鈕時使用了橢圓形區(qū)域創(chuàng)建函數,要使按鈕為園形在設計時該按鈕應設計為正方形。另外區(qū)域是以按鈕坐標的形式定義的,而不是用屏幕坐標。(0,0)點是按鈕的最左上角,而(寬,高)點是按鈕的最右下角。
    應該注意的是,一旦將區(qū)域句柄賦給按鈕,就不能再對區(qū)域句柄作任何操作。如果將區(qū)域句柄賦給按鈕后,修改或刪除這個句柄將導致程序崩潰,所以……千萬不要這樣做,否則,你的程序雖然花哨了一些,但卻是“拾了芝麻丟了西瓜”而因小失大!說到這里,我想,程序設計首先要注意“穩(wěn)定性”,至于其它的都次要。