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


    这几天专门调研了一下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可以销毁三个新生成的按钮。

  • 相关阅读:
    五种I/O模型
    Python socket服务
    Python 协程
    python openpyxl 简单使用
    python 文件夹压缩
    Python 多进程
    MySQL 自定义函数
    python 队列
    python 多线程、线程锁、事件
    python paramiko模块:远程连接服务器
  • 原文地址:https://www.cnblogs.com/sideny/p/3291046.html
Copyright © 2020-2023  润新知