MFC - 控制管理

在MFC应用程序中,在将控件可视地添加到应用程序后,如果要在代码中引用它,则可以基于该控件或与该控件关联来声明变量. MFC库允许您为应用程序中使用的某些控件(值或控制变量)声明两种类型的变量.

  • 一个变量用于存储在控件中的信息,也称为控制变量/实例.

  • 另一个变量称为控制值变量.用户可以使用此变量对该控件执行某种操作.

控制变量/实例

控制变量是基于管理控件的类的变量.例如,按钮控件基于CButton类.

要在实际编程中查看这些概念,让我们创建一个基于MFC对话框的项目MFCControlManagement.

MFCControlManagement

创建项目后,您将在设计器窗口中看到以下对话框.

MFCControlManagement Created

第1步 : 删除TODO行并拖动一个复选框和一个Edit控件,如下面的快照所示.将复选框的标题更改为启用控件.

更改标题

第2步 : 右键单击复选框.

MFCControlManagement Checkbox

第3步 : 选择添加变量.

步骤4 : 您现在可以看到添加成员变量向导.

添加成员变量

您可以在此对话框中选择不同的选项.对于复选框,变量类型为CButton.默认情况下在此对话框中选中它.

同样,默认情况下也会选择控件ID,现在我们需要在Category组合框中选择Control,并在Variable Name中键入m_enableDisableCheck编辑框并单击完成.

步骤5 : 同样,添加Edit Control of Edit控件,其设置如下图所示.

Control Variables6

观察对话框类的头文件.您可以看到现在添加了新变量.

 
 CButton m_enableDisableCheck; 
 CEdit m_myEditControl;

控制值变量

您可以为控件声明的另一种变量是值变量.并非所有控件都提供值变量.

  • 值变量必须能够处理存储在控件中的值的类型它的目的是引用.

  • 例如,因为基于文本的控件用于处理文本,所以可以为它声明基于文本的数据类型.这通常是一个CString变量.

让我们看看这种类型的变量用于复选框和编辑控件.

第1步 : 右键单击复选框并选择Add Variable.

Add Variable

第2步 : 变量类型是BOOL.从"类别"下拉列表中选择"值".

步骤3 : 单击"完成"继续.

步骤4 : 同样,使用以下快照中显示的设置为Edit控件添加Value Variable.

Value Variables

第5步 : 在变量类型字段中键入CString,在变量名称字段中键入m_editControlVal.

步骤6 : 您现在可以在Header文件中看到这些变量.

 
 bool m_enableDisableVal; 
 CString m_editControlVal;

控制事件处理程序

将控件添加到应用程序后,无论是直观添加还是动态创建,您还将决定如何处理用户可以对控件执行的操作.

  • 对于项目对话框,已经与类关联,您可以在创建事件处理程序时利用一些快捷方式.

  • 您可以快速为默认控件通知创建处理程序事件或任何适用的Windows消息.

让我们看看为复选框添加事件处理程序的相同示例.

第1步 : 右键单击要处理通知事件的控件.

Event Handler1

第2步 : 在快捷菜单上,单击添加事件处理程序以显示事件处理程序向导.

事件处理程序向导

第3步 : 在"消息类型"框中选择要添加到"类别"列表框中所选类别的事件.

步骤4 : 接受函数处理程序名称框中的默认名称,或提供您选择的名称.

步骤5 : 单击添加并编辑以添加事件处理程序.

步骤6 : 您现在可以看到在CMFCControlManagementDlg.cpp文件末尾添加了以下事件.

 
 void CMFCControlManagementDlg :: OnBnClickedCheck1(){
//TODO:在这里添加您的控制通知处理程序代码
}

控制管理

到目前为止,我们已经了解了如何向应用程序添加控件.我们现在将看到如何根据用户要求管理这些控件.我们可以在特定的事件处理程序中使用控制变量/实例.

步骤1 : 让我们看看下面的例子.在这里,我们将在选中/取消选中复选框时启用/禁用编辑控件.

步骤2 : 我们现在添加了复选框单击事件处理程序.这是实现 :

 
 void CMFCControlManagementDlg :: OnBnClickedCheck1(){
//TODO:在这里添加您的控制通知处理程序代码
 UpdateData(TRUE); 
 if(m_enableDisableVal)
 m_myEditControl.EnableWindow(TRUE); 
 else 
 m_myEditControl.EnableWindow(FALSE); 
}

第3步 : 创建对话框时,我们需要将以下代码添加到CMFCControlManagementDlg :: OnInitDialog().这将管理这些控件.

 
 UpdateData(TRUE); 
 if(m_enableDisableVal)
 m_myEditControl.EnableWindow(TRUE); 
 else 
 m_myEditControl.EnableWindow(FALSE);

第4步 : 以下是CMFCControlManagementDlg.cpp文件的完整实现.

 
//MFCControlManagementDlg.cpp:实现文件
//
 #include"stdafx.h"
 #include"MFCControlManagement.h"
 #include"MFCControlManagementDlg.h"
 #include"afxdialogex.h"
 #ifdef _DEBUG 
 #define new DEBUG_NEW 
 #endif 
 
//用于App的CAboutDlg对话框关于
 class CAboutDlg: public CDialogEx {
 public:
 CAboutDlg(); 
//对话数据
 #ifdef AFX_DESIGN_TIME 
 enum {IDD = IDD_ABOUTBOX}; 
 #endif 
 protected:
 virtual void DoDataExchange(CDataExchange * pDX);//DDX/DDV支持
//实施
受保护:
 DECLARE_MESSAGE_MAP()
}; 
 CAboutDlg :: CAboutDlg():CDialogEx(IDD_ABOUTBOX){
} 
 void CAboutDlg :: DoDataExchange(CDataExchange * pDX){
 CDialogEx: :的DoDataExchange(PDX); 
} 
 BEGIN_MESSAGE_MAP(CAboutDlg,CDialogEx)
 END_MESSAGE_MAP()
//CMFCControlManagementDlg对话框
 
 CMFCControlManagementDlg :: CMFCControlManagementDlg(CWnd * pParent/* = NULL */)
:CDialogEx(IDD_MFCCONTROLMANAGEMENT_DIALOG,pParent),
 m_enableDisableVal(FALSE),m_editControlVal(_T("")){
 m_hIcon = AfxGetApp()&rarr LoadIcon(IDR_MAINFRAME); 
} 
 void CMFCControlManagementDlg :: DoDataExchange(CDataExchange * pDX){
 CDialogEx :: DoDataExchange(pDX); 
 DDX_Control(pDX,IDC_CHECK1,m_enableDisableCheck); 
 DDX_Control(pDX,IDC_EDIT1,m_myEditControl); 
 DDX_Check(pDX,IDC_CHECK1,m_enableDisableVal); 
 DDX_Text(pDX,IDC_EDIT1,m_editControlVal); 
} 
 BEGIN_MESSAGE_MAP(CMFCControlManagementDlg,CDialogEx)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_BN_CLICKED(IDC_CHECK1,& CMFCControlManagementDlg :: OnBnClickedCheck1 )
 END_MESSAGE_MAP()
//CMFCControlManagementDlg消息处理程序
 BOOL CMFCControlManagementDlg :: OnInitDialog(){
 CDialogEx :: OnInitDialog(); 
//将"关于..."菜单项添加到系统菜单. 
//IDM_ABOUTBOX必须在系统命令范围内. 
 ASSERT((IDM_ABOUTBOX& 0xFFF0)== IDM_ABOUTBOX); 
 ASSERT(IDM_ABOUTBOX< 0xF000); 
 CMenu * pSysMenu = GetSystemMenu(FALSE); 
 if(pSysMenu!= NULL){
 BOOL bNameValid; 
 CString strAboutMenu; 
 bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); 
 ASSERT(bNameValid); 
 if(!strAboutMenu.IsEmpty()){
 pSysMenu →  AppendMenu(MF_SEPARATOR); 
 pSysMenu →  AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu); 
} 
} 
//设置此对话框的图标.当应用程序的主窗口不是对话框时,框架会自动执行
//
 SetIcon(m_hIcon,TRUE);//设置大图标
 SetIcon(m_hIcon,FALSE);//设置小图标
//TODO:在这里添加额外的初始化
 UpdateData(TRUE); 
 if(m_enableDisableVal)
 m_myEditControl.EnableWindow(TRUE); 
 else 
 m_myEditControl.EnableWindow(FALSE); 
返回TRUE;//返回TRUE除非你将焦点设置为控件
} 
 void CMFCControlManagementDlg :: OnSysCommand(UINT nID,LPARAM lParam){
 if((nID& 0xFFF0)== IDM_ABOUTBOX) {
 CAboutDlg dlgAbout; 
 dlgAbout.DoModal(); 
} else {
 CDialogEx :: OnSysCommand(nID,lParam); 
} 
} 
//如果在对话框中添加最小化按钮,则需要
//以下的代码来绘制图标.对于使用文档/视图模型的MFC应用程序,
//框架会自动为您完成此操作. 
 void CMFCControlManagementDlg :: OnPaint(){
 if(IsIconic()){
 CPaintDC dc(this);//绘制设备上下文
 SendMessage(WM_ICONERASEBKGND,
 reinterpret_cast< WPARAM>(dc.GetSafeHdc()),0); 
//客户端矩形中的中心图标
 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; 
//画出图标
 dc.DrawIcon(x,y,m_hIcon); 
} else {
 CDialogEx :: OnPaint(); 
} 
} 
//系统调用此函数以获取要显示的光标,同时用户拖动
//最小化窗口. 
 HCURSOR CMFCControlManagementDlg :: OnQueryDragIcon(){
 return static_cast< HCURSOR>(m_hIcon); 
} 
 void CMFCControlManagementDlg :: OnBnClickedCheck1(){
//TODO:在此处添加控制通知处理程序代码
 UpdateData(TRUE); 
 if(m_enableDisableVal)
 m_myEditControl.EnableWindow(TRUE); 
 else 
 m_myEditControl.EnableWindow(FALSE); 
}

第5步 : 编译并执行上述代码时,您将看到以下输出.默认情况下,该复选框未选中.这也会禁用编辑控件.

控制管理

第6步 : 选中Enable Control复选框.这将自动启用编辑控件.

控制管理