vc如何添加控件,C#动态添加控件
动态控件是指create()在需要的时候创建的控件,不同于事先放在对话框中的控件。
首先,创建一个动态控件:
为了比较,我们先来看看静态控件的创建。
放置静态控件时,必须首先建立一个容器,通常是一个对话框。这时,在对话框编辑窗口中,我们可以从工具窗口中拖动所需控件,放入对话框中。然后,我们可以适当地修改控件ID并设置控件属性,这样就创建了一个静态控件。当对话框显示时,对话框上的控件也将显示。
静态控件不需要调用Create()函数来创建。
创建动态控件是非常不同的。以按钮为例,看看创建动态控件的过程:
1.建立质控ID号:
ID是控件的标识,您必须在创建控件之前为其设置一个ID号。
打开资源中的“字符串表”,在空行上双击鼠标。这时会弹出一个ID属性对话框。在ID编辑框中输入ID,如IDC_MYBUTTON,在标题中输入控件标题或注释(注意:标题框不能为空,会导致创建失败)。在这里,我输入要在按钮上显示的文本——动态按钮。
2.建立控制对象:
不同种类的控件应该创建不同的类对象:
按钮控制按钮(包括普通按钮、单选按钮和复选按钮)
编辑控制代码
静态文本控件CStatic
标签控制CTabCtrl
旋转控件CSpinButtonCtrl
滑动标签控件CSliderCtrl
多信息编辑控件
进度栏控件CProgressCtrl
滚动条控件CSrcollBar
组合框控件
列表框控件CListBox
图像列表控件CImageCtrl
树控件控件
动画控件CAnimateCtrl
在这个例子中,我们创建了一个普通的CButton类的按钮。注意CButton对象不能直接定义,比如CButton m _ MyBut这个定义只能用于定义静态控件的控制变量,不能用于动态控件。
正确的做法是用new调用CButton构造函数生成实例:
CButton * p _ my but=new CButton();
然后用CButton类的Create()函数创建,其原型如下:boolcreate (lpctstr lpszcaption,dword dwstyle,constrectrect,cwnd * pparentwnd,uintnid);
LpszCaption是按钮上显示的文本;DwStyle指定按钮样式,可以是按钮样式和窗口样式的组合。这些值是:
窗口样式:
WS_CHILD子窗口,必须有
Ws _ visible窗口是可见的,通常有
WS_DISABLED禁用窗口,该窗口在创建初始状态为灰色且不可用的按钮时使用。
WS_TABSTOP可以通过Tab键选择。
WS_GROUP分组,用于分组单选按钮中的第一个按钮。
按钮样式:
BS_PUSHBUTTON按钮,即普通按钮
BS _ AUTO单选按钮包含具有自动选择状态的单选按钮。
,BS_RADIOBUTTON单选按钮,不常用。
BS_AUTOCHECKBOX包含一个自动选择状态的复选按钮。
BS_CHECKBOX检查按钮,不常用
BS_AUTO3STATE包含自动选择状态的三态复选按钮。
BS _ 3状态三态检查按钮,不常用。
上述样式指定了要创建的按钮的类型。它们不能同时使用,但必须有一个或另一个。
位图将显示在BS_BITMAP按钮上。
BS _ DEF按钮设置为默认按钮,仅用于下推按钮。在一个对话框中只能指定一个默认按钮。
rect指定按钮的大小和位置;
pParentWnd表示有按钮的父窗口,不能为空;
nID使用上一步中创建的ID号指定与按钮相关联的ID号。
不同控件类的Create()函数略有不同。请查阅相关资料。
例如:p_MyBut- Create(动态按钮,ws _ child ws _ visible bs _ button,CRECT (20,10,80,40),this,IDC _ my button);
这样,我们就创建了一个宽度为60,高度为30的下推按钮,并在当前对话框的(20,10)处创建了“动态按钮”的按钮文本。
为了使创建过程更加方便易用,我定义了以下函数:cbutton * ctexteditorview:new my button(int NID,crect rect,int n style)
{
CString m _ Caption
m_Caption。LoadString(nID);//获取按钮标题
CButton * p _ Button=new CButton();
断言_有效(p _ Button);
p_Button- Create( m_Caption,WS _ CHILD WS _ VISIBLE BS _ Button n style,rect,this,nID);//创建按钮
返回p _ Button
}
其中m_Caption。LoadString( nID)从String表中读取按钮文本,这样在创建按钮ID的时候,文本要设置好,参数nStyle是除了所需样式之外的额外样式。
下面,我调用这个函数创建三个按钮,并将第一个按钮指定为默认按钮。按钮的ID已经提前设置好了:CButton * p _ my but[3];
p _ my but[0]=new my button(ID _ my but 1,CRect(10,20,50,35),BS _ def button);
p _ my but[1]=new my button(ID _ my but 2,CRect(55,20,95,35),0);
p _ my but[2]=new my button(ID _ my but 3,CRect(100,20,140,35),0);
二、动态控件的响应:
控件的动态响应函数不能用ClassWizard添加,只能手动添加。还是以上面的按钮为例,我们做按钮的点击响应函数。
1.在MESSAGE_MAP中添加响应函数:
消息响应函数在MESSAGE_MAP表中定义,其格式为:消息名(ID,函数名)。当我们使用ClassWizard添加函数时,会在AFX_MSG_MAP包围的区间内自动添加,比如:begin _ message _ MAP(ctexteditorview,cformview)。
//{ { AFX _ MSG _ MAP(CTextEditorView)
ON_BN_CLICKED(IDC_ICONBUT0,OnIconbut0)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
手动添加时,不要添加到AFX_MSG_MAP区间,以防ClassWizard无法正常工作,比如:begin _ message _ MAP(ctexteditorview,cformview)。
//{ { AFX _ MSG _ MAP(CTextEditorView)
ON_BN_CLICKED(IDC_ICONBUT0,OnIconbut0)
//}}AFX_MSG_MAP
ON_BN_CLICKED(ID_MYBUT1,OnMybut1)
ON_BN_CLICKED(ID_MYBUT2,OnMybut2)
ON_BN_CLICKED(ID_MYBUT3,OnMybut3)
END_MESSAGE_MAP()
其中ON_BN_CLICKED是按钮点击消息。
2.在头文件中添加函数定义:
用ClassWizard添加函数时,会在头文件的AFX_MSG区间添加函数定义,比如:protected:
//{{AFX_MSG(CTextEditorView)
afx _ msg void on iconbut 0();
//}}AFX_MSG
声明消息映射()
我们模仿这种形式,只是在AFX_MSG区间之外添加了函数定义:protected:
//{{AFX_MSG(CTextEditorView)
afx _ msg void on iconbut 0();
//}}AFX_MSG
afx _ msg void on mybut 1();
afx _ msg void on mybut 2();
afx _ msg void on mybut 3();
声明消息映射()
3.编写消息响应函数:
上面把消息和函数联系起来,点击按钮后应该做的具体工作在函数中完成:void CTextEditorView:OnMybut1()
{
MessageBox(‘哈!你点击了动态按钮。);
}
void CTextEditorView:OnMybut2()
{
……
}
void CTextEditorView:OnMybut3()
{
……
}
除了按钮的响应功能,还可以用上面获得的指针访问按钮,比如:
修改按钮的大小和位置:p _ my but[0]-move window(…);
修改按钮文本:p _ my but[0]-setwindowtext(…);
显示/隐藏按钮:p _ my but[0]-显示窗口(…);等一下。
三。资源回收:
因为动态控件对象是new生成的,不会被程序自动释放,所以需要手动释放。当不再使用该控件时,可以将其删除:if( p_MyBut[0])
删除p _ my but[0];
以上就是动态生成按钮控件的方法。接下来看单选按钮的动态生成。四。示例:单选按钮组的动态生成
单选按钮也属于CButton类,但由于单选按钮总是成组使用,所以在制作和使用上与普通按钮不同。
假设一个组中有三个单选按钮。最初,选择第一个单选按钮。
我们先来看静态制作方法:在对话框中放三个单选按钮,设置属性如下:
Radio1属性:可见、分组、制表位、自动
单选按钮2属性:可见、制表位、自动
单选按钮3属性:可见、制表位、自动
该属性设置将三个单选按钮分成一组,一次只能选择其中一个。如果对话框中有其他分组的单选按钮,它们在使用时不会相互干扰。但是第一个按钮还没有被选中。
然后使用ClassWizard为这组单选按钮添加变量。这里,只需为第一个单选按钮添加变量。变量名为m_Radio,类型为int。在构造函数中,ClassWizard将m_Radio的值设置为-1,我们将其改为0,这样就可以看到运行程序时第一个单选按钮被选中。之后,还应该使用ClassWizard为三个单选按钮添加点击响应函数,并修改m_Radio的值以对应三个单选按钮。
以上是制作单选按钮组的常用方法。现在想改成动态生成,主要是解决按钮分组和点击控制的问题。以下是生产步骤:
1.定义三个单选按钮的ID:
在资源中打开“字符串表”,并向其中添加三个ID值:
第一个:ID为IDC_MYRADIO1,标题为单选1。
第二:ID为IDC_MYRADIO2,标题为单选2。
第三:ID为IDC_MYRADIO3,标题为单选3。
标题是显示在按钮上的文本,可以根据需要设置。
2.使用CButton类的Create()函数生成三个单选按钮:
为了方便起见,首先定义一个函数生成单选按钮:cbutton * ctexteditorview:newmy radio(int NID,crect rect,int n style)
{
CString m _ Caption
m_Caption。LoadString(nID);//获取按钮标题
CButton * p _ Radio=new CButton();
断言_有效(p _无线电);
p_Radio- Create( m_Caption,WS _ CHILD WS _ VISIBLE n style WS _ TABSTOP BS _ AUTORADIOBUTTON,rect,this,nID);//创建按钮
返回p _ Radio
}
LoadString()函数用于从“字符串表”中读取按钮文本,Create()函数设置单选按钮的必要属性,包括可见、制表位和自动属性。
参数nID是单选按钮ID号,rect是单选按钮大小,nStyle是除必要属性以外的其他属性。返回值是一个指向新按钮的指针。
有了这个函数,在创建单选按钮组时只能依次调用这个函数,其中单选按钮组的第一个单选按钮必须指定WS_GROUP属性。c button * p _ my radio[3];
p _ my radio[0]=new my radio(IDC _ my radio 1,CRect(15,90,60,105),WS _ GROUP);
p _ my radio[1]=new my radio(IDC _ my radio 2,CRect(15,108,60,123),0);
p _ my radio[2]=new my radio(IDC _ my radio 3,CRect(15,126,60,141),0);
3.定义单选按钮组的控制变量,并将第一个单选按钮设置为选中状态:
这里不能使用ClassWizard添加变量,也不要在DoDataExchange()中添加控制变量,因为动态控件一开始是不存在的,在DoDataExchange()中添加控制变量会导致运行错误。这里我们只需要在头文件中随机定义一个int变量作为控制变量,比如int m _ SelRadio
在构造函数中将其初始值设为0:m _ sel radio=0;
在上面创建按钮的语句中,使用SetCheck()函数设置初始选中的按钮:CButton * p _ my radio[3];
p _ my radio[0]=new my radio(IDC _ my radio 1,CRect(15,90,60,105),WS _ GROUP);
p _ my radio[1]=new my radio(IDC _ my radio 2,CRect(15,108,60,123),0);
p _ my radio[2]=new my radio(IDC _ my radio 3,CRect(15,126,60,141),0);
p _ my radio[m _ sel radio]-set check(1);//将第一个无线电设置为选定状态。
在SetCheck()函数中,参数1表示设置为选中状态,参数0表示未选中。
4.添加鼠标点击响应功能:
单击单选按钮后,鼠标的状态会自动改变。这里,我们需要修改控制变量m_SelRadio的值,以便跟踪选中的单选按钮。
首先,鼠标点击消息与MESSAGE _ MAP:begin _ MESSAGE _ MAP(ctexteditorview,cformview)中的响应函数相链接。
//{ { AFX _ MSG _ MAP(CTextEditorView)
On _ bn _ clicked (IDC _ iconbut0,iconbut 0)//此处添加classwizard。
//}}AFX_MSG_MAP
On _ bn _ clicked (IDC _ my radio 1,on my radio 1)//单选按钮1
On _ bn _ clicked (IDC _ my radio 2,on my radio 2)//单选按钮2
On _ bn _ clicked (IDC _ my radio 3,on my radio 3)//单选按钮3
END_MESSAGE_MAP()
然后在头文件的MESSAGE_MAP中定义click函数:protected:
//{{AFX_MSG(CTextEditorView)
afx _ msg void on iconbut 0();//此处添加了ClassWizard
//}}AFX_MSG
afx _ msg void on myradio 1();//单选按钮1
afx _ msg void on myradio 2();//单选按钮2
afx _ msg void on myradio 3();//单选按钮3
声明消息映射()
这里注意不要在AFX_MSG区间添加函数,以免影响ClassWizard的使用。
定义具体的响应函数(这里是手动添加的,不是用class wizard)://点击单选按钮1 void CTextEditor View:on my radio 1()
{
m _ sel radio=0;
}
//单击我的收音机2上的单选按钮2Void CTextEditor View:()
{
m _ sel radio=1;
}
//单击我的收音机3上的单选按钮3Void CTextEditor View:()
{
m _ sel radio=2;
}
5.回收资源:
在析构函数中,回收已创建的单选按钮(也可以在不使用单选按钮时立即回收):ctexteditorview:~ ctexteditorview()
{
int I;
for(I=0;我我)
{
if(p_MyRadio[i])
删除p _ my radio[I];
}
}
这些是动态控件的生成和响应方法。不同控件的做法略有不同,但思路和步骤都差不多。希望以上例子能对你有所帮助。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。