1. 程式人生 > >在C++Builder中動態建立控制元件

在C++Builder中動態建立控制元件

當開發類似解釋程式或實現視覺化操作功能等一類的應用程式時,都需要動態地建立控制元件(物件),而且還要為這些控制元件新增適當的事件處理程式,下面將介紹在C++Builder中如何實現基本的實現框架。

動態建立控制元件的一般過程:
  TButton *btn = new TButton(this);
  btn->Caption = "Button1";
  btn->Parent = this;
  btn->Show();

下面結合一個動態生成選單的例子來實踐如何動態建立控制元件並處理新增事件處理。

  先編寫一個函式用向一個已存在的選單物件中插入選單項:
  void __fastcall TForm1::AddContextMenuItem(TPopupMenu *pMenu,
    AnsiString caption, unsigned int tag, TNotifyEvent notifyEvent)

  引數:
  pMenu: 已存在的TPopupMenu物件指標
  caption: 選單項的標題
  tag: 選單項的tag值,用於標識不同的TMenuItem物件
  notifyEvent: 該選單項的事件處理函式

函式實現:

TMenuItem *mnuItem = new TMenuItem(pMenu); // Create new item

pMenu->Items->Add(mnuItem); // Add it to pMenu
mnuItem->Name = "CM_" + IntToStr(tag);
mnuItem->Caption = caption;
mnuItem->ImageIndex = imgIndex;
mnuItem->Tag = tag;
mnuItem->OnClick = notifyEvent; // Assign it an event handler


然後編寫呼叫AddContextMenuItem(...)的函式CreateContextMenu(),定義如下:

void __fastcall TForm1::CreateContextMenu(void)
{
FTagInc = 0;
FContextMenu = new TPopupMenu(this);
FContextMenu->AutoHotkeys = maManual;
FContextMenu->OnPopup = UpdateContextMenuItem;

AddContextMenuItem(FContextMenu, "選單項 1", FTagInc++, MenuItemClick);
AddContextMenuItem(FContextMenu, "選單項 2", FTagInc++, MenuItemClick);
AddContextMenuItem(FContextMenu, "-", FTagInc++, NullNotifyEvent);
AddContextMenuItem(FContextMenu, "選單項 3", FTagInc++, MenuItemClick);
}


FContextMenu是TForm1的成員變數,UpdateContextMenuItem()是用於在FContextMenu的Popup事件中更新選單項。

MenuItemClick與NullNotifyEvent都是TForm1中成員函式,是動態建立的控制元件的事件處理函式,格式為:
void __fastcall TForm1::MenuItemClick(TObject *Sender)
void __fastcall TForm1::NullNotifyEvent(TObject *Sender)

---------------------------------------------------------------------------------------------

程式碼如下:   
   .h檔案中:   
   class    TMyThread    :    public    TThread   
   {   
             public:   
                   __fastcall    TMyThread(void);   
             private:   
                   void    __fastcall    Execute();   
   };   
    
   .cpp檔案中:   
   __fastcall    TMyThread::TMyThread(void):    TThread(true)   
   {   
         FreeOnTerminate=true;   
         Resume();   
   }   
   void    __fastcall    TMyThread::Execute()   
   {   
           Form1->createview();     
   }   
   void    __fastcall    TForm1::Button1Click(TObject    *Sender)   
   {   
           TMyThread    *mythread    =    new    TMyThread;   
   }   
   void    __fastcall    TForm1::createview()          //createview()是我自己定義的函式   
   {         
           //動態生成LISTVIEW列表   
           TListView    *tempview    =    new    TListView(Form1);   
           tempview->Visible    =    true;   
           tempview->Parent    =    Form1;           
   }   
    
   就是以上程式碼執行後出現2個問題:   
   第一:點選Button按鈕時沒有建立listview控制元件   
   第二:關閉應用程式時出現以下錯誤提示:   
               應用程式發生異常    未知的軟體異常(0x0eedfade),位置為0x77e8bc3f。   

1:   
   void    __fastcall    TForm1::Button1Click(TObject    *Sender)   
   {   
           TMyThread    *mythread    =    new    TMyThread();   
           mythread->Execute;   
   }   
   2:估計是記憶體未釋放!!

TO:caizhen2000_82(猛將兄!!!)     
     你的方法不行呀,mythread->Execute;根本沒有這個方法。   
    
     估計是記憶體未釋放?可以說的具體一點嗎?   
    
    
   希望大家給出可行的解決方案,線上等!

Form1->createview();    Form1??   
   你要把ListView    放在那裡?
放在form1上呀

__fastcall    TMyThread::TMyThread(void):    TThread(true)   
   {   
    
         TListView    *ListView1    =    new    TListView(Form1);   
         ListView1->Parent=    Form1   
         FreeOnTerminate=true;   
         Resume();   
   }   
   放在建構函式中。
     TO:    chpst(斗轉星移)     
           非常感謝你的幫助,2個問題全部解決,不過又出現了新的問題!   
    
     動態生成的listview如何在createview()函式中呼叫呀

---------------------------------------------------------------------------------------------

關於動態建立控制元件

TButton    *a;   
   a    =    new    TButton(this);   
   a->Parent    =    Form1;   
   a->Top    =    10;   
   a->Left    =    10;   
   a->Width    =    30;   
   a->Height    =    10;   
   a->Caption    =    "haha";   
    
   如果要放到Panel上,指定的Parent指到Panel上就可以了Top

2 樓fjye(老薑)

動態名字的話我個人比較喜歡用控制元件陣列   
   比如   
   TButton    *button[10];   
   建立的方法一樣的   
   button[0]    =    new    TButton(this);   
   你可以定義個全域性變數num,代替方括號裡面變數的位置Top

3 樓JUNE20(花和尚:我也要學BCB!)

TButton    *    TempButton    =    new    TButton(this);   
                   TempButton->Parent    =    Form1;   
                   TempButton->Top    =      00;   
                   TempButton->Left    =    00;   
                   ...                    Width    =    00;   
                   ...                    Height    =    00;   
                   ...                    Caption    =    00;   
                   TempButton->Show();   
  Top

4 樓xiaoshi0(Rain)

動態建立的控制元件陣列是不用名字的,如果要在Panel上建立,只要把該控制元件的Parent屬性設定為Panel就可以了Top

5 樓ToIP(朽木)

//..........   
   buttone1->Update();Top

6 樓wcccc1(小豬義義)

TButton    *a;   
   string=buttonname="button"+i;//I定義成全域性的變數。   
   a    =    new    TButton(this);   
   a->Parent    =    Panel;   
   a->Top    =    10;   
   a->Left    =    10;   
   a->Width    =    30;   
   a->Height    =    10;   
   a->Name=    buttonname;   
   注,不知道這樣指名子行不行。如果系統不讓的話沒辦法了Top

7 樓wcccc1(小豬義義)

別忘了下邊I+1

------------------------------------------------------------------------------------

 在有些情況由於特殊的需求,需要開發自己的VCL元件以滿足需求。對於初學者來說有些問題是需要強調一下的。

  第一:就是檔案及類的命名問題

  選單操作過程:“Component->New Component...”,在“New Component”對話方塊的“Unit file name”欄中輸入你的類名,如你的類名為“TMyClass”,則這裡只要填寫“MyClass”,注意這裡沒有加“T”。確認後會開啟該檔案。

  完成對原始檔的編輯並儲存後,就要向IDE環境中 安裝該元件,操作如下:“Component->Install Component...”,選擇“Into new package”頁,在“Unit file name”中輸入要安裝的元件原始檔路徑及檔名,“Package file name”中輸入你要生成的新包檔案路徑及檔名,注意你裡的包名應該為類的名字,如“TMyClass.bpk”,這樣就會生成.bpk包檔案與包源文 件“TMyClass.cpp”,如果把包名寫MyClass.bpk,則你的元件的原始檔就會被覆蓋掉,當然你可以選擇存入在不同的路徑下,但這樣就會 不容易管理和容易產生混淆。

  第二:如何給新的元件自定義圖示

  一般情況下是需要為自己編寫的元件選擇一個合適的圖示,以更形象地表達該元件的功能,這個圖示是在設計階段在RAD環境中的元件欄中顯示,一般大小為24x24。

  首先,開啟C++Builder 自帶的Image Editor,選擇“File->New...->Component Resource File(.dcr)”,然後選擇“Resource->Bitmap”,輸入尺寸和顏色資料,確認後就建立了一個位圖讓你編輯,預設的資源名為“Bitmap1”,應該將這個名字更改,以和你的.bpl檔名一致,如你的元件的.bpl為“TMyComponent.bpl”,則它的名字應為“TMYCOMPONENT”,並且合部大寫。雙擊該結點就可開始編輯你的圖示,當然也可以使用PhotoShop之類的軟體做好後直接使用“貼上”命令貼上,注意最多支援256色。

  當圖示繪畫完成後就可以存檔,這時必須注意其命名的問題,該檔名必須與你的元件類名一致,如你的元件類名為“MyComponent”,則檔名應為“MYCOMPONENT.dcr”,並且全部大寫。再次安裝你的元件後就可以使用你自定義的圖示了。