补发:2021-11-13
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和相应函数关联起来。 当这种消息发送出来后,对应的函数就会触发。
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文件中的代码示例:
//声明一个Metefile的对象
HMETAFILE metafile;
//结束录制,保存文件
metafile = m_dcMetaFile.Close();
//重放文件
pDC->PlayMetaFile(metafile);
//准备一个新的录制
m_dcMetaFile.Create();
//在新的录制中重放旧元文件
m_dcMetaFile.PlayMetaFile(metafile);
//删除元文件
DeleteMetaFile(metafile);
//无效界面-请求重绘
Invalidate();
兼容设备描述表
兼容设备是一种内存设备,在显示图像的过程中,可以先在内存中准备这些图像,之后可以直接拷贝内存数据到真实的设备中,完成图像的显示。
起到一个二次缓冲的效果
自定义重绘
定义一个类,略......。
文件
文件读写
写入文件
void CMFCApplicationView::OnFileWirte()
{
// TODO: 在此添加命令处理程序代码
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();
}
}
读取文件
void CMFCApplicationView::OnFileRead()
{
// TODO: 在此添加命令处理程序代码
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(类名,父类名,版本号)
常用控件
与使用者进行交互。
- 获得控件
GetDlgItem(控件ID)获取相应的控件
- 通过绑定控件和变量
使用
UpdateData(TRUE|FALSE)同步,
默认为True,将控件内容同步到变量,FALSE,将变量同步回控件
按钮
Radio Button——单选
Check Box——多选
响应事件,如点击按钮时间.
示例:多选按钮。
void CContrlObjectDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData();//同步控件与变量
CString str;
str.Format(_T("上衣=%d\n裤子=%d\n鞋子=%d\n"),m_clothes,m_pants,m_shoes);
MessageBox(str);
}
多选按钮:
文本框和列表
- List Box——列表
- Edit Control——文本框
示例:将文本框的内容放到列表中
void CContrlObjectDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
//获取文本框中的内容
CString text;
//得到文本框对象
CEdit* edit = (CEdit*)GetDlgItem(IDC_EDIT1);
//将文本框中的文字存放到text中
edit->GetWindowText(text);
//得到列表对象
CListBox* list = (CListBox*)GetDlgItem(IDC_LIST1);
//将文本框中的文字添加到列表框中
list->AddString(text);
//清空文本框的输入框
edit->SetWindowText(_T(""));
}
示例2:
查看在列表中选择了什么
void CContrlObjectDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
//储存获取的内容
CString text;
CListBox* list = (CListBox*)GetDlgItem(IDC_LIST1);
//获取当前在列表中的选择,返回一个整型,该选项在列表中的位置
int n = list->GetCurSel();
//返回选项放到text中
list->GetText(n,text);
MessageBox(text);
}
下拉列表
- ComboBox——下拉列表
类似于ListBox,基本上操作一直,只是ListBox直接展开所有选项,而ComboBox需要点开查看。
示例:
void CContrlObjectDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
//储存获取的内容
CString text;
CComboBox* list = (CComboBox*)GetDlgItem(IDC_COMBO1);
int n = list->GetCurSel();
list->GetLBText(n,text);
MessageBox(text);
}
进度条
- Progress Control——进度条
示例:
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);
}
图片
- Picture Control——图片
BOOL CMFCPicODlg::OnInitDialog()中
//例如:加载bitmap,以局部变量的方式
BitMap bitmap;
m_bitmap.LoadBitmap(IDB_BITMAP1);
m_pic.SetBitmap(m_bitmap);
bitmap.Detach();
表格
- List Control
例如:Windows文件查看
示例:
//绘制表头
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"));
树
- Tree Control
示例:
HTREEITEM root;
HTREEITEM first_sub;
HTREEITEM second_sub;
m_tree.ModifyStyle(0, TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT);
root = m_tree.InsertItem(_T("Root"));
//root的子节点
first_sub = m_tree.InsertItem(_T("First_Sub"), root);
//与first同级的四个
m_tree.InsertItem(_T("1"),root);
m_tree.InsertItem(_T("2"),root);
m_tree.InsertItem(_T("3"),root);
m_tree.InsertItem(_T("4"),root);
//first的子结点
second_sub = m_tree.InsertItem(_T("Second"),first_sub);
//second的四个子节点
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);
引入、加载图片
//当前2张,还能加4张
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);
//这两个1分别代表的属性
//分别是:未选中时显示哪张图片,被选中时显示哪在张。
m_tree.InsertItem(_T("1"),1,1,root);