📜  MFC-控件管理

📅  最后修改于: 2020-11-20 06:27:37             🧑  作者: Mango


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

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

  • 另一个变量称为“控制值变量” 。用户可以使用此变量在该控件上执行某种动作。

控制变量/实例

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

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

MFCControl管理

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

MFCControlManagement已创建

步骤1-删除TODO行,并拖动一个复选框和一个Edit控件,如以下快照所示。将复选框的标题更改为“启用控件”。

更改标题

步骤2-右键单击复选框。

MFCControlManagement复选框

步骤3-选择添加变量。

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

添加成员变量

您可以在此对话框上选择其他选项。对于复选框,变量类型为CButton。在此对话框中默认选中它。

同样,默认情况下也会选择控件ID,现在我们需要在“类别”组合框中选择“控件”,然后在“变量名”编辑框中键入m_enableDisableCheck,然后单击“完成”。

步骤5-类似地,使用以下快照中所示的设置添加“编辑”控件的“控制变量”。

控制变量6

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

CButton m_enableDisableCheck;
CEdit m_myEditControl;

控制值变量

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

  • value变量必须能够处理要引用的控件中存储的值的类型。

  • 例如,由于使用了基于文本的控件来处理文本,因此可以为其声明基于文本的数据类型。这通常是一个CString变量。

让我们研究一下用于复选框和编辑控件的此类变量。

步骤1-右键单击复选框,然后选择添加变量。

添加变量

步骤2-变量类型为BOOL。从类别下拉列表中选择值。

步骤3-单击完成以继续。

步骤4-类似地,使用以下快照中所示的设置为Edit控件添加值Variable。

值变量

步骤5-在变量类型中键入CString,在变量名称字段中键入m_editControlVal。

步骤6-现在您可以看到这些变量已添加到Header文件中。

bool m_enableDisableVal;
CString m_editControlVal;

控制事件处理程序

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

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

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

让我们看看添加了事件处理程序复选框的同一示例。

步骤1-右键单击要处理其通知事件的控件。

事件处理程序1

步骤2-在快捷菜单上,单击添加事件处理程序以显示事件处理程序向导。

事件处理程序向导

步骤3-在消息类型框中选择事件,以添加到在类列表框中选择的类。

步骤4-在“函数处理程序名称”框中接受默认名称,或提供您选择的名称。

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

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

void CMFCControlManagementDlg::OnBnClickedCheck1() {
   // TODO: Add your control notification handler code here
}

控制管理

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

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

步骤2-我们现在添加了复选框click事件处理程序。这是实现-

void CMFCControlManagementDlg::OnBnClickedCheck1() {
   // TODO: Add your control notification handler code here
   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 : implementation file
//

#include "stdafx.h"
#include "MFCControlManagement.h"
#include "MFCControlManagementDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CAboutDlg dialog used for App About

class CAboutDlg : public CDialogEx {
   public:
      CAboutDlg();
    
   // Dialog Data
   #ifdef AFX_DESIGN_TIME
      enum { IDD = IDD_ABOUTBOX };
   #endif

   protected:
      virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
      
   // Implementation
   protected:
      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 dialog


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 message handlers

BOOL CMFCControlManagementDlg::OnInitDialog() {
   CDialogEx::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) {
      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);
      }
   }
    
   // 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
   UpdateData(TRUE);
   if (m_enableDisableVal)
      m_myEditControl.EnableWindow(TRUE);
   else
      m_myEditControl.EnableWindow(FALSE);
   return TRUE; // return TRUE unless you set the focus to a control
}
void CMFCControlManagementDlg::OnSysCommand(UINT nID, LPARAM lParam) {
   if ((nID & 0xFFF0) == IDM_ABOUTBOX) {
      CAboutDlg dlgAbout;
      dlgAbout.DoModal();
   }else {
      CDialogEx::OnSysCommand(nID, lParam);
   }
}

// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.

void CMFCControlManagementDlg::OnPaint() {
   if (IsIconic()) {
      CPaintDC dc(this); // device context for painting
      
      SendMessage(WM_ICONERASEBKGND,
         reinterpret_cast(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 {
      CDialogEx::OnPaint();
   }
}

// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMFCControlManagementDlg::OnQueryDragIcon() {
   return static_cast(m_hIcon);
}

void CMFCControlManagementDlg::OnBnClickedCheck1() {
   // TODO: Add your control notification handler code here
   UpdateData(TRUE);
   if (m_enableDisableVal)
      m_myEditControl.EnableWindow(TRUE);
   else
      m_myEditControl.EnableWindow(FALSE);
}

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

控制管理

步骤6-选中“启用控件”复选框。这将自动启用编辑控件。

控制管理