MFC基础篇
以C++类的形式对WINDOWS API进行封装。
MFC框架理论
关键类
CWinApp:MFC应用程序抽象,管理DocumentTemplate。
CFrameWnd: 框架窗口,负责创建应用主窗口,含标题栏,菜单栏,工具栏,状态栏等 。
CView: 负责展示应用数据,View其实是一个没有边框的窗口, 客户区 。
CDocument: 负责存储应用数据 。
CDocTemplate:DocumentTemplate: 隐藏Boss, 负责管理MainFrame,View和Document。
窗口与窗口对象
关系:
- 每个窗口对象都包含一个窗口
- 窗口对象使用Create方法创建窗口,在Create方法个中将窗口对象与窗口绑定
- 窗口对象的与窗口的生命周期不同,并不同生共死。(menu.Detach()将对象与它绑定在窗口的这一块区域分离(分离窗口对象和窗口))
afx
微软mfx小组。
消息映射
把消息ID和相应函数关联起来。 当这种消息发送出来后,对应的函数就会触发。
1 2 3 4 5
| BEGIN_MESSAGE_MAP(CMFCApplicationView, CView) ON_COMMAND(ID_MSG_DRAW_PEN,&CMFCApplicationView::OnPen) ON_COMMAND(ID_MSG_DRAW_RECT,&CMFCApplicationView::OnRect) ...... END_MESSAGE_MAP()
|
重绘
元文件
元文件(Metafile)是记录所有”绘图指令”的集合,拥有录制,重放的功能。
view文件中的代码示例:
1 2 3 4 5 6 7 8 9 10 11 12
| HMETAFILE metafile;
metafile = m_dcMetaFile.Close();
pDC->PlayMetaFile(metafile);
m_dcMetaFile.Create();
m_dcMetaFile.PlayMetaFile(metafile);
DeleteMetaFile(metafile);
|
兼容设备描述表
兼容设备是一种内存设备,在显示图像的过程中,可以先在内存中准备这些图像,之后可以直接拷贝内存数据到真实的设备中,完成图像的显示。
起到一个二次缓冲的效果
自定义重绘
定义一个类,略……。
文件
文件读写
写入文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| void CMFCApplicationView::OnFileWirte() { CString hello = _T("hello world\n"); CFileDialog fileDlg(FALSE);
if (IDOK==fileDlg.DoModal()) { CString path = fileDlg.GetPathName(); CFile file(path, CFile::modeWrite | CFile::modeCreate); int len = hello.GetLength()* sizeof(TCHAR); file.Write(hello, len); file.Close(); } }
|
读取文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| void CMFCApplicationView::OnFileRead() { CFileDialog fileDlg(TRUE); if (IDOK == fileDlg.DoModal()) { CString path = fileDlg.GetPathName(); CFile file(path, CFile::modeRead); TCHAR* pBuf; int cnt = file.GetLength(); int chars = cnt / sizeof(TCHAR); pBuf = new TCHAR[chars + 1]; file.Read(pBuf, cnt); pBuf[chars] = 0; MessageBox(pBuf); file.Close(); delete[] pBuf; } }
|
类的序列化
类的序列化是将程序中对象以一种二进制格式存放到设备中,如文件/数据库等,以实现”永生”或随意”流动”。
- 类要从CObject派生,或是CObject的派生类派生
- 实现Serialize方法
- 在类声明中使用DECLARE_SERIAL宏
- DECLARE_SERIAL(类名)
- 定义不带参数的构造函数
- 在类实现中添加IMPLEMNET_SERIAL宏
- IMPLEMNET_SERIAL(类名,父类名,版本号)
常用控件
与使用者进行交互。
1 2 3
| 使用 UpdateData(TRUE|FALSE)同步, 默认为True,将控件内容同步到变量,FALSE,将变量同步回控件
|
按钮
Radio Button——单选
Check Box——多选
响应事件,如点击按钮时间.
示例:多选按钮。
1 2 3 4 5 6 7 8
| void CContrlObjectDlg::OnBnClickedButton1() { UpdateData(); CString str; str.Format(_T("上衣=%d\n裤子=%d\n鞋子=%d\n"),m_clothes,m_pants,m_shoes); MessageBox(str); }
|
多选按钮:
![image-20211112181938778](/images/MFC%E5%9F%BA%E7%A1%80%E7%AF%871.assets/image-20211112181938778.png)
文本框和列表
- List Box——列表
- Edit Control——文本框
示例:将文本框的内容放到列表中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void CContrlObjectDlg::OnBnClickedButton2() { CString text; CEdit* edit = (CEdit*)GetDlgItem(IDC_EDIT1); edit->GetWindowText(text); CListBox* list = (CListBox*)GetDlgItem(IDC_LIST1); list->AddString(text); edit->SetWindowText(_T("")); }
|
![image-20211112185648190](/images/MFC%E5%9F%BA%E7%A1%80%E7%AF%871.assets/image-20211112185648190.png)
示例2:
查看在列表中选择了什么
1 2 3 4 5 6 7 8 9 10 11 12
| void CContrlObjectDlg::OnBnClickedButton2() { CString text; CListBox* list = (CListBox*)GetDlgItem(IDC_LIST1); int n = list->GetCurSel(); list->GetText(n,text); MessageBox(text); }
|
下拉列表
类似于ListBox,基本上操作一直,只是ListBox直接展开所有选项,而ComboBox需要点开查看。
示例:
1 2 3 4 5 6 7 8 9 10
| void CContrlObjectDlg::OnBnClickedButton2() { CString text; CComboBox* list = (CComboBox*)GetDlgItem(IDC_COMBO1); int n = list->GetCurSel(); list->GetLBText(n,text); MessageBox(text); }
|
进度条
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| BOOL CContrlObjectDlg::OnInitDialog()中
CProgressCtrl* prog = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);
prog->SetRange(0,100);
prog = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS1); num = prog->GetPos(); prog->SetPos(++num); prog->GetRange(low, high); if (num>= high) { prog->SetPos(low); }
|
图片
1 2 3 4 5 6 7
| BOOL CMFCPicODlg::OnInitDialog()中
BitMap bitmap; m_bitmap.LoadBitmap(IDB_BITMAP1); m_pic.SetBitmap(m_bitmap); bitmap.Detach();
|
表格
例如:Windows文件查看
![image-20211113082415733](/images/MFC%E5%9F%BA%E7%A1%80%E7%AF%871.assets/image-20211113082415733.png)
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| m_list.InsertColumn(0, _T("ADDRESS"), LVCFMT_LEFT, 400); m_list.InsertColumn(0, _T("AGE"), LVCFMT_LEFT, 50); m_list.InsertColumn(0, _T("NAME"), LVCFMT_LEFT, 100); m_list.InsertColumn(0, _T("ID"), LVCFMT_LEFT, 50);
int index; index = m_list.InsertItem(0, _T("0001")); m_list.SetItemText(index, 1, _T("kenny")); m_list.SetItemText(index, 2, _T("26")); m_list.SetItemText(index, 3, _T("Franch"));
index = m_list.InsertItem(1, _T("0002")); m_list.SetItemText(index, 1, _T("olofm")); m_list.SetItemText(index, 2, _T("29")); m_list.SetItemText(index, 3, _T("Sweden"));
|
![image-20211113093242047](/images/MFC%E5%9F%BA%E7%A1%80%E7%AF%871.assets/image-20211113093242047.png)
树
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| HTREEITEM root; HTREEITEM first_sub; HTREEITEM second_sub; m_tree.ModifyStyle(0, TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT); root = m_tree.InsertItem(_T("Root"));
first_sub = m_tree.InsertItem(_T("First_Sub"), root);
m_tree.InsertItem(_T("1"),root); m_tree.InsertItem(_T("2"),root); m_tree.InsertItem(_T("3"),root); m_tree.InsertItem(_T("4"),root);
second_sub = m_tree.InsertItem(_T("Second"),first_sub);
m_tree.InsertItem(_T("5"), second_sub); m_tree.InsertItem(_T("6"), second_sub); m_tree.InsertItem(_T("7"), second_sub); m_tree.InsertItem(_T("8"), second_sub);
|
![image-20211113104231000](/images/MFC%E5%9F%BA%E7%A1%80%E7%AF%871.assets/image-20211113104231000.png)
引入、加载图片
1 2 3 4 5 6 7 8 9 10 11
| m_imgList.Create(32, 32, ILC_MASK | ILC_COLOR32, 2, 4); for (int i = 0; i < 2; i++) { HICON icon = theApp.LoadIcon(IDI_ICON1+i); m_imgList.Add(icon); } m_tree.SetImageList(&m_imgList,TVSIL_NORMAL);
m_tree.InsertItem(_T("1"),1,1,root);
|