综合案例
- 通过MFC向导创建综合案例(销售信息管理系统)项目。
项目总体框架
整个项目分为登录界面、主界面。而主界面分裂成两个界面显示,分别为左侧选择界面和右侧显示界面。功能上分别有个人信息管理、销售管理窗口、库存信息窗口、库存添加窗口、库存删除窗口以及菜单栏。
文件处理
- 项目中使用到将数据保存到文件进行保存的功能,这部分设计成一个单独的文件处类CInfoFile。
在解决方案中添加类–>CInfoFile。
- CInfoFole.h
#pragma once #include <list> #include <fstream> #include <iostream> #include <string> #include "pch.h" #define _F_LOGIN "./login.ini" #define _F_STOCK "./stock.txt" struct msg { int id; std::string name; int price; int num; }; class CInfoFile { public: CInfoFile(); ~CInfoFile(); //读取登录信息 void ReadLogin(CString& name, CString& pwd); //修改密码 void WritePwd(char* name, char* pwd); //读取商品数据 void ReadDocline(); //商品写入文件 void WriteDocline(); //添加新商品 void AddLine(CString name, int num, int price); std::list<msg> ls; //存储商品容器 int num; //记录商品个数 };
- CInfoFole.cpp
#include "pch.h" #include "CInfoFile.h" CInfoFile::CInfoFile() { } CInfoFile::~CInfoFile() { } void CInfoFile::ReadLogin(CString& name, CString& pwd) { std::ifstream ifs;//创建文件输入对象 ifs.open(_F_LOGIN);//打开文件 char buf[1024] = { 0 }; ifs.getline(buf, sizeof(buf));//读取第一行 name = CString(buf);//char * 转为CString memset(buf, 0, sizeof(buf));//清空buf ifs.getline(buf, sizeof(buf)); pwd = CString(buf); ifs.close();//关闭文件 } void CInfoFile::WritePwd(char* name, char* pwd) { std::ofstream ofs;//创建文件输出对象 ofs.open(_F_LOGIN);//打开文件 ofs << name << std::endl;//将name写入文件并换行 ofs << pwd << std::endl;//将pwd写入文件并换行 ofs.close();//关闭文件 } void CInfoFile::ReadDocline() { std::ifstream ifs(_F_STOCK);//输入方式打开文件 char buf[1024] = { 0 }; num = 0;//初始化商品数目 ls.clear();//初始化容器 //取出表头 ifs.getline(buf, sizeof(buf)); while (!ifs.eof())//循环执行到文件结尾 { msg tmp;//声明暂存变量 ifs.getline(buf, sizeof(buf)); num++; char* set = strtok(buf, "|");//以|为分隔符切割字符串 if (set != NULL) { tmp.id = std::atoi(set);//第一个为商品id } else { break;//找不到分隔符则跳出循环 } set = strtok(NULL, "|"); tmp.name = set;//商品名称 set = strtok(NULL, "|"); tmp.price = std::atoi(set);//商品价格 set = strtok(NULL, "|"); tmp.num = std::atoi(set);//商品数目 ls.push_back(tmp); } ifs.close();//关闭文件 } void CInfoFile::WriteDocline() { std::ofstream ofs(_F_STOCK);//输出方式打开文件 if (ls.size() > 0) { ofs << "商品ID|商品名称|商品价格|库存" << std::endl;//写入表头 //通过迭代器写入内容 for (auto it = ls.begin(); it != ls.end(); ++it) { ofs << it->id << "|"; ofs << it->name << "|"; ofs << it->price << "|"; ofs << it->num << std::endl; } } ofs.close();//关闭文件 } void CInfoFile::AddLine(CString name, int num, int price) { msg tmp; if (ls.size() > 0) { if (!name.IsEmpty() && num > 0 && price > 0) { tmp.id = ls.size() + 1; CStringA str; str = name; tmp.name = str.GetBuffer(); tmp.num = num; tmp.price = price; ls.push_back(tmp);//放在链表后 } } }
登录对话框
添加对话框资源(ID修改为DIALOG_LOGIN),添加所需控件:
选中对话框 -> 右击 -> 添加类 -> 类名:CLoginDlg,添加关联变量。
具体功能实现:
- 需要重写OnInitDialog
- 在应用程序类CSaleSystemApp的InitInstance() 里面的APP 创建之前创建登陆对话框。
CLoginDlg dlg; //创建登陆对话框,需要头文件#include "LoginDlg.h" dlg.DoModal(); //以模态方式运行
- 登录按钮功能实现。
- CLoginDlg.h
#pragma once // CLoginDlg 对话框 class CLoginDlg : public CDialogEx { DECLARE_DYNAMIC(CLoginDlg) public: CLoginDlg(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CLoginDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_LOGIN }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() private: CString m_user; CString m_pwd; public: virtual BOOL OnInitDialog(); afx_msg void OnBnClickedButton2(); afx_msg void OnBnClickedButton1(); afx_msg void OnClose(); virtual void OnOK(); };
- CLoginDlg.cpp
// CLoginDlg.cpp: 实现文件 // #include "pch.h" #include "SaleSystem.h" #include "CLoginDlg.h" #include "afxdialogex.h" #include "CInfoFile.h" // CLoginDlg 对话框 IMPLEMENT_DYNAMIC(CLoginDlg, CDialogEx) CLoginDlg::CLoginDlg(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_LOGIN, pParent) , m_user(_T("")) , m_pwd(_T("")) { } CLoginDlg::~CLoginDlg() { } void CLoginDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_user); DDX_Text(pDX, IDC_EDIT2, m_pwd); } BEGIN_MESSAGE_MAP(CLoginDlg, CDialogEx) ON_BN_CLICKED(IDC_BUTTON2, &CLoginDlg::OnBnClickedButton2) ON_BN_CLICKED(IDC_BUTTON1, &CLoginDlg::OnBnClickedButton1) ON_WM_CLOSE() END_MESSAGE_MAP() // CLoginDlg 消息处理程序 BOOL CLoginDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // TODO: 在此添加额外的初始化 m_user = TEXT("斧头帮帮主"); m_pwd = TEXT("123456"); UpdateData(FALSE);//内容更新到对应控件 return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } void CLoginDlg::OnBnClickedButton2() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE);//更新控件数据到数据区 CInfoFile file; CString user, pwd; user = TEXT("斧头帮帮主"); pwd = TEXT("123456"); //file.ReadLogin(user, pwd); if (m_user == user) { if (m_pwd != pwd) { MessageBox(TEXT("密码错误")); m_user.Empty(); m_pwd.Empty(); } else { CDialogEx::OnOK(); } } else { MessageBox(TEXT("用户不存在")); m_user.Empty(); m_pwd.Empty(); } } void CLoginDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 exit(0); } void CLoginDlg::OnClose() { // TODO: 在此添加消息处理程序代码和/或调用默认值 exit(0); //CDialogEx::OnClose(); } void CLoginDlg::OnOK() { // TODO: 在此添加专用代码和/或调用基类 //CDialogEx::OnOK(); }
静态拆分窗口
实现主界面的拆分显示,左侧选择界面显示(CSelectView)和右侧显示界面(CDisplayView)。
CSelectView继承于CTreeView,CDispalyView继承于CFormView。
- 在CMainFrame类中,声明CSplitterWnd类型的对象:
private: CSplitterWnd m_spliter; // 切分窗口类对象
- 重写框架类CMainFrame的OnCreateClient函数
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { // TODO: 在此添加专用代码和/或调用基类 //return CFrameWnd::OnCreateClient(lpcs, pContext); //静态拆分窗口 m_spliter.CreateStatic(this, 1, 2); m_spliter.CreateView(0, 0, RUNTIME_CLASS(CSelectView), CSize(200, 500), pContext); m_spliter.CreateView(0, 1, RUNTIME_CLASS(CDisplayView), CSize(600, 500), pContext); return TRUE; }
- 显示如下:
左侧选择界面树视图实现
- 添加树视图图标。
- CSelectView类中声明相应变量:
CTreeCtrl *m_treeCtrl; //树控件 CImageList m_imageList; //图标列表
- 重写CSelectView的OnInitUpdate函数
void CSelectView::OnInitialUpdate() { CTreeView::OnInitialUpdate(); // TODO: 在此添加专用代码和/或调用基类 HICON icon = AfxGetApp()->LoadIconW(IDI_ICON_RE); //图片列表的串讲,指定图标的宽度和高度 m_imageList.Create(30, 30, ILC_COLOR32, 1, 1); m_imageList.Add(icon); //获取树视图中的控件 m_treeCtrl = &GetTreeCtrl(); //树控件设置图片列表 m_treeCtrl->SetImageList(&m_imageList, TVSIL_NORMAL); //树控件设置节点 m_treeCtrl->InsertItem(TEXT("个人信息"), 0, 0, NULL); m_treeCtrl->InsertItem(TEXT("销售管理"), 0, 0, NULL); m_treeCtrl->InsertItem(TEXT("库存信息"), 0, 0, NULL); m_treeCtrl->InsertItem(TEXT("库存添加"), 0, 0, NULL); m_treeCtrl->InsertItem(TEXT("库存删除"), 0, 0, NULL); }
功能节点消息处理
当左侧窗口点击树节点,会发送对应的消息给mainframe,主窗口接收到对应消息后会进行相应处理,将右侧窗口挂载成不同的显示界面。
- 树节点改变响应处理:
void CSelectView::OnTvnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) { LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 //获取当前项目 HTREEITEM item = m_treeCtrl->GetSelectedItem(); //根据所选项目获取内容 CString str = m_treeCtrl->GetItemText(item); //MessageBox(str); if (str == TEXT("个人信息")) { ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_A, (WPARAM)NM_A, (LPARAM)0); } else if (str == TEXT("销售管理")) { ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_B, (WPARAM)NM_B, (LPARAM)0); } else if (str == TEXT("库存信息")) { ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_C, (WPARAM)NM_C, (LPARAM)0); } else if (str == TEXT("库存添加")) { ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_D, (WPARAM)NM_D, (LPARAM)0); } else if (str == TEXT("库存删除")) { ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_E, (WPARAM)NM_E, (LPARAM)0); } *pResult = 0; }
- 在CMainFrame.h中声明了对应的消息宏:
#define NM_A (WM_USER + 100) #define NM_B (WM_USER + 101) #define NM_C (WM_USER + 102) #define NM_D (WM_USER + 103) #define NM_E (WM_USER + 104)
- 在CMainFrame.cpp中的宏节点声明对应的消息处理声明:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_WM_CREATE() ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook) ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnUpdateApplicationLook) ON_WM_SETTINGCHANGE() //自定义消息 ON_MESSAGE(NM_A, OnMyChange) ON_MESSAGE(NM_B, OnMyChange) ON_MESSAGE(NM_C, OnMyChange) ON_MESSAGE(NM_D, OnMyChange) ON_MESSAGE(NM_E, OnMyChange) ON_COMMAND(ID_EDIT_UNDO, &CMainFrame::OnEditUser) ON_COMMAND(ID_EDIT_CUT, &CMainFrame::OnEditSell) ON_COMMAND(ID_EDIT_COPY, &CMainFrame::OnEditCopy) ON_COMMAND(ID_EDIT_PASTE, &CMainFrame::OnEditAdd) ON_COMMAND(ID_32771, &CMainFrame::OnEditDel) END_MESSAGE_MAP()
- 自定义对应的消息处理函数
//自定义处理消息函数 LRESULT CMainFrame::OnMyChange(WPARAM wParam, LPARAM lParam) { CCreateContext Context; switch (wParam) { case NM_A: { //MessageBox(TEXT("个人信息界面显示")); //界面挂载 Context.m_pNewViewClass = RUNTIME_CLASS(CUserDlg); Context.m_pCurrentFrame = this; Context.m_pLastView = (CFormView*)m_spliter.GetPane(0, 1); m_spliter.DeleteView(0, 1); m_spliter.CreateView(0, 1, RUNTIME_CLASS(CUserDlg), CSize(600, 500), &Context); CUserDlg* pNewView = (CUserDlg*)m_spliter.GetPane(0, 1); m_spliter.RecalcLayout(); pNewView->OnInitialUpdate(); m_spliter.SetActivePane(0, 1); } break; case NM_B: { Context.m_pNewViewClass = RUNTIME_CLASS(CSellDlg); Context.m_pCurrentFrame = this; Context.m_pLastView = (CFormView*)m_spliter.GetPane(0, 1); m_spliter.DeleteView(0, 1); m_spliter.CreateView(0, 1, RUNTIME_CLASS(CSellDlg), CSize(600, 0), &Context); CSellDlg* pNewView = (CSellDlg*)m_spliter.GetPane(0, 1); m_spliter.RecalcLayout(); pNewView->OnInitialUpdate(); m_spliter.SetActivePane(0, 1); } break; case NM_C: { Context.m_pNewViewClass = RUNTIME_CLASS(CInfoDlg); Context.m_pCurrentFrame = this; Context.m_pLastView = (CFormView*)m_spliter.GetPane(0, 1); m_spliter.DeleteView(0, 1); m_spliter.CreateView(0, 1, RUNTIME_CLASS(CInfoDlg), CSize(600, 0), &Context); CInfoDlg* pNewView = (CInfoDlg*)m_spliter.GetPane(0, 1); m_spliter.RecalcLayout(); pNewView->OnInitialUpdate(); m_spliter.SetActivePane(0, 1); } break; case NM_D: { Context.m_pNewViewClass = RUNTIME_CLASS(CAddDlg); Context.m_pCurrentFrame = this; Context.m_pLastView = (CFormView*)m_spliter.GetPane(0, 1); m_spliter.DeleteView(0, 1); m_spliter.CreateView(0, 1, RUNTIME_CLASS(CAddDlg), CSize(600, 0), &Context); CAddDlg* pNewView = (CAddDlg*)m_spliter.GetPane(0, 1); m_spliter.RecalcLayout(); pNewView->OnInitialUpdate(); m_spliter.SetActivePane(0, 1); } break; case NM_E: { Context.m_pNewViewClass = RUNTIME_CLASS(CDelDlg); Context.m_pCurrentFrame = this; Context.m_pLastView = (CFormView*)m_spliter.GetPane(0, 1); m_spliter.DeleteView(0, 1); m_spliter.CreateView(0, 1, RUNTIME_CLASS(CDelDlg), CSize(600, 0), &Context); CDelDlg* pNewView = (CDelDlg*)m_spliter.GetPane(0, 1); m_spliter.RecalcLayout(); pNewView->OnInitialUpdate(); m_spliter.SetActivePane(0, 1); } break; default: break; } /* if (wParam == NM_A) { //MessageBox(TEXT("个人信息界面显示")); //界面挂载 Context.m_pNewViewClass = RUNTIME_CLASS(CUserDlg); Context.m_pCurrentFrame = this; Context.m_pLastView = (CFormView*)m_spliter.GetPane(0, 1); m_spliter.DeleteView(0, 1); m_spliter.CreateView(0, 1, RUNTIME_CLASS(CUserDlg), CSize(600, 500), &Context); CUserDlg* pNewView = (CUserDlg*)m_spliter.GetPane(0, 1); m_spliter.RecalcLayout(); pNewView->OnInitialUpdate(); m_spliter.SetActivePane(0, 1); } */ return LRESULT(); }
个人信息管理窗口
- 添加对话框资源(ID修改为DIALOG_USER),添加所需控件,在窗口属性中,Border改为None,Style改为Child:
- 选中对话框 -> 右击 -> 添加类 -> 类名:CUserDlg,基类选择CFormView
- 根据需求,控件关联所需变量
身份编辑区关联CString m_user,用户名编辑框关联CString m_name,
新密码编辑框关联CString m_newPwd,确定密码编辑框关联CString m_surePwd。
- 重写界面初始化函数OnInitDialog
// CUserDlg 消息处理程序 void CUserDlg::OnInitialUpdate() { CFormView::OnInitialUpdate(); //初始化代码 m_user = TEXT("销售员"); CInfoFile file; CString name, pwd; file.ReadDocline(); file.ReadLogin(name, pwd); m_name = name; UpdateData(FALSE); // TODO: 在此添加专用代码和/或调用基类 }
- 实现确定按钮功能实现
void CUserDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); if (m_newPwd.IsEmpty() || m_surePwd.IsEmpty()) { MessageBox(TEXT("输入的内容不能为空")); return; } //密码不一致 if (m_newPwd != m_surePwd) { MessageBox(TEXT("新密码与确定密码不一致")); return; } CInfoFile file; CString name, pwd; file.ReadLogin(name, pwd); //新密码与原密码要不一致 if (m_newPwd == pwd) { MessageBox(TEXT("新密码与原密码重复!")); return; } //修改密码 CStringA tmpName; CStringA tmpPwd; tmpName = name; tmpPwd = m_newPwd; file.WritePwd(tmpName.GetBuffer(), tmpPwd.GetBuffer()); MessageBox(TEXT("修改密码成功")); //清空输入内容 m_newPwd.Empty(); m_surePwd.Empty(); UpdateData(FALSE); }
取消按钮功能实现
void CUserDlg::OnBnClickedButton2() { // TODO: 在此添加控件通知处理程序代码 m_surePwd.Empty(); m_newPwd.Empty(); UpdateData(FALSE); }
销售管理窗口
- 添加新对话框,
- 选中对话框 -> 右击 -> 添加类 -> 类名:CSellDlg,基类选择CFormView
- 根据需求,控件关联所需变量
- 商品名组合框关联CComboBox m_combo,单价编辑框关联int m_price,个数编辑框关联int m_num,销售信息编辑框关联CString m_sellInfo。
- 重写OnInitDialog 函数。
void CSellDlg::OnInitialUpdate() { CFormView::OnInitialUpdate(); // TODO: 在此添加专用代码和/或调用基类 CInfoFile file; file.ReadDocline();//读取商品信息 for (auto it = file.ls.begin(); it != file.ls.end(); ++it) { m_combo.AddString((CString)it->name.c_str()); } file.ls.clear(); m_combo.SetCurSel(0); }
- 处理组合框处理实现
void CSellDlg::OnCbnSelchangeCombo1() { // TODO: 在此添加控件通知处理程序代码 CString text; int index = m_combo.GetCurSel(); m_combo.GetLBText(index, text);//获取当前选择的字符 CInfoFile file; file.ReadDocline(); for (auto it = file.ls.begin(); it != file.ls.end(); ++it) { if (text == it->name.c_str()) { m_price = it->price; m_num = 0; UpdateData(FALSE);//内容更新到显示空间 } } file.ls.clear(); }
- 购买按钮实现
void CSellDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE);//界面数据更新 if (m_num == 0) { MessageBox(TEXT("购买个数不能为0")); return; } CString type; //获取当前选择项目 int index = m_combo.GetCurSel(); m_combo.GetLBText(index, type); CString str; str.Format(TEXT("商品:%s \r\n 单价:%d \r\n 总价:%d"), type, m_price, m_num, m_price * m_num); m_sellInfo = str; UpdateData(FALSE);//更新到控件显示 MessageBox(str); //更新到库存文件 CInfoFile file; file.ReadDocline(); for (auto it = file.ls.begin(); it != file.ls.end(); ++it) { if (type == it->name.c_str()) { it->num = it->num - m_num; } } file.WriteDocline();//更新内容 file.ls.clear(); m_sellInfo.Empty();//清空 m_num = 0; UpdateData(FALSE); }
- 取消按钮实现
void CSellDlg::OnBnClickedButton2() { // TODO: 在此添加控件通知处理程序代码 //取消按钮处理 m_combo.SetCurSel(0);//选择第一个项目 m_sellInfo.Empty(); m_num = 0; OnCbnSelchangeCombo1(); }
库存信息窗口
- 添加对话框资源(ID修改为DIALOG_INFO),添加所需控件。View 属性为 Report(报表表模式):
- 选中对话框 -> 右击 -> 添加类 -> 类名:CInfoDlg,基类选择CFormView
- 根据需求,控件关联所需变量列表控件关联CListCtrl m_list:
- 重写 OnInitDialog 函数,进行商品信息初始化:
void CInfoDlg::OnInitialUpdate() { CFormView::OnInitialUpdate(); // TODO: 在此添加专用代码和/或调用基类 m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); //初始化表 CString field[] = { TEXT("商品ID"), TEXT("商品名称"), TEXT("商品价格"), TEXT("库存数量") }; for (int i = 0; i < sizeof(field) / sizeof(field[0]); ++i) { m_list.InsertColumn(i, field[i], LVCFMT_CENTER, 90); } //读取数据 CInfoFile file; file.ReadDocline(); int i = 0; CString str; for (auto it = file.ls.begin(); it != file.ls.end(); ++it) { str.Format(TEXT("%d"), it->id); m_list.InsertItem(i, str); int column = 1; m_list.SetItemText(i, column++, (CString)it->name.c_str()); str.Format(TEXT("%d"), it->price); m_list.SetItemText(i, column++, str); str.Format(TEXT("%d"), it->num); m_list.SetItemText(i, column++, str); i++; } }
库存添加窗口
- 添加对话框资源(ID修改为DIALOG_ADD),添加所需控件。
- 选中对话框 -> 右击 -> 添加类 -> 类名:CAddDlg,基类选择CFormView
- 根据需求,控件关联所需变量添加个数:商品组合框关联CComboBox m_combo,单价编辑框关联int m_price1,个数编辑框关联int m_num1。
- 添加新产品:商品组合框关联CString m_name2,单价编辑框关联int m_price2,个数编辑框关联int m_num2。
- 重写 OnInitDialog 函数,进行商品信息初始化:
void CAddDlg::OnInitialUpdate() { CFormView::OnInitialUpdate(); // TODO: 在此添加专用代码和/或调用基类 //读取文件数据 CInfoFile file; file.ReadDocline(); for (auto it = file.ls.begin(); it != file.ls.end(); ++it) { m_combo.AddString((CString)it->name.c_str()); } file.ls.clear(); m_combo.SetCurSel(0); }
- 处理组合框动作处理
void CAddDlg::OnCbnSelchangeCombo1() { // TODO: 在此添加控件通知处理程序代码 CString text; int index = m_combo.GetCurSel(); m_combo.GetLBText(index, text); CInfoFile file; file.ReadDocline(); for (auto it = file.ls.begin(); it != file.ls.end(); ++it) { if (text == it->name.c_str()) { m_price1 = it->price; m_num1 = 0; UpdateData(FALSE);//内容更新到空间 } } file.ls.clear(); }
- 添加个数确定按钮实现
void CAddDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); if (m_num1 == 0) { MessageBox(TEXT("个数不能为0")); return; } CString type; int index = m_combo.GetCurSel(); m_combo.GetLBText(index, type); CString str; str.Format(TEXT("添加了商品:%s \r\n 单价:%d \r\n 个数:%d"), type, m_price1, m_num1); MessageBox(str); //更新到数据文件中 CInfoFile file; file.ReadDocline(); for (auto it = file.ls.begin(); it != file.ls.end(); ++it) { if (type == it->name.c_str()) { it->num += m_num1; } } file.WriteDocline();//更新内容 file.ls.clear(); m_num1 = 0; UpdateData(FALSE); }
- 添加个数取消按钮实现
void CAddDlg::OnBnClickedButton2() { // TODO: 在此添加控件通知处理程序代码 //添加个数取消按键 m_combo.SetCurSel(0); m_num1 = 0; OnCbnSelchangeCombo1(); }
- 添加新商品确定按钮实现
void CAddDlg::OnBnClickedButton3() { // TODO: 在此添加控件通知处理程序代码\ //添加新商品确定按钮 UpdateData(TRUE); if (m_num2 <= 0 || m_price2 <= 0 || m_name2.IsEmpty()) { MessageBox(TEXT("输入信息有误")); return; } CInfoFile file; file.ReadDocline(); file.AddLine(m_name2, m_num2, m_price2); file.WriteDocline(); file.ls.clear(); MessageBox(TEXT("添加成功!")); m_name2.Empty(); m_num2 = 0; m_price2 = 0; UpdateData(FALSE); }
- 添加新商品取消按钮实现
void CAddDlg::OnBnClickedButton4() { // TODO: 在此添加控件通知处理程序代码 //添加新商品取消按钮 m_name2.Empty(); m_num2 = 0; m_price2 = 0; UpdateData(FALSE); }
库存删除窗口
- 添加对话框资源(ID修改为DIALOG_DEL),添加所需控件。
- 选中对话框 -> 右击 -> 添加类 -> 类名:CDelDlg,基类选择CFormView
- 根据需求,控件关联所需变量
商品名组合框关联CComboBox m_combo,单价编辑框关联int m_price,个数编辑框关联int m_num。
- 重写 OnInitDialog 函数,进行初始化。
void CDelDlg::OnInitialUpdate() { CFormView::OnInitialUpdate(); // TODO: 在此添加专用代码和/或调用基类 CInfoFile file; file.ReadDocline(); for (auto it = file.ls.begin(); it != file.ls.end(); ++it) { m_combo.AddString((CString)it->name.c_str()); } m_combo.SetCurSel(0); }
- 处理组合框事件实现
void CDelDlg::OnCbnSelchangeCombo1() { // TODO: 在此添加控件通知处理程序代码 CString text; int index = m_combo.GetCurSel(); m_combo.GetLBText(index, text); CInfoFile file; file.ReadDocline(); for (auto it = file.ls.begin(); it != file.ls.end(); ++it) { if (text == it->name.c_str()) { m_price = it->price; m_num = 0; UpdateData(FALSE); } } }
- 确定按钮功能实现
void CDelDlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 //确定按钮实现 UpdateData(TRUE); if (m_num == 0) { MessageBox(TEXT("个数不能为0!")); return; } CString type; int index = m_combo.GetCurSel(); m_combo.GetLBText(index, type); CString str; str.Format(TEXT("删除商品:%s \r\n 单价:%d \r\n 个数:%d"), type, m_price, m_num); MessageBox(str); CInfoFile file; file.ReadDocline(); for (auto it = file.ls.begin(); it != file.ls.end(); ++it) { if (type == it->name.c_str()) { it->num = it->num - m_num; } } file.WriteDocline();//更新数据内容 file.ls.clear(); m_num = 0; UpdateData(FALSE);//更新显示控件 }
- 取消按钮功能实现
void CDelDlg::OnBnClickedButton2() { // TODO: 在此添加控件通知处理程序代码 //取消按钮实现 m_combo.SetCurSel(0); m_num = 0; OnCbnSelchangeCombo1(); }
菜单栏实现
- 切换到资源视图的Menu,删除掉所有默认(帮助除外):
- 右键菜单栏项,添加事件处理程序,选择COMMAND 消息类型,添加至CMainFrame框架类中。
- 处理事件函数中发送消息给主框架实现界面切换。
void CMainFrame::OnEditUser() { // TODO: 在此添加命令处理程序代码 ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_A, (WPARAM)NM_A, (LPARAM)0); } void CMainFrame::OnEditSell() { // TODO: 在此添加命令处理程序代码 ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_B, (WPARAM)NM_B, (LPARAM)0); } void CMainFrame::OnEditCopy() { // TODO: 在此添加命令处理程序代码 ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_C, (WPARAM)NM_C, (LPARAM)0); } void CMainFrame::OnEditAdd() { // TODO: 在此添加命令处理程序代码 ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_D, (WPARAM)NM_D, (LPARAM)0); } void CMainFrame::OnEditDel() { // TODO: 在此添加命令处理程序代码 ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_E, (WPARAM)NM_E, (LPARAM)0); }
最终实现