C++Builder中保持控件的位置及大小

字號:

C++ Builder/Delphi是Inprise(原Borland)公司廣受歡迎的可視化C++/Pascal開發(fā)工具,利用它可極大地加快應(yīng)用程序的開發(fā)速度。但是,也正因為其是可視化編程工具,將控件拖放到Form后,控件的位置就固定死了。隨著Form的大小或屏幕分辨率的改變,控件和Form本身的位置往往變得非常混亂。本文將介紹一些正確定位控件及Form的方法。
    利用OnResize事件改變控件位置及大小
    C++ Builder/Delphi中的Form控件有一個OnResize事件,F(xiàn)orm的所有與大小變化有關(guān)的動作可以觸發(fā)這個事件,包括Form的創(chuàng)建、化/最小化/還原、用鼠標(biāo)拖動改變大小等。因此,在此事件中動態(tài)地改變各個控件的位置可以確保其在Form中的相對位置正確。因為CBuilder與Delphi的程序有很多共同之處,所以這里只列出CBuilder的代碼。
    下面的代碼將確保控件在任何情況下都居中。
    程序一:
    void __fastcall TForm1::FofmResize(TObject*Sender)
    {
    int midLoc=Width/2; file://取Form的中點
    Label1->Left=midLoc-Label1->Width/2; file://設(shè)置Label1的位置為Form居中
    Button1->Left=midLoc-Button1->Width/2; file://設(shè)置Button1的位置為Form居中
    }
    稍微修改這段代碼,可以使控件保持在任何想要的位置。同樣,也可以利用OnResize事件改變控件的大小。當(dāng)Form中控件很多時,分別對每一個控件單獨調(diào)整位置是件非常麻煩的事,在TFrom類中有一個Controls數(shù)組維護所有From中的控件,利用它可方便地對所有控件進行操作。下面是其源代碼:
    程序二:
    void __fastcall TForm1::FormResize(TObject*Sender)
    {
    int midLoc=Width/2;
    TControl * ChildControl;
    fof(int i=0; i    {//遍歷Controls數(shù)組,ControlCount是數(shù)組元素個數(shù)
    ChildControl = Controls[i];
    ChildCotrol->Left = midLoc-ChildControl->Width/2;
    }
    }
    利用“容器”控制成組控件位置
    上面的代碼對維持所有控制到統(tǒng)一位置非常方便,但不利于對成組控件進行操作。
    在C++Builder中提供了一些能安放其它控件的“容器”控件,如TPanel、TGrouPBox等,可以將控件放在“容器”控件中:然后對“容器”控件進行操作,從而達(dá)到成組控制控件的目的。利用“容器”控件控制控件位置的結(jié)果,所有控件都自動居中,但是在GroupBox1控件中的子控件卻沒有居中,這是因為Controls數(shù)組只維護Form的直接子控件,對Form中控件的子控件則無能為力。因此,GroupBox1控件中的子控件仍然在初始位置,必須編寫相應(yīng)代碼動態(tài)控制其位置及大小。這種技術(shù)非常重要,特別是在動態(tài)改變“容器”控件大小時。其實,“容器”控件與From一樣有Controls數(shù)組,只要對其進行與程序2類似的操作即可。代碼見程序三
    程序三:
    void __fastcall TForm1::FormResize(TObject*Sender)
    {
    int midLoc=Width/2;
    TControl * ChildControl;
    for(int i=0;i    {//遍歷Controls數(shù)組,ControlCount是數(shù)組元素個數(shù)
    ChildControl = Controls[i];
    ChildControl->Left = midLoc-ChildControl->Width/2;
    if (ChildControl ==GroupBox1)
    {//若控件是GroupBox,對其子控件進行操作
    int SubMidLoc=GroupBox1->Width/2;
    for(int
    j=0;jControlCount;j++)
    {//遍歷GroupBox1的Controls數(shù)組。ControlCount是數(shù)組元素個數(shù)
    ChildControl=GroupBox1->Controls[j];
    ChildContro1->Left=SubMidLoc-ChildControl->Width/2;
    }
    }
    }
    }
    在不同分辨率下維護窗體位置及大小
    商業(yè)程序一般要在各種分辨率下運行,正確判斷當(dāng)前分辨率就顯得很重要。Windows函數(shù)GetDeviceCaps可以返回任意設(shè)備描述表中設(shè)備大小。
    GetDeviceCaps有兩個參數(shù),第一個是要查詢的設(shè)備描述表句柄,第二個是要查詢參數(shù)的類型,其中HORZRES,VERTRES分別代表屏幕水平和垂直分辨率。程序4是獲得當(dāng)前屏幕分辨率的代碼。一般可將這段代碼放在“工程文件”(如Project1.cpp)中,并將i、j定義為全局變量,然后可以利用前面介紹的技術(shù)控制各種屏幕元素的大小及位置。
    程序四:
    HDC hdc=GetDC(NULL); file://獲得屏幕設(shè)備描述表句柄
    int i=GetDeviceCaps(hdc,HORZRES); file://查詢屏幕水平分辨率,并返回在變量i中
    int j=GetDeviceCaps(hdc,VERTRES); file://查詢屏幕水平分辨率,并返回在變量j中
    ReleaseDC(NULL,hdc); file://釋放屏幕設(shè)備描述表
    用同樣的方法,可以對不同大小紙張的打印進行控制,在這里不再贅述,有興趣的朋友可查看Caps幫助及打印幫助。