原文:http://blog.sina.com.cn/s/blog_4a08244901014ok1.html

这几天专门调研了一下MFC中如何动态创建控件及其消息响应函数。

参考帖子如下:

(1)http://topic.csdn.net/u/20101204/13/5f1b1e70-2f1c-4205-ba10-41616d16f07e.html

(2)http://www.cppblog.com/deercoder/articles/107132.html

这两篇帖子是比较经典的,能够回答我的问题。但是如何动态创建消息响应函数呢?这需要利用另外一个命令:

ON_COMMAND_RANGE

参考如下帖子:http://topic.csdn.net/t/20020728/22/906766.html

注意:ON_COMMAND_RANGE映射了一组控件ID与其相应的消息响应函数,因为要区分是哪个控件ID的消息响应函数,所以其消息响应函数需要加上参数:UINT   nID  

下面我自己新建了一个MFC工程,开始测试上面帖子中的用法。经过反复比较,发现还有一个细节需要注意:

需要在String Table中加入初始化时的那个控件ID,具体操作如下:

打开资源中的“String Table”,在空白行上双击鼠标,这时会弹出一个ID属性对话框,在其中的ID编辑框中输入ID,如:IDC_MYBUTTON,在Caption中输入控件标题或注解(注:Caption框不能为空,为空会导致创建失败),这里我输入的是按钮上要显示的文字--动态按钮。
这样后面的操作就不会出错了。

具体代码如下:

(1)建立控件ID号:在String Table中加入一个新ID:IDC_MYBUTTON。注意和默认的ID的值保持距离

(2)建立控件对象:
注意不能直接定义CButton对象,如:CButton m_MyBut;这种定义只能用来给静态控件定义控制变量,不能用于动态控件。

对于一个Dialog资源,先关联一个类,比如CTestDlg

然后在CTestDlg.cpp中位置加入:

ON_COMMAND_RANGE(IDC_MYBUTTON,IDC_MYBUTTON+10,&CTestDlg::OnMYBTN)

如下所示:

BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
 ON_COMMAND_RANGE(IDC_MYBUTTON,IDC_MYBUTTON+10,&CTestDlg::OnMYBTN)
 ON_BN_CLICKED(IDC_BUTTON1, &CTestDlg::OnBnClickedButton1)
 ON_BN_CLICKED(IDC_BUTTON2, &CTestDlg::OnBnClickedButton2)
END_MESSAGE_MAP()
然后添加一个创建控件的函数:

CButton* CTextEditorView::NewMyButton(int nID,CRect rect,int nStyle)
{
CString m_Caption;
m_Caption.LoadString( nID ); //取按钮标题
CButton *p_Button = new CButton();
ASSERT_VALID(p_Button);
p_Button->Create( m_Caption, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | nStyle, rect, this, nID ); //创建按钮
return p_Button;
}

然后使用工具箱新建了一个button(IDC_BUTTON1),使得这个button的消息响应函数是用来新建三个新按钮。其消息响应函数如下:

void CTestDlg::OnBnClickedButton1()
{
 // TODO: 在此添加控件通知处理程序代码
if(btn_flag==false)

{

p_MyBut[0] = NewMyButton( IDC_MYBUTTON, CRect(20,20,50,60), BS_DEFPUSHBUTTON );
 p_MyBut[1] = NewMyButton( IDC_MYBUTTON+1, CRect(70,20,95,50), 0 );
 p_MyBut[2] = NewMyButton( IDC_MYBUTTON+50, CRect(120,20,140,35), 0 ); 
 btn_flag=p_MyBut[0] && p_MyBut[1] && p_MyBut[2]; //btn_flag=true;
}

}

另外又设置了一个button(IDC_BUTTON2),按下这个按钮就销毁之前创建的三个新按钮。

void CTestDlg::OnBnClickedButton2()
{
 if(btn_flag)
 {
  if(p_MyBut[0]) delete p_MyBut[0];
  if(p_MyBut[1]) delete p_MyBut[1];
  if(p_MyBut[2]) delete p_MyBut[2];
  btn_flag=false;
 }
}

设置全局变量:bool btn_flag;用来表示是否按下了button1,新建了三个按钮

设置全局变量:CButton *p_MyBut[3];用来存放新建的三个按钮

而这三个按钮的消息响应函数如下:注意需要加参数!

void CTestDlg::OnMYBTN(UINT nID)
{
 int index = nID - IDC_MYBUTTON;

CString strBtn;
 strBtn.Format(_T("BUTTON%d"),index);
  MessageBox(strBtn);
}

========================================================

最后实现的功能就是按Button1生成三个新按钮,每个按钮都可以触发一个messagebox。而按Button2可以销毁三个新生成的按钮。

【转载】MFC动态创建控件及其消息响应函数的更多相关文章

  1. MFC动态创建控件及其消息响应函数

    这几天专门调研了一下MFC中如何动态创建控件及其消息响应函数. 参考帖子如下: (1)http://topic.csdn.net/u/20101204/13/5f1b1e70-2f1c-4205-ba ...

  2. MFC 动态创建控件

    动态控件是指在需要时由Create()创建的控件,这与预先在对话框中放置的控件是不同的.   一.创建动态控件:   为了对照,我们先来看一下静态控件的创建.   放置静态控件时必须先建立一个容器,一 ...

  3. 小子给大家分享一个或者多个新手创建tableview经常会遇到的坑(动态创建控件,xib的重用)

    小子最近做了一个根据接口返回的数据在Cell中动态创建控件,感觉应该会一部分人卡在这里,小子就跟大家分享一下: 1.控件重复创建:这个问题出现的原因是动态创建的cell内容的时候,无法进行重用设置,所 ...

  4. VisionPro笔记(1):动态创建控件

     VisionPro学习笔记(1):动态创建控件 有的时候可能需要在程序中动态创建控件,VisionPro实例中提供了一例动态创建Blob控件的方法.当然,动态创建过多的控件会极大的消耗系统的资源,建 ...

  5. delphi动态创建控件

    动态创建控件 其实动态创建控件很简单,相信看过本文后你会全明白的. 1 先在单元的initialization 部分注册它,(这样在单元使用时会自动注册的)如: RegisterClass( TBut ...

  6. 在DELPHI中动态创建控件以及控件的事件

    在DELPHI中我们经常要动态的创建控件以及控件的事件.例如,我们可能想根据程序需要动态的创建一些Tshape组件来创建某个图形,并使得在鼠标移动上去之后可以完成某些操作.这一般需要需要三步: 生成一 ...

  7. Winfrom动态创建控件

    FlowLayoutPanel flowLayoutPanel1 = new FlowLayoutPanel();for (int i = 0; i < 9; i++){    Button b ...

  8. 动态创建控件 #Create(...)

    在类中创建一个控件对象;例:CButton m_btn; 用Create创建一个对象(#其实已经与其绑定)m_btn.Create(.....); #注意Create()函数的参数 问题一:点击一个b ...

  9. 【VS开发】MFC CListCtrl列表控件的消息响应

    MFC里的CListCtrl选中一行,消息是哪个.实在想不起来了.找了一篇文章,比较有用: http://www.cnblogs.com/hongfei/archive/2012/12/25/2832 ...

随机推荐

  1. 在html的JavaScript部分计算,保留小数点后面的位数

    例: f_pbf = ((f_boday_fat/f_weight)*100).toFixed(1);      注:例子中的.toFixed(1)是所用函数,确保在所得结果中保留小数点后面一位数,若 ...

  2. 转:未能打开编辑器:Unmatched braces in the pattern.

    原文地址:http://blog.csdn.net/hytdsky/article/details/4736462 Eclipse出现这个问题而不能查看源代码  原因就是语言包的问题 出现这个问题了 ...

  3. 超简易复制Model对象(为后续备忘录设计模式博文做铺垫)

    超简易复制Model对象(为后续备忘录设计模式博文做铺垫) 复制整个Model需要实现NSCopy协议,可以想象是非常麻烦的一件事情,今天我跟大家分享一个不需要你做任何操作的复制Model对象的方法, ...

  4. iOS手势处理

    iOS手势处理 iOS手势有着如下几种: UITapGestureRecognizer UIPinchGestureRecognizer UIRotationGestureRecognizer UIS ...

  5. Windows批量修改文件夹及子文件夹下文件的扩展名

    实例:将 D:/backup 目录下所有后缀名为 “.zip” 的文件替换为 “.exe” 后缀 bat批处理: @echo off rem 不显示执行过程 D: rem 切换至指定盘符 cd D:/ ...

  6. C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数

    各位相加 给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数. 示例: 输入: 输出: 解释: 各位相加的过程为: + = , + = . 由于 是一位数,所以返回 . 进阶:你可以 ...

  7. Spring 读取配置文件的俩种方式

    读取配置可通过 org.springframework.core.env.Environment 类来获取, 也可以通过@Value的方式来获取 注解形式: @PropertySource({&quo ...

  8. 1003. [ZJOI2006]物流运输【区间DP+最短路】

    Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转 停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严 ...

  9. Docker实战(八)之Web服务与应用

    1.Apache 官方提供了名为httpd的Apache镜像,可以作为基础web服务镜像 Dockerfile(安装apache2) FROM httpd:2.4 COPY ./public-html ...

  10. 【转】Android:No implementation found for native

    解决方法: 1.检查native c code的定义: JNIEXPORT void Java_com_example_something_MyClass_getMyString(JNIEnv * e ...