1 新建MFC程序,选择单文档视图,并取消选择文档视图结构
2 默认CMainFrame建的视图是CChildView,这是个普通的视图,屏蔽掉下面的代码
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)里面的
// 创建一个视图以占用框架的工作区
/*if (!m_wndView.Create(nullptr, nullptr, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, nullptr))
{
TRACE0("未能创建视图窗口\n");
return -1;
}*/
void CMainFrame::OnSetFocus(CWnd* /*pOldWnd*/)
{
// 将焦点前移到视图窗口
/*m_wndView.SetFocus();*/
}
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
// 让视图第一次尝试该命令
/*if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;*/
// 否则,执行默认处理
return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
3 在项目上右键,打开类向导,点击添加类右边的向下箭头,选择MFC类(注意,必须通过类向导创建MFC类才可以,手动创建无法走到OnInitUpdate)
4 输入视图类名称,选择基类为CListView
5 在CMainView.h里面添加代码
#include <afxcview.h>
6 在CMainView上面右键选择类向导,添加虚函数OnInitUpdate
7 修改代码
void CMainView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
// TODO: 在此添加专用代码和/或调用基类
CListCtrl& lst = GetListCtrl();
lst.ModifyStyle(0, LVS_REPORT|LVS_SHOWSELALWAYS);
lst.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
lst.InsertColumn(0, _T("工号"), 0, 200);
lst.InsertColumn(1, _T("姓名"), 0, 200);
lst.InsertColumn(2, _T("部门"), 0, 200);
}
8 修改重要的nt CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct),增添视图
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
CCreateContext cc;
cc.m_pNewViewClass = RUNTIME_CLASS(CMainView);
m_pMainView = (CMainView*)CreateView(&cc);
// 创建一个视图以占用框架的工作区
/*if (!m_wndView.Create(nullptr, nullptr, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, nullptr))
{
TRACE0("未能创建视图窗口\n");
return -1;
}*/
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("未能创建工具栏\n");
return -1; // 未能创建
}
if (!m_wndStatusBar.Create(this))
{
TRACE0("未能创建状态栏\n");
return -1; // 未能创建
}
m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
// TODO: 如果不需要可停靠工具栏,则删除这三行
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
//FloatControlBar(&m_wndToolBar, CPoint(200,200));
return 0;
}
9 在CMainFrame.cpp里面添加包含
#include "CMainView.h"
10 在编辑菜单栏下面添加菜单
11 添加消息处理函数
12 新建对话框,添加成员变量,注意对话框的返回值就是EndDialog的参数
#pragma once
// CAddDlg 对话框
class CAddDlg : public CDialogEx
{
DECLARE_DYNAMIC(CAddDlg)
public:
CAddDlg(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CAddDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DLG_ADD };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
BOOL m_bModify;
CString m_szDept;
CString m_szName;
CString m_szNum;
afx_msg void OnBnClickedBtnOk();
afx_msg void OnBnClickedBtnCancel();
virtual BOOL OnInitDialog();
};
// CAddDlg.cpp: 实现文件
//
#include "pch.h"
#include "Demo.h"
#include "CAddDlg.h"
#include "afxdialogex.h"
// CAddDlg 对话框
IMPLEMENT_DYNAMIC(CAddDlg, CDialogEx)
CAddDlg::CAddDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_DLG_ADD, pParent)
, m_szDept(_T(""))
, m_szName(_T(""))
, m_szNum(_T(""))
,m_bModify(FALSE)
{
}
CAddDlg::~CAddDlg()
{
}
void CAddDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDT_DEPT, m_szDept);
DDX_Text(pDX, IDC_EDT_NAME, m_szName);
DDX_Text(pDX, IDC_EDT_NUM, m_szNum);
}
BEGIN_MESSAGE_MAP(CAddDlg, CDialogEx)
ON_BN_CLICKED(IDC_BTN_OK, &CAddDlg::OnBnClickedBtnOk)
ON_BN_CLICKED(IDC_BTN_CANCEL, &CAddDlg::OnBnClickedBtnCancel)
END_MESSAGE_MAP()
// CAddDlg 消息处理程序
void CAddDlg::OnBnClickedBtnOk()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData();
EndDialog(IDOK);
}
void CAddDlg::OnBnClickedBtnCancel()
{
// TODO: 在此添加控件通知处理程序代码
EndDialog(IDCANCEL);
}
BOOL CAddDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
if (m_bModify)
{
SetWindowText(_T("Modify"));
GetDlgItem(IDC_EDT_NUM)->EnableWindow(FALSE);
}
// TODO: 在此添加额外的初始化
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
13 实现Add菜单的功能
void CMainView::OnEdtAdd()
{
CAddDlg dlg;
if (IDCANCEL == dlg.DoModal())
{
return;
}
CListCtrl& list = GetListCtrl();
int i = list.GetItemCount();
list.InsertItem(i, dlg.m_szNum);
list.SetItemText(i, 1, dlg.m_szName);
list.SetItemText(i, 2, dlg.m_szDept);
}
14 同上增加删除菜单,实现功能
oid CMainView::OnEdtDelete()
{
CListCtrl& list = GetListCtrl();
if (!list.GetSelectedCount()<0)
{
AfxMessageBox(_T("请选中一条记录再删除"));
return;
}
int nSel = list.GetSelectionMark();
if (IDYES == AfxMessageBox(_T("确定删除该条记录吗?"),MB_YESNO))
{
list.DeleteItem(nSel);
}
}
15 增加修改菜单,实现功能
void CMainView::OnEdtModify()
{
CListCtrl& list = GetListCtrl();
if (!list.GetSelectedCount() < 0)
{
AfxMessageBox(_T("请选中一条记录再修改"));
return;
}
int nSel = list.GetSelectionMark();
CAddDlg dlg;
dlg.m_bModify = TRUE;
dlg.m_szNum = list.GetItemText(nSel, 0);
dlg.m_szName = list.GetItemText(nSel, 1);
dlg.m_szDept = list.GetItemText(nSel, 2);
if (IDCANCEL == dlg.DoModal())
{
return;
}
list.SetItemText(nSel,1, dlg.m_szName);
list.SetItemText(nSel,2, dlg.m_szDept);
}
16 通过PreCreateWindow来修改框架的位置,大小和样式
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: 在此处通过修改
//cs.x = 100;
//cs.y = 100;
cs.cx = 800;
cs.cy = 600;
// CREATESTRUCT cs 来修改窗口类或样式
cs.style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX);
/*cs.lpszClass = AfxRegisterWndClass(0);*/
return TRUE;
}
17 修改OnSetFocus程序
void CMainFrame::OnSetFocus(CWnd* /*pOldWnd*/)
{
// 将焦点前移到视图窗口
if (m_pMainView)
{
m_pMainView->SetFocus();
}
}
18 双击回调消息
void CMainView::OnNMDblclk(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
OnEdtModify();
*pResult = 0;
}