• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 16, 文章 - 1, 評論 - 4, 引用 - 0
            數據加載中……

            C++ Builder 初學問與答(五~十)

            38)問:事件OnChange和OnScorll都可以描述滾動條的滾動事件,他們有什么區別嗎?

            答:事件OnChange和OnScorll是有區別的。只要屬性Position的值發生改變,那么無論這個值是用戶操作滾動條引起的還是通過程序修改的,都會產生OnChange事件。而OnScorll事件只有在用戶操作滾動條時才發生。當用戶操作滾動條時,首先發生OnScorll事件,然后OnChange事件才會發生。

              下面我們共同看一個程序來加深對滾動條的理解。

              在窗體上放置一個水平滾動條ScrollBar1和一個垂直滾動條ScrollBar2,以及一個記錄滾動條事件的Memo組件。當用戶操作滾動條時,在Memo組件中就會顯示發生的事件。

              選擇Memo組件,把它的ScrollBars屬性設置為ssVertical。

              選擇水平滾動條組件,雙擊OnScroll的Value域,系統將生成事件處理模板,輸入這樣一段代碼。

            void __fastcall TForm1::ScrollBar1Scroll(TObject *Sender,

                  TScrollCode ScrollCode, int &ScrollPos)

            {

            AnsiString temp;

            if(Sender==ScrollBar2)

            temp="垂直滾動條的";

            else

            temp="水平滾動條的";

            switch(ScrollCode)

            {

                   case scLineUp:temp+="scLineUp";break;

                   case scLineDown:temp+="scLineDown";break;

                   case scPageUp:temp+="scPageUp";break;

                   case scPageDown:temp+="scPageDown";break;

                   case scPosition:temp+="scPosition";break;

                   case scTrack:temp+="scTrack";break;

                   case scTop:temp+="scTop";break;

                   case scBottom:temp+="scBottom";break;

                   case scEndScroll:temp+="scEndScroll";break;

                 default:

            temp+="未知";break;

            }

            Memo1->Lines->Append(temp+"事件");
            }

              第一條語句聲明一個AnsiString類型的變量,用來存放將要顯示的字符串。

                   第二條語句判斷發送事件的對象,如果是垂直滾動條,將temp初始化為 “垂直滾動條的”,否則初始化為 “水平滾動條的”。

                   第三條語句根據ScrollCode的值,顯示相應的事件。

                   最后一條語句將要顯示的字符串加到文本框的末尾。

              在窗體中選擇垂直滾動條組件,選擇Events標簽,單擊OnScroll的Value域,從下拉列表框中選擇ScrollBar1Scroll事件處理程序。這樣,垂直滾動條和水平滾動條將共用一個事件處理程序。

              選擇水平滾動條組件,選擇Events標簽,雙擊OnChange域,然后輸入:

              Memo1->Lines->Append("水平滾動條的OnChange事件");

              它將在文本框后面顯示水平滾動條改變的信息。

              類似的,給垂直滾動條的OnChange事件加上如下代碼:

            Memo1->Lines->Append("垂直滾動條的OnChange事件");

              詳細代碼如下:

            //--------------------------------------------

            #include <vcl.h>

            #pragma hdrstop

            #include "Unit1.h"

            //--------------------------------------------

            #pragma package(smart_init)

            #pragma resource "*.dfm"

            TForm1 *Form1;

            //--------------------------------------------


            __fastcall TForm1::TForm1(TComponent* Owner)

                    : TForm(Owner)

            {

            }

            //--------------------------------------------

            void __fastcall TForm1::ScrollBar1Scroll(TObject *Sender,

                  TScrollCode ScrollCode, int &ScrollPos)

            {

                     AnsiString temp;

            if(Sender==ScrollBar2)

            temp="垂直滾動條的";

            else

            temp="水平滾動條的";

            switch(ScrollCode)

            {

                   case scLineUp:temp+="scLineUp";break;

                   case scLineDown:temp+="scLineDown";break;

                   case scPageUp:temp+="scPageUp";break;

                   case scPageDown:temp+="scPageDown";break;

                   case scPosition:temp+="scPosition";break;

                   case scTrack:temp+="scTrack";break;

                   case scTop:temp+="scTop";break;

                   case scBottom:temp+="scBottom";break;

                   case scEndScroll:temp+="scEndScroll";break;

                 default:

            temp+="未知";break;

            }

            Memo1->Lines->Append(temp+"事件");

            }

            //--------------------------------------------

            void __fastcall TForm1::ScrollBar1Change(TObject *Sender)

            {

                   Memo1->Lines->Append("水平滾動條的OnChange事件");

            }

            //--------------------------------------------

            void __fastcall TForm1::ScrollBar2Change(TObject *Sender)

            {

                Memo1->Lines->Append("垂直滾動條的OnChange事件");

            }
            //--------------------------------------------

              現在,編譯并運行這個程序,點擊滾動條,可以看出滾動條的事件產生情況。

              哪個事件優先你能看出來嗎?你一定會對OnScroll同一事件產生的兩個屬性值先后被OnChange分開而不解是嗎?你好好看一下什么時候產生scEndScroll值J

              其實我們如果要了解其他某個組件所產生的事件之間的順序,也可以用同樣的方法來實現。

              39)問:軌跡條(TrackBar)有那些主要屬性呢?

              答:軌跡條與滾動條有相似之處,它也有一個類似于滾動塊的滑動塊,可以用鼠標或者使用方向鍵移動。軌跡條的某些屬性與滾動條完全相同,例如Max,Min和Position。但是它還有一些特殊的屬性。

              1.LineSize屬性,用于指定當用戶按下方向鍵時,軌跡條的滑動塊移動的距離。

              2.PageSize屬性,用于指定當用戶按下PgUp和PgDn時,軌跡條上的滑動塊移動的距離。

              3.Frequency屬性,用于設置軌跡條刻度的單位。如果Max-Min等于100,而這個屬性等于10,那么軌跡條就被分成了10等份。

              4.Orientation屬性,用來確定軌跡條的放置方向,它有兩個值,tbHorizontal表示水平放置,tbVertical表示是垂直放置的。缺省情況下是水平放置的。


            5.SelStart這個屬性用來設置選擇的起點。

              6.SelEnd這個屬性用來設置的選擇終點。

              7.TickMarks這個屬性用來設置軌跡條標尺的位置。它有三個值,分別表示三種不同的滑動塊位置:

              tmBottomRight表示垂直放置時標尺顯示在軌跡條的下面或者水平放置時顯示在右邊。

              tmTopLeft表示垂直放置時標尺顯示在軌跡條的上面或者水平放置時顯示在左邊。

              tmBoth則表示軌跡條的兩邊都有標尺。

              8.TickStyle這個屬性用來確定軌跡條標尺的樣式。它有三個值,分別表示三種不同的標尺樣式:

              tsAuto表示自動顯示標尺的刻度。

              tsManual表示需要使用SetTick過程才能設置在某個位置顯示刻度。

              tsNone表示標尺不顯示刻度。

              40)問:軌跡條有哪些常用的事件呢?

              答:當用戶用鼠標或者鍵盤操作軌跡條時,就會產生OnChange事件。不過要注意,在程序中改變屬性Position的值不會產生OnChange事件,這一點與滾動條不同。

              41)問:進程條(ProgressBar)如何用呢?

              答:它的屬性與上面的那些組件差不多,象Max、Min、Orientation、Position與上面的含義大同小異。其中Position是這個組件的關鍵,它用來設置或者返回進程條的填充小方塊的當前位置,當進條結束的時候,這個位置應該是位置上限。

              Smooth:布爾類型,缺省為false。這時的填充是按格進行的,如果設置為true,則填充是平滑進行的。

              StepBy:其聲明為:void _fastcall StepBy(int Detla);這個函數用來向前填充進程條,同時改變Position的屬性值。它的增加量由參數Detla來指定。

              StepIt:其聲明為:void _fastcall StepIt(void);這個函數用來向前填充進程條,同時改變Position的屬性值。其填充步長由Step屬性來指定。

              Step:這個屬性用來設置當調用StepIt函數時,Position位置的增加量。缺省為10。

              42)問:UpDown控件有什么用?

              答:這個控件是一對上下箭頭按鈕,按下按鈕時會自動增加或減少某個數值。它通常有一個附屬組件,由UpDown控件的Associate屬性指定。如果這個組件是一個編輯框,那么編輯框就會自動顯示UpDown控件的屬性Position的值。

              UpDown控件也有一些滾動條和軌跡條所具備的屬性,例如Max,Min,Position,Orientation,它們的意義也基本上相同,不過UpDown控件同樣有一些特殊的屬性。

              AlignButton為udLeft時,表示將UpDown控件放置在附屬組件的左邊,為udRight時,則表示將UpDown控件放置在附屬組件的右邊。

              Associate用來指定關聯的附屬組件。

              ArrowKey屬性,當屬性為True時,按下上下方向鍵就像按下UpDown控件的上下箭頭一樣。缺省值為True。


            Thousands屬性, 當屬性為True時,如果Position超過1000,那么就會自動給所顯示的數值加上一個千分位。缺省值為True。

              Wrap屬性,當屬性為True時,如果Position的值大于Max,那么就會自動回到Min屬性指定的值。缺省值為False。

              43)問:UpDown控件有哪些常用的事件呢?

              答:UpDown控件有兩個常用的事件:OnChanging和OnClick。當用戶正在按下上下箭頭時,將發生OnChanging事件;當用戶按下上下箭頭時,會發生OnClick事件。

                我們共同來看一個例子:

              在窗體上放置兩個Edit控件,和兩個UpDown控件,將兩個UpDown控件的Orientation屬性分別取值udHorizontal和udVertical。

              將第二個UpDown控件的Max的取值為5000,Position值為100,將他們的Associate屬性分別與兩個編輯框關聯。在對應事件中輸入如下代碼:

            void _fastcall TForm1::UpDown1Changeing(TObject *Sender,bool &AllowChange)

            {

                   Edit1->Text=UpDown1->Position;

            }

            // 注意參數AllowChange可以用來指定是否允許改變Position屬性的值。

            void _fastcall TForm1::UpDown2Click(TObject *Sender,TUBtnType Button)

            {

                   Edit2->Text=UpDown2->Position;

            }

            //注意參數Button表示哪個按鈕被按下:btNext為上箭頭或者右箭頭;btPrew為下箭頭或者左箭頭。

              44)問:在UpDown右邊有一個HotKey組件是做什么的?

              答:熱鍵HotKey用來在程序運行期間動態地指定某個組件或者菜單的快捷鍵。在它的屬性中你只要記住HotKey屬性就可以了,這個屬性用來返回用戶指定的快捷鍵。

            代碼如下:

            //--------------------------------------

            #include <vcl.h>

            #pragma hdrstop


            #include "Unit1.h"

            //--------------------------------------

            #pragma package(smart_init)

            #pragma resource "*.dfm"

            TForm1 *Form1;

            //--------------------------------------

            __fastcall TForm1::TForm1(TComponent* Owner)

                    : TForm(Owner)

            {

            }

            //--------------------------------

            void __fastcall TForm1::X1Click(TObject *Sender)

            {

            Close();

            }

            //-------------------------------

            void __fastcall TForm1::HotKey1Change(TObject *Sender)

            {

                X1->ShortCut=HotKey1->HotKey;//X1為菜單名,注意有些書介紹用OnEnter事件,但我覺得不妥,不防你也試一下,用OnEnter你將得不到什么關聯J

            }

            //-------------------------------

              為什么這里用了一個Button1?如果你的程序中沒有另外一個組件可以獲得焦點,你將感受不到快捷鍵的功能的,因為焦點會停在HotKey組件上,在這里就是想將焦點轉移一下,然后用快捷鍵試一下效果J

            6.圖形列表組件TreeView
              45)問:有時侯,我希望實現類似資源管理器對文件夾管理的顯示方式,和對文件的管理顯示方式,在C++Builder中應該怎么辦?

            答:在C++Builder中可以直接使用圖形列表組件來實現,它包括TreeView、ListView以及Outline組件。其中Outline組件實際上是基于Windows 3.1環境的組件,而且無論從功能還是使用的角度來看,它都無法與TreeView相比,因此完全可以用TreeView組件代替Outline。所以我將主要介紹前面兩種組件。這兩個組件都在頁Win32中。

              46)問:TreeView組件是一個怎樣的組件?

              答:TreeView組件比較復雜,所以我們首先簡單地介紹一下這個組件的基本使用情況,然后再深入討論。

              TreeView組件采用了樹形結構,最典型的例子就是Windows 95的資源管理器,它用樹形結構顯示磁盤上的文件夾和文件。因此TreeView組件能夠清晰地顯示層次關系。

              47)問:請給我演示一下怎樣在設計狀態編輯TreeView好嗎?

              答:首先在窗體上放置一個TreeView組件,然后在對象編輯器中單擊屬性Items中的省略號按鈕,就會打開一個項目編輯器。

              TreeView組件的項目編輯器是一個在設計時專門增加、刪除節點和為節點賦予圖標的工具。從屏幕上可以看到,項目編輯器由項目組框和項目屬性組框組成。項目組框由一個項目列表框、按鈕New Item、按鈕New SubItem、按鈕Delete和按鈕Load組成。當你剛打開項目編輯器時,項目列表框是空的,New SubItem和Delete按鈕處于失效狀態。

              項目屬性組框由編輯框Text、編輯框Image Index、編輯框Selected Index和編輯框State Index組成。

              項目組框可以創建和刪除節點、子節點。如果要載入一個已經存在的TreeView節點,可以單擊按鈕Load。要創建一個新項目,單擊New Item,然后在文本編輯框中輸入新節點的標題。這時,New SubItem按鈕由失效變為有效,允許你在節點下再嵌套子節點。如果項目列表框中顯示了節點,那么Delete按鈕也會變的有效。你只要在項目列表框中選中這個節點然后單擊Delete按鈕,就可以刪除這個節點了。

              要注意的是:如果刪除的節點還包括子節點,那么子節點也會被同時刪除。

              項目屬性組框主要是為當前選中的節點(或子節點)設置屬性的。其中編輯框Text可以修改節點的標題。如果要在不是當前被選中的節點的左邊顯示圖像,那么應該在編輯框Image Index中輸入圖像的索引號。要禁止顯示圖像可以把這個節點Image Index設置為缺省值-1。

              如果要在被選中的節點的左邊顯示圖像,應該在編輯框Selected Index中指定圖像的索引號,索引號是從0開始的。要禁止顯示圖像可以把它設置為缺省值-1。

              如果要在節點的左邊多顯示一個圖像,可以在編輯框State Index中輸入圖像的索引號。這個索引號代表Tree View組件中的StateImages屬性所表示的圖像列表的索引。要禁止顯示圖像可以把這個項目設置為缺省值-1。

              注意:Image Index與 Selected Index 使用的是Images指定的ImageList;而State Index使用的是StateImages 指定的ImageList。

              48)問:TreeView的屬性太多了,我想問我一定要清楚哪些主要屬性?

              答: Items : 該屬性包含TreeView組件中的所有節點,它是TtreeNodes的對象,在設計時,你可以使用項目編輯器來增加、刪除和修改節點。在運行期間,可以通過Items屬性訪問每一個節點,并且也能夠增加、刪除和修改節點。而每一個節點又都是一個TtreeNode對象。

              AutoEWxpand:布爾類型。為true時,則當前被選擇的節點將自動擴展,沒有被選擇節點將自動折疊。缺省為false,這時擴展和折疊要用戶自己指定。

              DragMode:其聲明為:_property TdragMode DragMode;這個屬性用來設置樹狀視圖的拖放模式。缺省為dmManual,用戶要拖放節點需要調用BeginDrag才能拖放。若設置為 dmAutomatic,則樹狀視圖將支持自動拖放,用戶可以把一個節點拖到另一個位置。

              Images:用來設定TreeView中的不同節點的圖標。

              StateImages:用不同的的圖像來表示節點的不同狀態。

              在TreeView組件中,每個節點除了可以有一個文字標題外,還可以附加圖標,這樣可以使用戶界面更加直觀。這兩個屬性就包含著節點所使用的圖標。

              這兩個屬性都是TImageList的對象,所以如果要在TreeView組件中給節點添加圖標,就必須使用圖標列表組件給這兩個屬性賦值。如果在窗體中放置了圖標列表組件,那么單擊屬性Images中的下拉按鈕,就可以選取這個組件了。

              ShowButtons屬性值為True時表示凡是有子節點的節點將自動具有擴展按鈕(即+號按鈕)和折疊按鈕(即減號按鈕),單擊它們就可以擴展和折疊節點。屬性值為False時,不顯示這兩個按鈕,缺省值為True。

              ShowLines屬性用來確定是否顯示在節點和子節點之間的連線。缺省值為True。

              ShowRoot屬性用來確定與頂層節點連線是否顯示。缺省值為True。

              HideSelection屬性用來確定當輸入焦點從TreeView移動到其它控件上時,被選中的節點是否處于被選中狀態。當屬性值為True時,不再處于選中狀態。缺省值為True。

              Indent屬性用來設置子節點與父節點之間縮進顯示的距離。

              ReadOnly用來確定用戶是否可以直接修改節點的標題。當屬性值為False時,表示可以修改。修改方法是,選中要修改的節點并單擊進入編輯狀態。缺省值為False。

              SortType用來設置節點進行排序的方式。它有以下幾種取值:

              stNone:不排序(缺省值);

              stData:當節點所關聯的對象發生改變時重新排序;

              stText:當節點的標簽發生變化時重新排序;

              stBoth:當節點所關聯的對象或者節點的標簽發生改變時重新排序。

              以上排序原則為在同一層的節點以標簽的字母順序排序。

            此外,還有一些運行時態屬性。

              TopItem:這個屬性用來設置一個節點,這個節點將顯示在樹狀視圖的最上面。

              RowSelcet:缺省為false。若設置為true,則表示當前選擇的節點所在的整行都將加亮顯示。當ShowLines設置為true時,這個屬性無效。

              Selected:用來返回當前選擇的節點。

              49)問:屬性Images和StateImages有什么區別呢?

              答:每一個節點可以有兩個附帶的圖標。一般情況下只需要顯示一個圖標,這時我們經常使用Images來指定圖標,也就是說給屬性Images賦予一個ImageList對象。如果某個節點要顯示兩個圖標,那么還需要給屬性StateImages賦予一個ImageList對象。然后給節點的屬性StateIndex指定圖標的索引號。具體的方法是在項目編輯器中,修改編輯框State Index的值。

              其實在顯示一個圖標時,也可以使用屬性StateImages。但是使用Images屬性有一個優點,就是它可以為處于不同狀態的節點指定不同的圖標。例如在Windows 95的資源管理器中,被選中的節點顯示一個打開的文件夾,而沒有選中的節點顯示一個關閉的文件夾。要實現這一點很簡單,因為項目編輯器中的編輯框Image Index指定的圖標在節點未選中時顯示,而編輯框Seleted Index指定的圖像在節點選中時顯示。

              50)問:請在前面設計的TreeView組件的基礎上,給TreeView組件中的節點增加圖標。好嗎?

              答:好的,首先在窗體上放置兩個ImageList組件,這兩個組件將具有缺省的名字ImageList1和ImageList2。

              其次、編輯ImageList組件:ImageList組件實際上是一個圖標列表,它可以包含大量的圖標,這些圖標的大小由屬性Width和Height確定,缺省值都是16。

              ImageList剛建立時不包含任何圖標,你需要把已創建好的圖標引入到ImageList中。這個工作可以通過ImageList編輯器完成。

              用鼠標右鍵單擊ImageList組件,在快捷菜單中選擇ImageList Editor或雙擊一下該組件,就會出現下面這個編輯器。

              單擊Add按鈕,在彈出的Add Images對話框中選擇要引入的圖像文件,圖標就會出現在Images框內。從圖中可以看出,引入的圖標被自動賦予索引號。

              為了使用上的方便,每一個圖標都有一個編號,這個編號就是這個圖標的索引號。如果要引用某個圖標,只需要使用它的索引號就可以了。

              要注意的是:這個編輯器會自動把引入的圖像分解成16×16的圖標,之所以尺寸為16×16是因為ImageList的屬性Width和Height被設置成了16。如果圖標的尺寸不一樣,那么可以修改這兩個屬性,使其滿足圖標的要求。

            然后、繼續用項目編輯器給節點增加圖標:我們已經在圖標列表組件中加入了兩個圖標,其索引號分別為0和1,接著可以使用項目編輯器給節點增加圖標。

              再次打開項目編輯器,輸入所有節點。

              修改節點的ImageIndex, SelectedIndex屬性,    

              要注意的是,編輯框Image Index中的索引號是0,編輯框Selected Index中的索引號是1。也就是說,在選中或未選中狀態下,該節點顯示的圖標不同。

              修改所有節點的圖標索引號,使包含子節點的節點有兩種不同的圖標,而不含子節點的節點只有一種圖標,也就是編輯框Image Index和Selected Index的索引號相同。

              最后,修改TreeView1組件的Images屬性,從下拉列表中選擇ImageList1組件。

              從屏幕上可以看到,圖標已經出現在控件里面了。

              51)問:那怎樣給節點增加第二個圖標呢?

              答:要給節點增加第二個圖標,首先必須再創建一個圖標列表組件,然后把這個圖標列表賦值給TreeView組件的屬性StateImages。當然還要給這個圖標列表引入圖標。

              完成這些工作后,我們就可以進入項目編輯器,選中要增加第二個圖標的節點,修改編輯框State Index中的索引號即可。

              52)問:TreeView有哪些重要的函數呢?

              答:AlphaSort:其聲明為:bool _fastcall AlphaSort(void);這個函數用來對所有的節點按標簽的字母順序排序。若排序成功,則返回true。

              FullCollapse:其聲明為void _fastcall FullCollapse(void);這個函數的作用是折疊所有的節點,直到最頂層為止。

              FullExpand:其聲明為 void _fastcall FullExpand(void);這個函數的作用是展開所有的節點,直到最底層為止。若ShowButtons屬性為true,則所有的“+”都會變成“-”。

              GetHitTestInfoAt:其聲明為THitTests _fastcall GetHitTestInfoAt(int X,int Y);這個函數返回指定點與樹狀視圖之間的位置關系。這個點的位置由參數X、Y確定。THitTests是個集合,它可能包含下面的元素:

              HtAbove:在樹狀視圖的客戶區上方;

              HtBelow:在樹狀視圖的客戶區下方;

              HtNowhere:在樹狀視圖的客戶區內但在最后一個節點下面;

              HtOnItem:在某個節點的標簽或者圖標上;

              HtOnButton:在某個節點的左邊的圖標上;

              HtOnIcon:在某個節點的圖標上;

              HtOnIndent:在某個節點的縮進線上;

              HtOnLabel:在某個節點的標簽上;

              htOnRight:在某個節點的右邊;

              htOnStateIcon:在某個節點的狀態圖標上;

              htToLeft:在客戶區的右邊;

              htToRight:在客戶區的的左邊。

              GetNodeAt:其聲明為TTreeNode*_fastcall GetNodeAt(int X,int Y);這個函數用來返回指定點所在的節點。參數X、Y為這個點的坐標。如果這個點沒有節點,則返回NULL。

            53)問:能介紹一下TTreeNodes與TTreeNode?

            答:在BCB中,樹狀視圖的節點是通過TTreeNodes對象來管理的,通過這個對象可以對樹狀視圖進行動態的增加、刪除、插入、移動節點等操作。而每一個節點都是一個TTreeNode對象。

              TTreeNode的主要屬性和函數:

              Count:這個屬性用來返回某個節點所擁有的子節點的數目。它不包括其子節點。

              Item:其聲明為:_property TTreeNode* Item[int Index];這個屬性用來訪問該節點的某個子節點。其中參數Index為其子節點在所有子節點中的位置。

              Index:這個屬性用來返回該節點在其父節點的所有子節點中的位置。

              Text:這個屬性用來設置或者返回節點的標簽。

              Delete:這個函數用來刪除該節點本身。

              DeleteChildren:這個函數用來刪除該節點的所有子節點。

              EditText:這個函數用來對節點進行就地編輯。

              IndexOf:其聲明為:int _fastcall IndexOf(TTreeNode* Value);這個函數將返回該節點的某個子節點的序號。子節點由參數value指定。如果參數value指定的節點不是該節點的子節點,函數將返回-1。

              TTreeNodes的主要屬性和函數:

              Count:這個屬性用來返回樹狀視圖中節點的數目。

              Add:其聲明為:TTreeNode *_fastcall Add(TTreeNode,const System::AnsiString S);這個函數將在樹狀視圖中增加一個節點,新節點成為參數Node 指定的節點的父節點的最后一個子節點,參數S為新節點的標簽。

              AddChild:其聲明為: TTreeNode *_fastcall AddChild(TTreeNode,const System::AnsiString S);增加的新節點為參數Node指定的節點的最后一個子節點。

              AddChildFirst:其聲明為: TTreeNode *_fastcall AddChildFirst(TTreeNode,const System::AnsiString S);這個函數與AddChild不同的是新增加的節點為Node節點的第一個子節點。

              AddFirst :其聲明為:TTreeNode *_fastcall AddFirst(TTreeNode,const System::AnsiString S);這個函數與Add 相似,不同的是新節點成為Node節點的父節點的第一個子節點。

              Clear:這個函數將把整個樹狀視圖都清空。

              Delete:其聲明:void _fastcall Delete(TTreeNode *Node);這個函數將刪除參數Node 指定的節點。

              Insert:其聲明為:TTreeNode _fastcall Insert (TTreeNode* Node,const System::AnsiString S);這個函數用來在參數Node 指定的節點之后插入一個新的節點,新節點的標簽由參數S指定。

              7.圖形列表組件ListView
              54)問:TreeView組件能夠實現資源管理器左邊顯示區的內容,可是它右邊顯示區能將列表用各種不同的方式顯示,例如大圖標方式、小圖標方式、簡單列表方式和詳細列表方式。這在C++Builder應該怎樣來實現?

              答:這可以用ListView組件來實現,ListView組件從功能上講與列表框相似,但是從組件的屬性來看與TreeView相似。ListTiew組件所建立的列表可以用各種不同的方式顯示,例如大圖標方式、小圖標方式、簡單列表方式和詳細列表方式。

              ListView組件中的一部分屬性與TreeView組件中的屬性是相同的,例如Items,StateImages等。還有一些屬性是ListView特有的。

            LargeImages屬性用來設置存放大圖標的圖標列表,當列表處于大圖標顯示方式時,列表使用這個圖標列表中的圖標顯示。

              SmallImages屬性用來設置存放小圖標的圖標列表,當列表處于小圖標顯示方式時,列表使用這個圖標列表中的圖標顯示。

              MultiSelected屬性可確定用戶是否可以同時選擇多個項目。缺省值為false。

              屬性ViewStyle確定了顯示風格,可以取這樣一些值。

              vsIcon:列表以大圖標方式顯示,可以進行拖放操作。只顯示第一層節點,放置方式由Arrangement決定。

              vsSmallIcon:列表以小圖標方式顯示,可以進行拖放操作。只顯示第一層節點,放置方式由Arrangement決定。

              vsList:以簡單列表的方式顯示,不能進行拖放操作。節點是豎向放置的,只顯示第一層節點,Arrangement不起作用。

              vsReport:以詳細列表的方式顯示,顯示的信息可以分成多列。最左邊的列顯示圖標和文字,其余的列顯示詳細信息。節點是豎向放置的,每一層均已經展開,只有此時Columns的設置才起作用,Arrangement不起作用。

              屬性Columns  當屬性ViewStyle被設置為vsReport時,列表中的每一項可以分成多列顯示,這個屬性用于設置列數和列的標題。

              在設計時,按下Columns屬性Value列中的省略號按鈕可以打開一個ListView Columns編輯器,在這個編輯器中可以生成和編輯列及列的標題。

              屬性ColumnClick的值為True時,列表中的標題可以作為按鈕使用, 這個屬性最常見的應用是在Windows 95的資源管理器中,單擊文件名或者其它幾個列標題,列表中的文件就會按照文件名重新排序。

              屬性Items 包含列表中所有項目的集合。與TreeView組件中的Items屬性類似,這個屬性也有一個項目編輯器,你可以使用這個編輯器在設計時增加、刪除項目,設置項目的圖標索引以及標題等。它的使用方法與TreeView組件的Items編輯器基本相同。

              IconOptions屬性用來設置圖標的顯示方式。它還包含幾個子屬性:

              (1)Arrangement屬性:當該屬性等于iaTop時,表示圖標從左到右排列在ListView組件的頂部;等于iaLeft時,表示圖標從上到下排列在組件的左邊。

              (2)AutoArrange屬性:等于True時,表示增加、刪除或移動圖標時圖標將自動重排。

              (3)WrapText屬性:等于True時,表示當項目的標題超過圖標的寬度時標題將換行。

              此外,還有運行時態屬性

              Selected屬性用來返回列表中被選中的項目。

              TopItem屬性用來返回列表中當前可見的最頂端的項目。

              55)問:請您編寫一個程序來幫助我理解和記憶ListView控件好嗎?

              答:好的,選擇File菜單的New Application菜單項,打開一個空的工程,在窗體上放置一個ListView控件,兩個ImageList控件,一個ListBox控件。

              選中ImageList1控件,將它的Height和Width屬性設置為32。雙擊ImageList1控件,打開圖像列表編輯框。點擊Add按鈕,選擇一個大圖標文件。點擊打開按鈕。然后點擊OK按鈕。同樣方法給ImageList2控件加上小圖標。選擇TreeView控件,將它的LargeImages屬性修改為ImageList1。

            將它的SmallImages屬性修改為ImageList2。在ListView控件上點擊鼠標右鍵,選擇Columns Editor選項(當然我們只要點擊屬性Columns右邊的“…”就可以了)。彈出Columns編輯對話框。點擊Add New工具按鈕加入四個列表,選中它們,將它們的caption屬性修改為名稱、大小、類型、修改時間。

              關閉列表編輯對話框。

              在ListView控件上點擊鼠標右鍵(同樣我們只要點擊 Itmes屬性右邊的“…”也一樣),選擇Items Editor選項。彈出Items編輯對話框(與TreeView的Items Editor差不多),輸入樹型結構文檔。在這里,點擊“New Item”按鈕可以新建一個項,“NewSubItem”按鈕用來設置這個項的子項。“Delete”用來刪除某個項,包括它的子項。項司性編輯框中,Caption為這個項的標題,另外兩個為項的圖標。

              編寫列表框的OnClick事件代碼如攏?/P>

            void __fastcall TForm1::ListBox1Click(TObject *Sender)

            {

            switch(ListBox1->ItemIndex)

               {

                 case 0:    ListView1->ViewStyle=vsIcon;

                            break;

                 case 1:    ListView1->ViewStyle=vsSmallIcon;

                            break;

                 case 2:    ListView1->ViewStyle=vsList;

                            break;

                 case 3:    ListView1->ViewStyle=vsReport;

                            break;

               }

            }

              //------------------------------


              把ListView中的ViewStyle屬性改為vsReport,否則你將得不到上面的那種顯示方式。

              最后,編譯并運行這個程序,選擇不同的類型,我們可以看到TreeView控件的效果。

              56)問:在TreeView、ListView中的圖標管理能再說一下嗎?

              答:圖形列表組件很難理解的,主要問題是不太容易掌握它使用圖標的方式。圖形列表組件使用一個名為ImageList的組件管理所有的圖標,ImageList給每個圖標提供一個索引號,這樣在TreeView或ListView組件引用時就不必指出圖標的名字而直接指定索引號就可以了。用ImageList集中管理圖標,用戶使用圖標索引號的方式的確從某種角度減輕了編程人員的負擔,但是也使得他們在編程時必須記住一大堆編號代表的各是哪一種圖標,這就在一定程度上削弱了ImageList的優勢,也許在C++Builder以后的版本中能有更好的方法。

              57)問:如何動態的創建一個列表視圖呢?

              答:我們舉例說明。我先建立如圖的界面。

            并編寫如下的代碼:

            //------------------------------
            #include <vcl.h>

            #pragma hdrstop

            #include "Unit1.h"

            //------------------------------
            #pragma package(smart_init)

            #pragma resource "*.dfm"

            TForm1 *Form1;

            //------------------------------
            __fastcall TForm1::TForm1(TComponent* Owner)

                    : TForm(Owner)

            {

            }

            //------------------------------
            void __fastcall TForm1::FormCreate(TObject *Sender)

            {

            const char Names[6][3][10] =

               {{"廣東省","廣州市","華南"},

                {"上海市", "上海市","華東"},

                {"北京市", "北京市","華北"},

                {"遼寧省", "沈陽市","東北"},

                {"湖北省", "武漢市","華中"},

                {"云南省", "昆明市","西南"}};//準備各項的文字

              TListColumn  *NewColumn;//創建一個欄

              TListItem  *ListItem;//創建一個Items

              ListView1->ViewStyle = vsReport;//定義顯示方式

              Button3->Enabled=false;

              NewColumn = ListView1->Columns->Add();//增加欄

              NewColumn->Caption = "省份";//添置欄的名稱

              NewColumn = ListView1->Columns->Add();

              NewColumn->Caption = "省會";

              NewColumn = ListView1->Columns->Add();

              NewColumn->Caption = "方位";

              for (int i = 0; i < 6; i++)

              {

                ListItem = ListView1->Items->Add();

                ListItem->Caption = Names[i][0];//添置父節點

                ListItem->SubItems->Add(Names[i][1]);//添置子節點

                ListItem->SubItems->Add(Names[i][2]);

              }

            }/*此處有些朋友總感覺為什么還要創建TListColumn  *NewColumn;

              TListItem  *ListItem;其實我們只要這樣想就可以了,我們再手功創建時打開Columns、Items時等于又創建了一個項目,他們并不存在,我們卻要用,所以只能用這種方法來動態創建了J*/

            //------------------------------

            void __fastcall TForm1::Button1Click(TObject *Sender)

            {

            TListItem  *temp;

            temp=ListView1->Items->Add();

            temp->Caption=Edit1->Text;

            temp->SubItems->Add(Edit2->Text);

            temp->SubItems->Add(Edit3->Text);

            }

            //------------------------------
            void __fastcall TForm1::Button2Click(TObject *Sender)

            {

            ListView1->Items->Clear();        

            }

            //------------------------------
            void __fastcall TForm1::RadioButton1Click(TObject *Sender)

            {

            ListView1->ViewStyle = vsReport;

            Button3->Enabled=false;

            }

            //------------------------------
            void __fastcall TForm1::RadioButton2Click(TObject *Sender)

            {

            ListView1->ViewStyle = vsIcon;

            Button3->Enabled=true;

            }

            //------------------------------
            void __fastcall TForm1::Button3Click(TObject *Sender)

            {

            ListView1->AlphaSort(); //這個函數的作用是把列表視圖中的項按照它們的標簽字母順序排列,成功返回true。      

            }

            //------------------------------


              58)問:我要想對TreeView、ListView里面的項進行操作如何來進行呢?

              答:我們一般都是通過OnChange或OnChangeing事件來完成的,我們通過一個例子來看一下他們的應用及區別,我們在窗體中放上一個TreeView和一個Memo組件,并在TreeView的OnChange和OnChangeing分別寫如下代碼:

            //------------------------------
            #include <vcl.h>

            #pragma hdrstop

            #include "Unit1.h"

            //------------------------------
            #pragma package(smart_init)

            #pragma resource "*.dfm"

            TForm1 *Form1;

            //------------------------------
            __fastcall TForm1::TForm1(TComponent* Owner)

                    : TForm(Owner)

            {

            }

            //------------------------------
            void __fastcall TForm1::tvwChange(TObject *Sender, TTreeNode *Node)

            {

                    if(Node->Text=="遼寧")

                    Memo1->Lines->Add("I'm change!") ;

            }

            //------------------------------
            void __fastcall TForm1::tvwChangeing(TObject *Sender, TTreeNode *Node,

                  bool &AllowChange)

            {

                    AllowChange=false;

                    if(Node->Text=="遼寧")

                    Memo1->Lines->Add("I'm changeing!") ;

            }

            //------------------------------
               運行效果如下:

                只有OnChangeing起了作用,為什么呢?再看下面代碼:

            //------------------------------
            #include <vcl.h>

            #pragma hdrstop

            #include "Unit1.h"

            //------------------------------
            #pragma package(smart_init)

            #pragma resource "*.dfm"

            TForm1 *Form1;

            //------------------------------

            __fastcall TForm1::TForm1(TComponent* Owner)

                    : TForm(Owner)

            {

            }

            //------------------------------

            void __fastcall TForm1::tvwChange(TObject *Sender, TTreeNode *Node)

            {

                    if(Node->Text=="遼寧")

                    Memo1->Lines->Add("I'm change!") ;

            }

            //------------------------------

            void __fastcall TForm1::tvwChangeing(TObject *Sender, TTreeNode *Node,

                  bool &AllowChange)

            {

                    //AllowChange=false;這與把此句寫成AllowChange=true是一樣的

                    if(Node->Text=="遼寧")

                    Memo1->Lines->Add("I'm changeing!") ;

               兩個事件都起作用了,并且OnChangeing先于Onchange發生,所以原因很顯然:這一切都是OnChangeing的參數AllowChange造成的,所以要注意對這個參數的使用。

               在ListView中只要把上面的Node->Text改成Item->Caption就可以了。

            8.圖形類組件
              59)問:Windows是一個圖形系統,C++Builder是怎樣處理圖形的呢?

            答:C++Builder通過提供圖形組件來處理圖形,其中比較常用的有圖像組件(Image)、幾何圖形組件(Shape)和畫板組件(PaintBox)。前兩個組件位于Additional頁中,畫板組件位于System頁中。

              在BCB中,Form、Image、BitMap、PaintBox等都具有繪圖能力,這些組件中都有Canvas屬性。

              60)問:圖像控件有哪些特殊的屬性?

              答:圖像組件可以顯示各種以文件形式存儲在磁盤上的圖形。它有這樣一些特殊的屬性。

              AutoSize屬性,當屬性值為True時,圖像組件會自動調節尺寸以便適應圖像組件的大小。缺省值為True。

              Stretch屬性,當該屬性為True時,圖像的尺寸自動調整并填滿整個圖像組件的范圍。但ICO文件無法產生這種效果。缺省值為False。

              Transparent屬性,確定是否允許圖像中指定的顏色透明,從而使組件下面的物體顯示出來。缺省值為False。

              Center屬性,當該屬性為True時,圖像居中顯示;否則,從左上角開始顯示。

              屬性Picture,你可以在設計階段利用這個屬性指定所要顯示的圖片,也可以在運行期間再顯示。前面一種情況下,你可以單擊Picture屬性的Value列中的省略號按鈕,這時會出現一個圖片編輯對話框,單擊對話框中的Load按鈕就可以選擇載入要顯示的圖片了。

              61)問:如果是在程序運行期間載入圖片,應該怎么辦?

              答:如果是在程序運行期間載入圖片,那么可以使用TPicture類的方法LoadFromFile,這個方法可以載入存儲在磁盤上的圖像文件。例如要載入D盤根目錄下的picture.bmp,可以這樣調用:

              Image1->Picture->LoadFromFile("d:\\picture.bmp");

              這個控件可處理的圖片文件的類型有:.BMP文件、.ICO文件、.EMF和.WMF等多種圖像文件。如果你試圖載入一種無法識別的文件類型,將會產生異常錯誤。

              62)問:能說一下AutoSize與Stretch的區別嗎?

              答:好的,在窗體上放置兩個圖像組件,將左邊的圖像組件的AutoSize屬性為True,所以載入任何圖片后,組件的尺寸與圖片的尺寸完全相同。而且如果你增大或減小圖像組件的尺寸,圖片的顯示仍然不變。將右邊的圖像組件的AutoSize屬性設置為False,將它的Stretch屬性設置為True。當你增大或減小圖像組件的尺寸,圖片將按比例增大或縮小,也就是說圖片始終充滿整個組件。

              63)問:TShape控件有什么重要屬性?

              答:這個組件可以顯示一些常見的幾何圖形,例如矩形、圓、橢圓等。幾何圖形組件有幾個比較重要的屬性:Brush,Pen 和Shape。

              Brush屬性,用來設置幾何圖形內部的填充特性,包括填充的圖案(Style)和顏色(Color)等。

              Pen屬性,用來設置幾何圖形的外框特性,包括畫筆的顏色(Color)、線型(Style)和線寬(Width)及Mode關系等。

              屬性Shape,用來指出所顯示的幾何圖形類型。這個屬性可以有六種不同的值,分別表示六種不同的幾何圖形;

              (1)stEllipse表示橢圓。

              (2)stRectangle表示矩形。

              (3)stRoundRect表示圓角矩形。

              (4)stRoundSquare表示圓角正方形。

              (5)stSquare表示正方形。

              (6)stCircle表示圓。

              在設計階段,你可以使用鼠標改變圖形的尺寸。在運行期間,可以通過Height和Width屬性改變圖形的尺寸。

              64)問:屬性Brush前面有一個加號,它是什么意思?

              答:它表示這個屬性是可以展開的,也就是說,它還包含一些子屬性。單擊加號,可以發現它的子屬性是:Color和Style。

              Color屬性包含一系列C++Builder預定義的顏色,你可以從中為顯示的幾何圖形選擇一種填充顏色。

              Style屬性確定了幾何圖形的填充樣式,它可以分別取這樣8種值:bsBDiagonal, bsClear, bsCross, bsDiagCross, bsDiagonal, bsHorizontal, bsSolid和bsVertical。

              屬性Pen也象屬性Brush一樣有子屬性。它的子屬性是Color, Mode, Style和Width。其中最常用的就是Style和Width,它們分別表示線型和線寬。子屬性Style可以取這樣一些值來畫邊框:

              psSolid
              表示實線。
              
              psDash
              表示破折號。
              
              psDot
              表示圓點。
              
              psDashDot
              表示破折號和圓點。
              
              psDashDotDot
              表示破折號、圓點、圓點。
              
              psClear
              表示沒有線。
              
              psInsideFrame
              表示內框實線。
              
              65)問:這個畫板組件有什么作用?

              答:畫板組件主要為用戶提供一塊作圖區域,用戶可以使用繪圖語句在這個作圖區域上畫出各種不同的圖形。

              要注意的是,由于畫板組件沒有邊界,所以通常應該把它放在一個有邊界的容器類組件上。

              畫板組件主要使用Canvas屬性來進行繪圖工作。Canvas(畫布)是類TCanvas的對象,類TCanvas包含繪圖中使用的各種方法和屬性。下面我們首先介紹Canvas對象的各種屬性。

              畫筆(Pen)  Canvas對象中有一個畫筆成員,它確定繪制幾何圖形時使用的畫筆類型。剛才我們介紹了畫筆的線型和線寬。

              畫筆的Color屬性是繪圖時使用的前景色。

              畫筆的屬性Mode用來確定畫筆與屏幕上原有點的混合方式。可結合當前的顏色、屏幕的顏色或它們的反轉值,對線段的顏色重新定義。但不改變Color屬性。

              它可以取這樣一些值:

              pmBlack:表示用黑色繪圖;

              pmWhite:表示用白色繪圖;

              pmNot:畫筆繪制的點的顏色與原有的顏色相反;

              pmCopy:畫筆用Color屬性中定義的顏色繪圖。

              PmNotCopy:畫筆用Color屬性中定義的顏色的反轉色繪圖;

              PmMergePenNot:畫筆用Color屬性中定義的顏色與屏幕顏色的反轉色結合后繪圖;

              PmMaskNotPen:畫筆用屏幕顏色與Color屬性中定義的顏色結合后繪圖;

              PmMergeNotPen:畫筆用屏幕顏色與Color屬性中定義的顏色的反轉值結合后繪圖。

              Brush屬性,刷子屬性在前面已經詳細介紹過,它可以確定圖形的填充模式和填充顏色。

              屬性ClipRect,用來確定繪圖區域的范圍。任何超出這個范圍的圖形不會顯示。

              66)問:在Canvas對象上,我們可以用怎樣的方法來完成作圖工作?

              答:Canvas對象有一些基本做圖方法:

              1.首先是MoveTo方法,MoveTo將筆的當前位置設置到點(x,y)處,筆的當前位置將保存到PenPos屬性中,要注意的是,改變筆的當前位置用MoveTo方法,而不要修改PenPos屬性。函數形式為MoveTo(x,y)。

              2.LineTo方法,用來完成從當前位置畫一條直線至點(x,y),并把筆的位置移動到這一點。函數形式為LineTo(x,y)。

              在畫線時一般首先使用方法MoveTo移動線的起始點,然后再使用方法LineTo畫直線。

              3.方法Rectangle用來在畫布上用當前畫刷繪制矩形,其中x1,y1是矩形的左上角坐標,x2,y2是矩形的右下角坐標。因為正方形實際上就是一種特殊的矩形,所以你可以使用這個方法畫出正方形。函數形式為Rectangle(x1,y1,x2,y2)。

              4.方法Ellipset用來在畫布上給定的矩形邊界上畫一個橢圓,其中x1,y1是邊界矩形的左上角坐標,x2,y2是邊界矩形的右下角坐標。所謂邊界矩形就是圓或橢圓的外接矩形。函數形式為Ellipse(x1,y1,x2,y2)。

              5.方法RoundRect用來繪制圓角矩形:其中x1,y1,x2,y2分別是圓角矩形虛擬的左上角和右下角。x3,y3是圓角的長短半徑。函數形式為RoundRect(x1,y1,x2,y2)。

              6.方法Polygon可以畫出多邊形。函數形式為Polygon(Tpoint p,int Point_Size)。

              參數P是類Tpoint的一個數組,每一個Tpoint對象包含一個點的X和Y坐標。Points_Size用來指示數組的大小。這個是實心多邊形,Polyline是畫多邊形的,二者用法基本相同。

              67)問:在顯示區域輸出文本信息,我們是不是還象DOS下用printf函數來實現?

              答:printf是一個控制臺函數,不能在窗口程序中使用,一般我們TextOut輸出文本,其聲明:void _fastcall TextOut(int X,int Y,const AnsiString Text);其中x,y是輸出字符串起始點的坐標,text是要輸出的文本。當然你要用Lable也是可以的J

             

            9.多頁組件
              68)問:我覺得C++Builder的組件模板的管理方式很好,在這個模板中通過單擊頁就可以在各個頁之間進行切換,在C++Builder中我應該怎樣來實現呢?

            答:我們可以用多頁組件來實現,它的好處就是可以在有限的空間中盡量多地存放信息,而且便于把信息分類。就拿組件模板來說吧,在那么小的屏幕中放置了上百個組件,而且并不顯得凌亂,這都是多頁組件的功勞。

              如果窗體上要放置大量的組件,而且這些組件又是分組使用的,那么可以考慮使用多頁組件。這樣做可以使窗體更加簡潔明了。多頁組件既有多頁的特性,又是一個容器組件,它就像窗體一樣可以包含其他的組件。

              C++Builder提供了幾種功能相似的多頁組件,它們是:Win32頁中的TabControl,PageControl組件,Win31頁中的TabSet和TabbedNoteBook組件。從它們所在的頁的不同就可以知道,前兩個組件是應用在32位系統中的組件,無論從性能還是風格上來看,這兩個組件都更適合在Windows 95以上的板本中使用。后面兩種組件是為喜愛Windows 3.1風格的用戶保留的,其實我們完全可以只使用前兩種組件。

              69)問:TabControl組件和PageControl組件他們看起來簡直是一模一樣?

              答:初看起來這兩種組件的確差不多,我們可以通過下面的操作可以說明這一點。

              (1)在窗體上放置這兩個組件,通過修改Height和Width屬性把它們的尺寸設置成相同的。

              (2)在對象編輯器中,單擊TabControl的屬性Tabs中的省略號按鈕,這時會彈出一個字符串編輯器。在這個編輯器中分三行輸入第一頁,第二頁和第三頁。然后點擊OK按鈕。

              (3)在窗體中選取PageControl組件,用鼠標右鍵單擊該組件,在彈出的快捷菜單中選擇NewPage命令,PageControl組件將生成一個缺省名為“TabSheetN”的頁,其中N是從1開始的整數。第一次運行New Page命令生成的頁名為TabSheet1,第二次生成的名為TabSheet2,以此類推。我們使用這個命令生成三個頁。

              與TabControl組件不同的是,你可以直接單擊頁來切換頁面。單擊頁在切換頁面的同時也選中了整個PageControl組件。如果要選擇某個頁,可以先單擊頁切換到該頁,然后再單擊頁面就可以了。

            4)在對象編輯器中,選擇TabSheet1,TabSheet2和TabSheet3的Caption屬性,把它分別修改為第一頁,第二頁和第三頁。

              這樣看起來他們就完全一樣。

              70)問:但要是一樣,為什么有兩個不同的組件呢,用一個不就行了,好象他們并不真的完全一樣?

              答:你說的對,千萬不要被他們的外表假象所蒙蔽,實際上它們并不一樣。TabControl是一種“假”多頁組件,而PageControl才是“真”多頁組件。

              我們知道多頁組件把所要顯示的信息放在不同的頁中,實際上每個頁都是一個窗體,并可以通過頁來進行頁的切換。TabControl組件雖然有多個頁,但是實際上只有一個頁的模板,也就是說,每次用戶單擊頁時,這個頁都要根據頁模板更新一次,以便對用戶的選擇作出響應。

              很顯然,如果需要在每個頁上顯示不同的組件,那么TabControl肯定無法勝任這種工作。因為你每次換頁時,必須用代碼更新頁模板,這在C++Builder中實在不是一個好辦法。如果每個頁所顯示的組件相同只是內容有變化,那么使用TabControl會更加合適,因為它消耗的系統資源比較少。

              而PageControl則是每頁對應一個頁模板。所以,它適宜于每頁都不同的情況。

              71)問:TabControl組件有哪些常用的屬性?

              答:HotTrack屬性用來確定當鼠標指向頁時,頁上的標簽是否自動被加亮顯示。缺省值為False。

              MultiLine屬性用來確定當頁一行顯示不下時是否顯示到下一行。缺省值False表示在一行無法顯示完時,在行的右邊自動出現一個雙向箭頭,可以用來移動頁。

              TabHeight屬性用來設置頁的高度。缺省?表示頁的高度將自動適應頁上文本的高度。

              TabWidth屬性用來設置頁的寬度。缺省值0表示頁的寬度將自動適應頁上文本的寬度。

              TabPosition屬性為tpTop時,表示將頁放在TabControl組件的上面,為tpBottom時則表示放在下面。

              TabControl組件上的每一個頁都有自己的索引,最左邊的頁的索引為0,緊接著的頁的索引為1,以此類推。TabIndex屬性返回當前被按下的頁。

              Tabs屬性用來設置頁的個數及其標題,在設計時是使用一個字符串編輯器來實現的。

              72)問:TabControl控件有哪些比較重要的事件呢?

              答:TabControl有兩個比較重要的事件OnChange和OnChanging。每當頁被選中后就會發生OnChange事件,這時可以根據屬性TabIndex判斷哪個頁被選中,然后再采取響應的動作。

              OnChanging事件正好發生在頁被選中之前,也就是正好在一個頁切換到另一個頁之前。這個事件使得我們可以在頁切換之前采取某些行動,例如在某些條件沒有設置之前不準離開這一頁。

              其實這兩個事件以前我們已經詳細的研究過,這里就不再舉例說明了。

            73)問:PageControl組件好像比TabControl組件功能更強大,它是怎樣使用的?

              答:與TabControl相比,PageControl組件的功能確實更加強大,但是卻并不復雜。PageControl中的每一個頁都是一個TTabSheet組件,這個組件實際上是一個容器,你可以在上面放置各種控件。每個TTabSheet組件都有自己的屬性。

              實際上這里有兩層關系。最頂層的是PageControl組件,它負責管理多個TTabSheet組件,而每個TTabSheet組件也管理著放在它上面的組件。

              74)問:PageControl組件有哪些比較重要的屬性呢?

              答:ActivePage這個屬性顯示當前被選中的頁,它也可以用來切換頁。

              MultiLine屬性用來確定當頁一行顯示不下時是否顯示到下一行。缺省值False表示在一行無法顯示完時,在行的右邊自動出現一個雙向箭頭,可以用來移動頁。缺省值為False。

              TabHeight屬性用來設置頁的高度。缺省值0表示頁的高度將自動適應頁上文本的高度。

              TabWidth屬性用來設置頁的寬度。缺省值0表示頁的寬度將自動適應頁上文本的寬度。

              TabPosition這個屬性的值為tpTop時,頁將放在TabControl組件的上面,而為tpBottom時將顯示在下面。

              此外,還有運行時態屬性:

              Pages這個只讀屬性是PageControl組件上所有的頁組成的數組。

              PageCount這個屬性返回PageControl組件上的頁數。

              75)問: PageControl的每一頁都是一個TTabSheet組件,那TTabSheet有些什么屬性呢?

              答:TabVisible 這個屬性用來屏蔽某一頁的顯示。也說是說,它的值為False的時候PageControl組件將不顯示這個頁了,但是這個頁還存在,你還可以把這個屬性設置為True來恢復它的顯示。在程序運行期間不能刪除頁,只能屏蔽頁的顯示。

              PageIndex是頁的索引號,

              此外,還有運行時態屬性。

              PageControl屬性返回該頁所在的PageControl組件。

              TabIndex屬性返回該頁在所有可見頁中的索引號。

              因為在程序運行時是不能刪除頁的,所以PageIndex索引號是固定不變的。但是頁可以被屏蔽,當沒有頁被屏蔽時,TabIndex與PageIndex完全相同;當有頁被屏蔽時,TabIndex就與PageIndex就不同了。TabIndex是這一頁在所有可見頁中的索引號,也就是說,第一個可見頁的TabIndex是0,第二個可見頁的TabIndex是1,以此類推。

              76)問:能設計一個例子讓我更好的理解一下它們嗎?

              答:好的 ,首先在TabControl組件的頁面上放置一個編輯框組件。

              然后在PageControl組件的Tab1頁中放置一個編輯框組件。

              接著將PageControl組件切換到Tab2頁,放置一個文本編輯框組件。

              最后,編譯并運行這個程序。

              點擊tabControl組件的tab1到tab3標簽,可以看出,編輯框出現在組件的每一頁中。

              點擊PageControl組件的tab1到tab3標簽,可以看出,每一頁組件都不相同。

            10.菜單組件
              77)問:菜單是Windows常用的用戶界面。對于一個能夠實際應用的程序,菜單是必不可少的組成部分。C++Builder中是怎樣實現菜單的?

            答:C++Builder為我們提供了兩種菜單組件:一種是主菜單組件MainMenu;另一種是彈出菜單PopMenu組件。

              主菜單組件的作用是在窗體上生成菜單條。菜單組件剛放到窗體上時,菜單是不可見的,當雙擊它打開菜單編輯器并且增加了菜單項后,菜單條才出現在窗體的頂部。設計時的菜單條與運行時的菜單條完全一樣。

              下面我們介紹利用菜單編輯器進行菜單設計的過程。

              首先要打開菜單編輯器

              從組件模板上的Standard選項卡中選擇MainMenu組件,放置到窗體上。然后,用鼠標右鍵單擊菜單組件,然后在彈出菜單中選擇Menu Designer。當然,你也可以雙擊菜單組件打開菜單編輯器。

              被加亮顯示的小方框就是一個空白菜單項。

              接著要添加菜單項

              選中這個菜單項,這時對象編輯器中將出現這個菜單項的屬性。

              我們在菜單項的Caption屬性中輸入“文件(&File)”,其中“&F”可以生成一個快捷鍵,這樣用戶就可以通過鍵盤操作了,并且F下面出現了下劃線(注意:由于是系統原因,”&”一定要在英文狀態下輸入)。當我們輸入完標題并按下回車鍵時,C++Buildr會自動給這個菜單項賦一個名字,這里的名字是N1。如果你不滿意這個名字可以修改Name屬性。

              添加完菜單項后會自動出現一個空白的子菜單項等待你輸入。

              現在菜單編輯器中的輸入焦點移到了這個空白子菜單項上,同時對象編輯器將對應顯示這個子菜單項的屬性。你可以在Caption屬性中輸入子菜單項的標題“打開(&Open)”,然后按下回車鍵。菜單編輯器會打開一個新的子菜單項,并把輸入焦點移動到這個子菜單項上。這樣,就可以給菜單項增加一系列的子菜單了。

              同樣方法添加退出菜單。

              要開始編輯下一個菜單項,可以用鼠標單擊菜單項“文件”的右邊的虛線框,它表示一個空白的菜單項。


            78)問:當菜單項中的子菜單項屬于不同類別時,有必要用分隔條把子菜單項進行分組,菜單組件是怎樣實現這個功能的?

              答:我們在退出和保存兩個菜單項中間加入選擇分隔條,在退出菜單項上點擊鼠標右鍵,從彈出菜單中選擇Insert,這時,一個空白的菜單項就插入了,將它的Caption屬性設置為“–”這個減號符就可以了。

              79)問:那么,我們又怎樣給菜單項設置熱鍵呢?

              答:每個菜單項都有一個屬性ShortCut,利用這個屬性就可以給這個菜單項設置熱鍵了。現在我們給打開文件菜單項添加熱鍵。單擊這個菜單項,選擇屬性ShortCut,出現一個下拉菜單,其中包括一系列的熱鍵的組合。選擇Ctrl+O,這個熱鍵中就被賦給了退出菜單項。

              80)問:快捷鍵與熱鍵這兩個概念我已經弄糊涂了,您能給我解釋一下嗎?

              答:好的,快捷鍵與熱鍵相同的方面是,它們都是通過鍵盤來訪問。

              一個菜單項可以同時擁有快捷鍵和熱鍵。所謂快捷鍵通常只是一個字母,而熱鍵通常是一個組合鍵。另外它們的激活方式不一樣,例如一個子菜單項有一個快捷鍵O和一個熱鍵Ctrl+O,那么使用熱鍵就可以直接激活這個子菜單項,而使用快捷鍵你必須首先選中該子菜單項上一層的菜單項,然后按下快捷鍵才可以激活這個子菜單項。

              81)問:您講解的菜單到現在還只有菜單項和子菜單兩級,如果我希望子菜單還有自己的子菜單,應該怎么辦?

              答:這種嵌套的菜單項實際上就是級聯菜單。這里,我們給顏色菜單項添加子菜單項,選擇顏色菜單,單擊鼠標右鍵,在彈出的快捷菜單中選擇Create Submenu命令,這時在子菜ハ鈧薪魷忠桓鮒趕蠐業募罰被共艘桓黽讀說ァ?/P>

              當然,你也可以用Ctrl+方向鍵右鍵。

              82)問:很多菜單項的旁邊有復選標記,請問菜單編輯器是否提供了這個功能呢?

              答:復選標記就是在菜單項的標題的前面出現的勾號。復選標記經常用于一些狀態設置的菜單項,當處于該狀態時就會出現復選標記,否則復選標記消失。

              現在,我們給回繞菜單項設置復選標記,在對象編輯器中把它的屬性Checked改為True,這樣這個菜單項就會顯示復選標記。要取消復選標記可以把Checked屬性再次設置為False。


            83)問:我有時要設計一組互相排斥的菜單項,也就是單選菜單項,應該怎么辦呢?

              答:要使一組菜單項成為單選菜單項,必須滿足幾個條件。

              首先,這一組菜單必須在同一個下拉菜單中。

              其次,它們的RadioItem屬性必須都設置成了True。

              最后,它們的GroupIndex屬性必須相同。

              這一組中唯一被選中的菜單項的前面將會顯示一個圓點標記。

              84)問:我怎樣使菜單項失效呢?

              答:只要把菜單項的Enabled屬性設置為False,就可以使菜單項失效,這時菜單項是灰色的。在設計時和運行時你可以任意設置菜單項的Enabled屬性。

              85)問:菜單項有些什么常用的事件呢?

              答:菜單項只有一種事件OnClick,在實際編輯中這個事件是一定要響應的。

              86)問:我們一般在主菜單之外還會提供一個快捷菜單,就像C++Builder一樣,在窗體中單擊右鍵隨時都可以打開一個彈出菜單。C++Builder是怎樣實現彈出菜單的?

              答:彈出菜單有時候又稱為快捷菜單。彈出菜單與主菜單的區別是:主菜單是固定的,而彈出菜單是活動的;主菜單有多組菜單項,而彈出菜單只有一組。彈出菜單的設計方法與主菜單基本相同,也是使用菜單編輯器來完成的。 

            posted on 2007-06-29 11:17 東東會會 閱讀(3191) 評論(0)  編輯 收藏 引用 所屬分類: C++Builder 基礎

            久久久久亚洲AV无码专区首JN| 日韩久久无码免费毛片软件| 亚洲精品无码久久久久AV麻豆| 亚洲国产精品久久久久久| 久久精品天天中文字幕人妻| 久久精品国产亚洲AV忘忧草18| 欧美一级久久久久久久大| 久久久这里有精品中文字幕| 国产呻吟久久久久久久92| 国内精品久久久久久久涩爱| 国产日韩久久免费影院| 久久久久久一区国产精品| 久久人人爽人人爽AV片| 久久久久无码专区亚洲av| 青青久久精品国产免费看| 亚洲人成网站999久久久综合| 久久无码人妻精品一区二区三区| 久久久WWW免费人成精品| 人妻丰满?V无码久久不卡| 一本色道久久88综合日韩精品| 欧美久久久久久| 亚洲国产精品无码久久一区二区| 人妻精品久久无码专区精东影业| 99久久精品国产高清一区二区| 亚洲综合精品香蕉久久网97| 久久精品国产第一区二区| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 久久久午夜精品| 亚洲精品乱码久久久久久蜜桃| 久久乐国产综合亚洲精品| 色综合久久中文字幕无码| 久久免费国产精品一区二区| 狠狠色伊人久久精品综合网| 无码任你躁久久久久久老妇App| 亚洲伊人久久大香线蕉综合图片| 久久久久亚洲Av无码专| 国产精品成人久久久久久久| 久久精品国产亚洲AV久| 久久99免费视频| 久久99热这里只频精品6| 狠狠色噜噜狠狠狠狠狠色综合久久 |