11.2 对话框框架简介

特殊说明:版权归个人所有,请勿转载,谢谢合作。

打开VC6.0后,点击【File】菜单,选择【New…】项,在弹出的新建窗口中,选择【MFC AppWizard(exe)】使用MFC向导方式创建,在【Project name】处输入项目名称,此处以“Demo_11”为例,点击【OK】按钮确认创建,如图11.2所示。

  • 图11.2 新建窗口

 

在弹出的MFC向导的第一步里,选择【Dialog based】项,即基于对话框模式,点击【Finish】按钮确认,如图11.3所示。

  • 图11.3 模式选择

 

工程创建完成后,如图11.4所示。

  • 图11.4 对话框模式

 

典型的对话框程序创建完成后,可以在类视图(ClassView)中,看到如下几个类:

CAboutDlg:关于版本对话框控制类;

CDemo_11App:应用程序管理类;

CDemo_11Dlg:对话框管理类。

 

其中,后两个类是根据项目名称而定的,规则是:C+项目名称+App(或Dlg))组成。

 

11.2.1  关于对话框控制类

关于对话框,主要用来显示程序的版本、版权、作者及创建等相关信息。在应用程序中没有任何功能作用,只是用于显示版本、版本权等信息。对话框执行结果如图11.5所示。

  • 图11.5 关于对话框

 

在VC6.0中,可以在资源视图(ResourceView)中找到这个对话框,在那里可以对相应用信息进行修改。当然也可以在类视图(ClassView)中,选择CAboutDlg类后点击鼠标右键,在弹出的菜单中选择【Go To Dialog Editor】项,如图11.6所示。

  • 图11.6 对话框编辑视图跳转

跳转成功后如图11.7所示。

  • 图11.7 关于对话框编辑界面

MFC编程模式下,通常情况下,一个对话框会对应一个类来对它进行管理,所有的操作方法与响应的消息也会在这个类中撰写与捕获。所有对话框管理类跳转到对话框,都可以使用如图11.6所示的操作方法。

如果想在资源视图(ResourceView)中找到这个对话框,就先需要知道这个类管理的是哪个对话框,以CAboutDlg类为例,在类视图(ClassView)中,双击【CAboutDlg】类,即可跳转到类的定义部分,代码如下所示(如下代码为系统生成):

class CAboutDlg : public CDialog
{
public:
  CAboutDlg();

// Dialog Data
  //{{AFX_DATA(CAboutDlg)
  enum { IDD = IDD_ABOUTBOX };
  //}}AFX_DATA

  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CAboutDlg)
  protected:
  virtual void DoDataExchange(CDataExchange* pDX);    
  // DDX/DDV support
  //}}AFX_VIRTUAL

// Implementation
protected:
  //{{AFX_MSG(CAboutDlg)
  //}}AFX_MSG
  DECLARE_MESSAGE_MAP()
};

 

在类的定义部分,可以找到“IDD=”后面的“IDD_ABOUTBOX”则为这个类管理的对话框的ID,此时就可以在资源视图(ResourceView)中的“Dialog”中找到这个ID,并使用双击鼠标右键,打开它,如图11.8所示。

  • 图11.8 关于对话框编辑模式

 

在MFC编程中,大部分对话框都需要一个类来对它进行控制。并使用DoModal()的方法显示,操作代码如下所示(如下代码为系统生成):

void CDemo_11Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
  if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  {
    CAboutDlg dlgAbout;
    dlgAbout.DoModal();
  }
  else
  {
    CDialog::OnSysCommand(nID, lParam);
  }
}

 

11.2.2  应用程序管理类

在MFC编程模式下,不会再出现入口函数,Windows已经将入口函数封装到底层操作,而应用程序管理类,它是项目第一个被执行的类,整个窗口由它来进行管理。它有一个很特殊的函数InitInstance,该函数可用于程序初始化,在程序开始执行时被自动调用。如果创建完工程后,不做任何操作,该函数将被第一个被执行。该函数有一个更重要的功能,就是调用下一章节讲解的对话框管理类(本例为CDemo_11Dlg)。代码如下所示(如下代码为系统生成):

BOOL CDemo_11App::InitInstance()
{
  AfxEnableControlContainer();

  // Standard initialization
  // If you are not using these features and wish to reduce the size
  //  of your final executable, you should remove from the following
  //  the specific initialization routines you do not need.

#ifdef _AFXDLL
  Enable3dControls();		// Call this when using MFC in a shared DLL
#else
  Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

  CDemo_11Dlg dlg;
  m_pMainWnd = &dlg;
  int nResponse = dlg.DoModal();
  if (nResponse == IDOK)
  {
    // TODO: Place code here to handle when the dialog is
    //  dismissed with OK
  }
  else if (nResponse == IDCANCEL)
  {
    // TODO: Place code here to handle when the dialog is
    //  dismissed with Cancel
  }

  // Since the dialog has been closed, return FALSE so that we exit the
  //  application, rather than start the application's message pump.
  return FALSE;
}

代码中灰色的部分说明了对话框管理类的调用,以及返回值的应用。

 

11.2.3  对话框管理类

对话框管理类,管理应用程序对话窗口。在通常情况下,一个对话框应该有一个管理它的类于之对应。类里的所有成员方法如图11.9所示。

  • 图11.9 对话框管理类

 

 

如图11.9所示,CDemo_11Dlg类中OnSysCommand函数,主要用来处理对话框标题栏菜单的一些操作,本例中实现了关于对话框显示,具体代码如下所示(如下代码为系统生成):

void CDemo_11Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
  if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  {
    CAboutDlg dlgAbout;
    dlgAbout.DoModal();
  }
  else
  {
    CDialog::OnSysCommand(nID, lParam);
  }
}

 

OnPaint函数主要用于图形的绘制,该函数相当于Win32 SDK编程下的WM_PAINT消息,相当于将WM_PAINT消息内部的结构封装成一个函数,用于图形的绘制。代码如下所示(如下代码为系统生成):

void CDemo_11Dlg::OnPaint() 
{
  if (IsIconic())
  {
    CPaintDC dc(this); // device context for painting

    SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

    // Center icon in client rectangle
    int cxIcon = GetSystemMetrics(SM_CXICON);
    int cyIcon = GetSystemMetrics(SM_CYICON);
    CRect rect;
    GetClientRect(&rect);
    int x = (rect.Width() - cxIcon + 1) / 2;
    int y = (rect.Height() - cyIcon + 1) / 2;

    // Draw the icon
    dc.DrawIcon(x, y, m_hIcon);
  }
  else
  {
    CDialog::OnPaint();
  }
}

 

OnInitDialog函数也是最常用的函数,它常用于数据的初始化操作(如:初始化控件风格、控件的内容等),代码如下所示,初始化的内容写在代码加灰处的后面(如下代码为系统生成):

BOOL CDemo_11Dlg::OnInitDialog()
{
  CDialog::OnInitDialog();

  // Add "About..." menu item to system menu.

  // IDM_ABOUTBOX must be in the system command range.
  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  ASSERT(IDM_ABOUTBOX < 0xF000);

  CMenu* pSysMenu = GetSystemMenu(FALSE);
  if (pSysMenu != NULL)
  {
    CString strAboutMenu;
    strAboutMenu.LoadString(IDS_ABOUTBOX);
    if (!strAboutMenu.IsEmpty())
    {
      pSysMenu->AppendMenu(MF_SEPARATOR);
      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, 
strAboutMenu);
    }
  }

  // Set the icon for this dialog.  The framework does this automatically
  //  when the application's main window is not a dialog
  SetIcon(m_hIcon, TRUE);			// Set big icon
  SetIcon(m_hIcon, FALSE);		// Set small icon
  
  // TODO: Add extra initialization here
  
  return TRUE;  // return TRUE  unless you set the focus to a control
}

 

对话框工程创建完成后,系统自动生成的三个类:CAboutDlg(关于版本对话框控制类)、CDemo_11App(应用程序管理类)、CDemo_11Dlg(对话框管理类)之间的关系在上面的章节中已经进行了说明,下面从全局角度进行介绍。CDemo_11App类是最早执行的一个类,而这个类中有一个Initstance函数,此函数调用了CDemo_11Dlg类。在CDemo_11Dlg类中,有一个OnSysCommand函数,又调用了CAboutDlg类。具体的调用过程,如图11.10描述了这一调用的过程。

  • 图11.10 对话框各类调用关系

 

转载请附上原文出处链接及本声明
李老师的博客 » 11.2 对话框框架简介

发表评论

提供最优质的文章集合

立即查看 了解详情