當開發類似解釋程式或實現可視化操作功能等一類的應用程式時,都需要動態地建立控制項(對象),而且還要為這些控制項添加適當的事件處理常式,下面將介紹在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()函數中調用呀
---------------------------------------------------------------------------------------------
關於動態建立控制項1.個button,動態建立後如何控制它的位置?
2.這個控制項要放在另一個控制項上,比如panel上,怎麼寫?
3.如果動態建立的button的名字也是動態,該怎麼寫?比如先判斷是否要建立,如果需要則建立一個button1,再判斷,再需要的話則建立button2,這種情況下如何給button命名?
1 樓fjye(老薑)
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”,並且全部大寫。再次安裝你的組件後就可以使用你自訂的表徵圖了。