什么是MFC?

MFC – Microsoft Foundation Classes 微软基础类库

以C++的类的形式封装了SDK的api,并带有一个应用程序框架

单文档MFC类的继承关系

img

更多MFC类的介绍可以查看官方文档☛[MFC Classes]

更多继承关系可以查看官方文档☛[Hierarchy Chart]

MFC的子类化

MFC的子类化相比较于SDK的子类化实现起来就相对简单一点了,因为MFC的控件已经封装成了一个个类,需要子类化的时候继承原本的类就行。

新建一个类

img

选择需要继承的控件的类,这里我使用Edit作为例子

img

添加消息处理函数

在类视图中右键需要添加消息处理的类,选择类向导,添加WM_CHAR消息处理

img

然后vs就会自动生成代码

img

在这添加自己想要的代码即可

将控件绑定消息处理函数

1
右键控件`->`添加变量

名称处填入一个名字即可

img

点击确定后就可以看见对话框的类中多了一个成员变量

img

接下来包含我们刚刚新建类的头文件

img

再把原本的CEdit替换成我们自己的CMyEdit即可实现子类化

img

控件使用

使用SDK的方法获取编辑框内容

1
2
3
4
5
6
7
8
void CMFCSubClassDlg::OnBnClickedButton1()
{
char szBuff[MAXBYTE] = {0};
// CMFCSubClassDlg中包含了m_hWnd直接使用就行 也可以使用GetSelfHwnd()获取
//::使用sdk中的函数,避免使用类中定义的对象
::GetDlgItemText(m_hWnd,EDT_NAME,szBuff,sizeof(szBuff));
AfxMessageBox(szBuff);
}

使用MFC的方法获取编辑框内容

GetDlgItemText

1
2
3
CString strText;
GetDlgItemText(EDT_NAME,strText);
AfxMessageBox(strText);

GetWindowText

1
2
3
4
CString strText;
CWnd *pEdit = GetDlgItem(EDT_NAME);
pEdit->GetWindowText(strText);
AfxMessageBox(strText);

SendMessage

1
2
3
4
CWnd *pEdit = GetDlgItem(EDT_NAME);
char szBuff[MAXBYTE] = {0};
pEdit->SendMessage(WM_GETTEXT,sizeof(szBuff),(LPARAM)szBuff);
AfxMessageBox(szBuff);

使用MFC中的DDX

1
选中编辑框`->`右键`->`添加变量

类别中选择,设置一个名称即可

img

使用方法:

1
2
3
//UpdateData如果是TRUE,那么则将编辑框里的内容存入CString,如果是FALSE,则将CString里的内容填入编辑框
UpdateData(TRUE);
AfxMessageBox(m_strText);

如果要设置的话:

1
2
m_strText = "测试";
UpdateData(FALSE);

查看控件与变量的绑定

变量和控件是在DoDataExchange这个函数中进行绑定的,可以在函数内查看相关的绑定情况

img

另外也可以在类向导的成员变量中查看

img

单选按钮的使用

一个个判断是否选中

1
2
3
4
5
6
7
8
9
CButton* pRdbMan = (CButton*)GetDlgItem(RDB_MAN);
CButton* pRdbWomen = (CButton*)GetDlgItem(RDB_WOMEN);
CButton* pRdbOther = (CButton*)GetDlgItem(RDB_OTHER);
CButton* pRdbUnknown = (CButton*)GetDlgItem(RDB_UNKNOWN);

if (pRdbMan->GetCheck() == 1)
{
AfxMessageBox("男");
}

使用DDX

开启单选按钮Group属性即可对按钮进行DDX绑定

img

将单选按钮绑定为int类型

img

判断代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
UpdateData(TRUE);
switch (m_nGender)
{
case 0:
AfxMessageBox("男");
break;
case 1:
AfxMessageBox("女");
break;
case 2:
AfxMessageBox("其他");
break;
case 3:
AfxMessageBox("未知");
break;
}

复选按钮的使用

将复选按钮绑定为BOOL类型

img

判断代码

1
2
3
4
5
6
7
8
9
10
11
12
13
UpdateData(TRUE);
if (m_bCode)
{
AfxMessageBox("code");
}
if (m_bDebug)
{
AfxMessageBox("Debug");
}
if (m_bReverse)
{
AfxMessageBox("Reverse");
}

组合框的使用

绑定组合框

img

初始化

1
2
3
4
5
6
7
// TODO: 在此添加额外的初始化代码
m_ComboText.AddString("选项1");
m_ComboText.AddString("选项2");
m_ComboText.AddString("选项3");
m_ComboText.AddString("选项4");
m_ComboText.AddString("选项5");
m_ComboText.AddString("选项6");

组合框默认是开启排序的,如果不需要使用可以关闭

img

设置默认值

1
m_ComboText.SetCurSel(0);

获取选中内容

1
2
3
4
int nCurSel = m_ComboText.GetCurSel();
CString StrLoc;
m_ComboText.GetLBText(nCurSel,StrLoc);
AfxMessageBox(StrLoc);

List Control

添加变量

img

初始化

1
2
3
4
5
6
7
8
9
10
11
//设置风格 选中一行

m_lstcTextInfo.SetExtendedStyle(m_lstcTextInfo.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

//添加表头
int nColIdx = 0;
m_lstcTextInfo.InsertColumn(nColIdx++, "学号");
m_lstcTextInfo.InsertColumn(nColIdx++, "姓名");
m_lstcTextInfo.InsertColumn(nColIdx++, "性别");
m_lstcTextInfo.InsertColumn(nColIdx++, "爱好");
m_lstcTextInfo.InsertColumn(nColIdx++, "班级");

自动调整列宽

1
2
3
4
5
6
//自动调整列宽
CHeaderCtrl* pHdrCtr = m_lstcTextInfo.GetHeaderCtrl();
for (int i = 0; i < pHdrCtr->GetItemCount(); ++i)
{
m_lstcTextInfo.SetColumnWidth(i, LVSCW_AUTOSIZE_USEHEADER);
}

插入内容

1
2
3
4
5
6
7
int nItemIdx = 0;//行数
int nColIdx = 0;
m_lstcTextInfo.InsertItem(nItemIdx, "1001");
m_lstcTextInfo.SetItemText(nItemIdx, ++nColIdx, "小红");
m_lstcTextInfo.SetItemText(nItemIdx, ++nColIdx, "女");
m_lstcTextInfo.SetItemText(nItemIdx, ++nColIdx, "debug");
m_lstcTextInfo.SetItemText(nItemIdx++, ++nColIdx, "1班");

获取选中内容

1
2
3
4
5
6
7
8
9
10
int nIdx = m_lstcTextInfo.GetSelectionMark();
int nSubItemText = 0;
CString strID = m_lstcTextInfo.GetItemText(nIdx, nSubItemText++);
CString strName = m_lstcTextInfo.GetItemText(nIdx, nSubItemText++);
CString strGender = m_lstcTextInfo.GetItemText(nIdx, nSubItemText++);
CString strHobby = m_lstcTextInfo.GetItemText(nIdx, nSubItemText++);
CString strClass = m_lstcTextInfo.GetItemText(nIdx, nSubItemText++);
CString strFmt;
strFmt.Format("索引%d 学号%s 姓名%s 性别%s 爱好%s 班级%s ", nIdx, strID, strName, strGender, strHobby, strClass);
AfxMessageBox(strFmt);

删除内容

1
2
int nIdx = m_lstcTextInfo.GetSelectionMark();
m_lstcTextInfo.DeleteItem(nIdx);

双缓冲绘图

双缓冲绘图的步骤

  • 1.创建内存DC(兼容DC)
  • 2.创建兼容位图
  • 3.在内存绘制图形
  • 4.将图片从内存贴到客户区