zoukankan      html  css  js  c++  java
  • 11.MFC对话框

    一、MFC对话框

      1.对话框的分类

        模式和非模式

      2.相关类

        CDialog类 - 父类CWnd类

        CCommonDialog - 父类是CDialog类,称为通用对话框类,包括颜色对话框、文件对话框、字体对话框、

                 查找对话框、页面设置对话框、打印对话框。

        CPropertyPage类 - 父类是CDialog类,称为属性页对话框。

      3.CDialog类的使用类

       3.1 创建基于模式对话框的应用程序

        (1)添加对话框资源,与对话框类关联

        (2)在应用程序类的InitInstance函数中创建和显示对话框窗口

           CDialog::DoModal( )

        (3)对话框的关闭

           不要做任何处理,点击OK或关闭的时,会自动调用相关函数

           CDialog::OnOk

           CDialog::OnOk 

       3.2 创建基于非模式对话框的应用程序

        (1)添加对话框资源,与对话框类关联

        (2)窗口的创建和显示与一般的框架窗口类似

        (3)处理对话框的关闭(销毁对话框)

           重写CDialog::OnOk( )和CDialog::OnOk( )函数,在函数中调用DestroyWindow销毁对话框窗口

           重写CWnd::PostNcDestroy( )函数,在函数中完成对象的自我销毁,delete  this;

      相关代码:

    #include "stdafx.h"
    
    
    //2对话框类
    class CMyDialog :public CDialog
    {
    public:
        CMyDialog() : CDialog(IDD_DIALOG1) { }
        virtual void OnOK();
        virtual void OnCancel();
        virtual void PostNcDestroy();
    };
    void CMyDialog::OnOK() { DestroyWindow(); }
    void CMyDialog::OnCancel() { DestroyWindow(); }
    void CMyDialog::PostNcDestroy() { delete this; }
    
    //1应用程序类
    class CMyWinApp : public CWinApp
    {
    public:
        virtual BOOL InitInstance();
    };
    
    CMyWinApp theApp;
    
    BOOL CMyWinApp::InitInstance()
    {    
        //模式对话框
        //CMyDialog dlg;
        //m_pMainWnd = &dlg;
        //dlg.DoModal();    
        
        //非模式对话框
        CMyDialog *pDlg = new CMyDialog;
        pDlg->Create(IDD_DIALOG1);
        m_pMainWnd = pDlg;
        pDlg->ShowWindow(SW_SHOW);
        pDlg->UpdateWindow();
    
        return TRUE;
    }
    View Code

      运行结果:

      

      在MFC应用程序中创建对话框,在框架类中添加代码

      相关代码:

    #include "DlgModel.h"
    #include "DlgModeless.h"
    void CMainFrame::OnDlgModel()
    {
        //创建和显示模式对话框
        CDlgModel dlg;
        int nRet = dlg.DoModal();
        if (1 == nRet)
        {
            AfxMessageBox(L"用户点击OK按钮");
        }
        if (2 == nRet)
        {
            AfxMessageBox(L"用户点击Cancel按钮");
        }
    }
    void CMainFrame::OnDlgModeless()
    {
        //创建和显示非模式对话框
        CDlgModeless *pDlg = new CDlgModeless;
        pDlg->Create(IDD_DIALOG2);
        pDlg->ShowWindow(SW_SHOW);
        pDlg->UpdateWindow();
        
    }
    View Code

      运行结果:

      

      

      4. DoModal函数的执行过程

        4.1 查找并加载资源

        4.2 将父窗口设置为不可用状态

        4.3 创建对话框,进入对话框的消息循环

        4.4 点击OK、Cancel或者关闭按钮时,跳出循环,并且隐藏对话框窗口

        4.5 将父窗口设置为可用和活动状态

        4.6 销毁对话框窗口

        4.7 释放对话框资源

        4.8 返回

        dlg.DoModal( )

        {      

          //1 查找加载资源

          HRSRC hResource  =  ::FindResource( hInst, m_lpszTemplateName,   RT_DIALOG );

          hDialogTemplate  =  LoadResource( hInst,  hResource );

          //2 将父窗口设置为不可用状态

          HWND hWndParent  =  PreModal( );

          ::EnableWindow( hWndParent, FALSE );

          //3 创建对话框,进入对话框的消息循环

          CreateRunDlgIndirect( lpDialogTemplate,  CWnd::FromHandle(hWndParent), hInst )

          {

            BOOL  bRet  =  CreateDlgIndirect( lpDialogTemplate,  pParentWnd,  hInst )

            {

              RunModalLoop( dwFlags ) ==  m_nModalResult; 

              //4 点击OK、Cancel或者关闭按钮时,跳出循环,并且隐藏对话框窗口      

              SetWindowPos( NULL, 0, 0, 0, 0,  SWP_HIDEWINDOW |

                SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );

            }

          }

          //5 将父窗口设置为可用和活动状态

          ::EnableWindow( hWndParent,  TRUE );

          ::SetActiveWindow( hWndParent );

          //6 销毁对话框窗口

          DestroyWindow( );

          //7 释放对话框资源

          FreeResource( hDialogTemplate );

          return  m_nModalResult;

        }     

    二、控件操作

      1. 控件的初始化放到对话框的OnInitDialog( )函数中

      2. 对话框数据交换技术DoDataExchange,DDX

        2.1概念

          将控件与对话框类的成员变量绑定,通过操作成员变量的方式间接的操作控件

        2.2 使用步骤

          (1)添加成员变量

          (2)在CWnd::DoDataExchange( )函数中,将变量与控件绑定

             DDX_Control( ) - 控件类型的绑定

             DDX_Text( ) - 值类型的绑定,需要结合UpdateData使用

          (3)UpdateData(BOOL)函数

             FALSE - 将变量的值传递给控件

             TRUE - 用户在控件中输入的值传递给变量

      相关代码:  

    #include "stdafx.h"
    
    
    class CMyDialog : public CDialog
    {
    public:
        CMyDialog() : CDialog(IDD_DIALOG1) { }
        virtual BOOL OnInitDialog();
        virtual void DoDataExchange(CDataExchange* pDX);
        virtual void OnOK();
    protected:
        CButton m_btnOK;//与OK按钮绑定的成员变量
        CString m_sText;//与文本框绑定的值类型的成员变量
    };
    void CMyDialog::OnOK()
    {
        UpdateData(TRUE);//将用户在控件中输入的值传递给变量
        AfxMessageBox(m_sText);
        CDialog::OnOK();
    }
    void CMyDialog::DoDataExchange(CDataExchange* pDX)
    {
        //变量m_btnOK与OK按钮绑定
        DDX_Control(pDX, IDOK, m_btnOK);
        //值类型的绑定
        DDX_Text(pDX, IDC_EDIT1, m_sText);
    }
    BOOL CMyDialog::OnInitDialog()
    {
        if (!CDialog::OnInitDialog())
            return FALSE;
    
        //控件的初始化操作
        CWnd *pWnd = GetDlgItem(IDCANCEL);
        pWnd->EnableWindow(FALSE);
    
        //使用DDX操作OK按钮
        m_btnOK.MoveWindow(0, 0, 100, 100);
        m_btnOK.SetWindowTextW(L"DDXOK");
    
        //值类型的操作
        m_sText = "Hello World";
        UpdateData(FALSE);
        return TRUE;
    }
    
    class CMyWinApp : public CWinApp
    {
    public:
        virtual BOOL InitInstance();
    };
    
    CMyWinApp theApp;
    
    BOOL CMyWinApp::InitInstance()
    {
        CMyDialog dlg;
        m_pMainWnd = &dlg;
        dlg.DoModal();
        return TRUE;
    }
    View Code

      运行结果:

      

        2.3 实现原理

          (1)控件类型绑定

             DDX_Control( pDX,  IDOK,  m_btnOK )

             {

               //1 根据控件ID获取控件句柄

               pDX->PrepareCtrl( IDOK );  //给pDX中的成员m_pDlgWnd赋值

               HWND  hWndCtrl;

               pDX->m_pDlgWnd->GetDlgItem( IDOK,  &hWndCtrl );

               //2 将控件句柄附加到对象中

               m_btnOK.SubclassWindow( hWndCtrl )

               {

                 Attach( hWndCtrl )

                 {

                   pMap->SetPermanent( m_hWnd = hWndCtrl ,  &m_btnOK )

                   {

                     //以控件句柄为键,以变量地址为值,建立映射关系

                     m_permanentMap[ m_hWnd ]  =  &m_btnOK;  //★★★

                   }

                 }

               }

             }

          (2)值类型的绑定

             UpdateData( TRUE )

             {

               CDataExchange  dx( this, TRUE );  //对话框信息及相关参数

               DoDataExchange( &dx )

               {    

                 //回到我们自己写的代码         

                 DDX_Text( pDX,  IDC_EDIT1,  m_sText )

                 {

                   //1 根据控件ID得到控件句柄

                   HWND  hWndCtrl  =  pDX->PrepareEditCtrl( IDC_EDIT1 ); 

                   //2.1 将用户在控件的输入传递给变量            

                   if  ( pDX->m_bSaveAndValidate )  
                   {

                      //获得文本框内容长度

                     int nLen  =  ::GetWindowTextLength( hWndCtrl ); 

                     //获取文本框的值

                     ::GetWindowText( hWndCtrl,  m_sText .GetBufferSetLength( nLen ), nLen + 1 );  

                   }

                    //2.2 将变量的值显示到控件上

                   else

                   {

                     AfxSetWindowText( hWndCtrl,  m_sText ); 

                   }

                 }

               }

             }

  • 相关阅读:
    河工大玲珑校赛重现の 饶学妹的比赛
    河工大玲珑杯校赛随笔
    河南省第四届ACM省赛(T1) 序号互换
    河南省第四届ACM省赛(T3) 表达式求值
    debian系统下安装ssh
    戴尔poweredge r730服务器配置以及系统安装
    win10环境下安装Ubantu双系统(超详解)
    debian服务器解决中文安装后出现乱码的问题
    debian系统下安装ssh
    如何在ubuntu上搭建hustoj?
  • 原文地址:https://www.cnblogs.com/csqtech/p/5727563.html
Copyright © 2011-2022 走看看