Windows 库存管理软件开始
MFC 配合 C++, 就像豆浆配油条, 如同行云流水啊...
MFC使用概论
MFC并没有想象中的那么神秘
不要看VS自动生成一大堆代码, 就以为它多么"高大上"
它其实就是Win32封装成了类, 和C++类是一样用的使用VS生成一个基于对话框的MFC应用程序
VS自动帮我们生成了2个类, 一个是 C___App, 一个是 C___Dlg
C___App
- 它是我们的应用程序类
它继承自
CWinApp类- 可以看到, 我们的
CWinApp类具有m_hInstance - 具有
m_lpCmdLine - 具有
m_nCmdShow - 具有
m_pszAppName - 哎, 是不是很眼熟?
- 回想一下
Win32 里的 WinMain 函数的参数!!!
- 可以看到, 我们的
看到其中的
InitInstance函数- 它其实就是
MFC中的入口函数 - 和 WinMain 一样, 是
被动调用的.
- 它其实就是
C___Dlg
- 它是我们的应用程序主对话框类
它继承自
CDialogEx类它继承自
CDialog类它继承自
CWnd类- 这是 MFC 中的窗口的基类
- 抽象了一些窗口的共性
- 它是对话框类, 具有对话框的特点
- 它是一个扩展的对话框类, 为对话框增加了更多的特性
它具有
OnInitDialog函数- 这个函数会初始化对话框的一些设置和控件
综上分析, 基本上, MFC就是一个从Win32(C语法编程)变成了C++(面向对象)的编程
被动调用
在MFC中, 有很多 OnXXXX 的方法
比如, OnInitDialog, OnPaint, OnTimer, OnClose 等等
它们表示在接收到XXXX消息的时候去执行的方法
比如,
在 WM_PAINT 的时候, 会去执行 OnPaint 方法
在 WM_TIMER 的时候, 会去执行 OnTimer 方法
它们其实本质上都是回调函数
通过
DECLARE_MESSAGE_MAP,BEGIN_MESSAGE_MAP,END_MESSAGE_MAP三个宏之间的配合
加上宏替换, 就形成了MFC配合VS自动生成消息映射的功能
它们都是被调用的
ListView操作
初始化表头
// 初始化列
// 由于第一列不会对齐 所以先随意插入一列 然后在干掉
CRect rect = { 0 };
m_listInfo.GetWindowRect(&rect);
INT nListWidth = rect.right - rect.left;
m_listInfo.InsertColumn(0, L"", LVCFMT_CENTER, 0);
m_listInfo.InsertColumn(1, L"品名", LVCFMT_CENTER, nListWidth / 0.2);
m_listInfo.InsertColumn(2, L"数量", LVCFMT_CENTER, nListWidth / 0.2);
m_listInfo.InsertColumn(3, L"厂商", LVCFMT_CENTER, nListWidth / 0.2);
m_listInfo.InsertColumn(4, L"价值", LVCFMT_CENTER, nListWidth / 0.2);
m_listInfo.InsertColumn(5, L"更新时间", LVCFMT_CENTER, nListWidth / 0.2);
m_listInfo.DeleteColumn(0);设置样式
// 整行选中 + 网格线 + 跟踪选中
DWORD dwListStyle = m_listInfo.GetStyle();
dwListStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_TRACKSELECT;
m_listInfo.SetExtendedStyle(dwListStyle);注意, 一定要
先获取, 在设置
不然, 原来有的样式就会被干掉
响应右键消息
- 选中 ListView
- 右键, 添加事件处理程序
- 找到
NM_RCLICK消息, 选择好要生成到的类 - 添加编辑
添加右键菜单
- 首先, 在资源视图中增加菜单
- 在响应的右键消息中, 实现如下代码
// 获取一个 CMenu 对象
CMenu menu;
// 加载指定的菜单
menu.LoadMenu(IDR_LIST_POPUP_MENU);
// 获取这个 CMenu 对象的第一个子菜单
// 因为我们现在获取的menu是最顶上的菜单
// 而我们需要弹出的, 是顶级菜单的菜单项
// 就比如, 文件菜单包括了 打开 和 关闭 两个菜单项
// 现在, menu 指向的是 文件 菜单
// 如果弹出 menu, 就只会显示 文件 菜单
// 而实际上, 我们要显示 打开 和 关闭 这两个菜单项
CMenu* popup = menu.GetSubMenu(0);
// 获取鼠标位置
CPoint point;
GetCursorPos(&point);
// 弹出菜单显示
popup->TrackPopupMenu(TPM_RIGHTBUTTON | TPM_LEFTALIGN, point.x, point.y, this);菜单操作
响应菜单项消息
- 打开资源视图, 找到菜单并打开, 展开到菜单项并选中
- 右键菜单项, 选择 "添加事件处理程序"
- 选择
COMMAND消息, 选择实现类 - 添加编辑
修改菜单项ID
- 打开资源视图, 找到菜单并打开
- 右键空白处, 选择 "编辑ID" 即可方便的更改
修改菜单ID
注: 菜单ID指的是新插入的菜单的类似IDR_MENU1这种ID
- 打开
属性窗口, 不要关闭. (或者不打开也行) - 打开
资源视图,选中要修改ID的菜单 切换到
属性窗口, 修改ID即可.- 如果没打开, 可点击
视图菜单, 找到属性窗口, 或直接按下快捷键F4
- 如果没打开, 可点击
添加一个窗口
- 打开
资源视图 - 插入Dialog
- 设计这个Dialog
- 右键Dialog, 选择"添加类"为这个Dialog生成类
模态对话框显示
CXXXDlg dlg;
dlg.DoModel();非模态对话框显示(多个)
CXXXDlg* dlg = new CXXXDlg;
dlg.Create(IDD_DIALOG_XXX);
dlg.ShowWindow(SW_SHOW);需要注意的是, 对 CXXXDlg 要实现特定的方法
必须实现虚函数
OnCancel- 必须调用
DestoryWindow - 必须
不能调用 CDialogEx::OnCancel();
- 必须调用
必须实现虚函数
PostNcDestroy- 调用
delete this
- 调用
void CXXXXDlg::PostNcDestroy()
{
// TODO: 在此添加专用代码和/或调用基类
delete this;
CDialogEx::PostNcDestroy();
}
void CXXXXDlg::OnCancel()
{
// TODO: 在此添加专用代码和/或调用基类
this->DestroyWindow();
//CDialogEx::OnCancel();
}非模态对话框显示(单个)
单个就不用如此麻烦了
直接在 类成员变量 中定义即可.
只要保证不内存泄露, 怎么都好说.
theApp对象
MFC提供了一个全局的 C___App 类型的 theApp 对象
使用它可以用来组织我们当前的程序中的窗口, 逻辑, 数据
要善于用 theApp 对象来管理我们的程序
未完待续...
如有错误,请提出指正!谢谢.
本文由 花心胡萝卜 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: 2017-05-15 at 04:01 pm