• 使用MFC创建一个SaleSystem


    目录

    1、项目的创建:

    2、项目的配置:

    3、设置窗口属性:

    (1)、设置图标

    1)、添加导入资源

    2)、代码初始化图标

    (2)、设置标题

    (3)、设置窗口大小和位置

    4、CInfoFile类的引入:

    5、登录功能的实现:

    (1)、插入对话框

    (2)、修改对话框ID 

    (3)、修改对话框标题(caption)

    (4)、添加控件

    (5)、布局调整

    (6)、登录窗口添加类

    (7)、创建登录窗口以模态形式弹出

    (8)、实现登录功能

    (9)、保存账号密码

    (10)、取消功能实现

    (11)、解决问题1和问题2

    6、静态拆分窗口:

    (1)、添加类

    (2)、添加拆分窗口对象

     (3)、重写客户端

    7、树视图的功能:

    8、个人信息界面搭建:

    (1)UI以及属性的设置

    (2)、新创建的dialog添加类

    (3)、关联变量

    9、自定义消息以及界面的挂载:

    (1)、添加自定义的消息

    (2)、挂载界面

    10、个人信息功能完善:

    (1)、完善我的信息

    (2)、完善修改密码

    (3)、取消修改

    11、销售管理功能的实现:

    (1)、创建对话框并且更改属性

    (2)、为对话框添加类

     (3)、为控件添加变量

    (4)、挂载窗口

    (5)、完善窗口内容

    (6)、如果出现乱码

    (7)、重写一个改变的事件

    (8)、添加购买的点击事件

    (9)、购买之后清空数据

    (10)、数据写到文件中

    (11)、取消直接清空单价库存个数

    12、添加商品的个数功能实现:

    (1)UI设计

    (2)、dlg添加类

    (3)、控件添加变量

    (4)、界面挂载

    (5)、初始化界面

    (6)、添加功能实现

    (7)、取消添加按钮事件

    (8)、添加新商品的添加按钮

    (9)、添加商品的取消按钮


    1、项目的创建:

    2、项目的配置:

    由于现在VS不支持传统的scanf,strcpy,sprintf等,所以直接使用这些函数会提示C4996错误。

    VS建议采用带有_s的函数,如scanf_s、strcpy_s,但是这些不是标准的C++函数,如果想要继续使用这些函数需要添加_CRT_SECURE_NO_WARNINGS这个预定义。

    在项目->属性->c++预处理器->预处理器中添加_CRT_SECURE_NO_WARNINGS

    3、设置窗口属性:

    (1)、设置图标

    1)、添加导入资源

    导入成功后会出先在资源视图Icon里面

    2)、代码初始化图标

    CMainFrame中的OnCreate函数的用途:

    在MFC框架中,CMainFrame是主窗口的类,它是整个应用程序的核心。在CMainFrame的OnCreate函数中,通常会进行一些初始化操作,其中包括设置应用程序的图标

    应用程序的图标是应用程序的重要标志,它通常出现在窗口标题栏、任务栏和启动器等地方。

    具体来说,在CMainFrame的OnCreate函数中,通常会进行以下步骤:

            1、创建主窗口

    通过调用CFrameWnd::Create函数来创建主窗口,并将窗口显示在屏幕上。

            2、设置主窗口图标

    通过调用CWnd::SetIcon函数来设置主窗口的图标。可以选择不同大小的图标,以适应不同的显示需要。

            3、创建菜单和工具栏

    根据设计需求,使用MFC提供的相关类来创建菜单和工具栏,并设置相应的功能和事件处理函数。

            4、加载默认文档

    根据设计需求,利用MFC的文档视图框架来加载应用程序的默认文档,并打开初始的文档窗口。

    因此,在CMainFrame的OnCreate函数中设置应用程序的图标,是一个很自然和合理的选择。这样可以通过一次函数调用来完成这个任务,同时也可以与其他初始化操作相结合,使代码更加清晰和易于维护。

    代码部分:

    1. //设置图标。IDI_ICON_WIN为图标资源ID
    2. // 在 CMainFrame::OnCreate 函数中设置窗口图标
    3. HICON hIcon = AfxGetApp()->LoadIconW(IDI_ICON_WIN);
    4. //SetIcon(hIcon, TRUE); // 设置大图标
    5. SetIcon(hIcon, FALSE); // 设置小图标

    HICON代表图标资源句柄类型,

    hIcon代表接收的窗口图标句柄,

    AfxGetApp()->MFC全局函数(Afx开头)获取当前应用程序的指针

    LoadIconW(ID)加载图标资源并且返回图标资源的句柄。

    (2)、设置标题

    (左标题由操作系统管理在文档类)

    1. //设置左侧标题
    2. SetTitle(TEXT("销售管理系统"));

    1. //设置标题(右侧标题)
    2. SetTitle(TEXT("2023.10.17"));

    至于为什么标题的设置还有图标的初始化会在这些函数中:

    在 MFC 中,应用程序类(CWinApp 的派生类)负责应用程序的初始化和管理。当应用程序启动时,应用程序类的 InitInstance 函数被调用,可以在其中创建主窗口框架(CMainFrame)对象、文档模板(CDocTemplate)对象以及其他需要的资源。 

     主窗口框架类(CMainFrame)是应用程序的主窗口,并且通常包含菜单栏、工具栏、状态栏等界面元素,通过 CFrameWnd::OnCreate 函数进行初始化。OnCreate 函数中,可以设置窗口的标题、图标、样式等属性。

     文档类(CDocument 的派生类)负责管理应用程序的数据以及与数据相关的业务逻辑。每个文档类对应一个打开的文档实例,当打开新文档时,文档类的 OnNewDocument 函数会被调用。在 OnNewDocument 函数中,可以进行文档的初始化,包括设置标题、初始化数据等操作。

    (3)、设置窗口大小和位置

    MoveWindow()函数前俩个参数代表坐标,后面俩个参数代表宽高。

    CenterWindow()函数默认参数把窗口居中显示。

    设置之后的窗口样式:

    4、CInfoFile类的引入:

    俩个文本文件可以直接读取,但是.h和.cpp文件必须得添加到现在的项目中

    InfoFile.h

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. #include
    6. //#include
    7. //#include "stdafx.h"
    8. #define _F_LOGIN "./login.ini"//自定义宏_F_LOGIN代表打开login文件。
    9. #define _F_STOCK "./stock.txt"//自定义宏_F_STOCK代表打开stock文件。
    10. using namespace std;
    11. struct msg
    12. {
    13. int id; //商品id
    14. string name; //商品名
    15. int price; //商品价格
    16. int num; //商品个数
    17. };
    18. class CInfoFile
    19. {
    20. public:
    21. CInfoFile();
    22. ~CInfoFile();
    23. //读取登录信息
    24. void ReadLogin(CString &name, CString &pwd);
    25. //修改密码
    26. void WritePwd(char* name, char* pwd);
    27. //读取商品数据
    28. void ReadDocline();
    29. //商品写入文件
    30. void WriteDocline();
    31. //添加新商品
    32. void Addline(CString name, int num, int price);
    33. list ls; //存储商品容器
    34. int num; //用来记录商品个数
    35. };

    InfoFile.cpp

    1. #include "stdafx.h"
    2. #include "InfoFile.h"
    3. CInfoFile::CInfoFile()
    4. {
    5. }
    6. CInfoFile::~CInfoFile()
    7. {
    8. }
    9. //读取登录信息
    10. void CInfoFile::ReadLogin(CString &name, CString &pwd)
    11. {
    12. ifstream ifs; //创建文件输入对象
    13. ifs.open(_F_LOGIN);
    14. char buf[1024] = { 0 };
    15. if (!ifs.is_open()) {
    16. cout << "文件打开失败" << endl;
    17. }
    18. ifs.getline(buf, sizeof(buf)); //读取一行内容
    19. name = CString(buf); //将char* 转换为CString
    20. ifs.getline(buf, sizeof(buf)); //读取一行内容
    21. pwd = CString(buf); //将char* 转换为CString
    22. ifs.close(); //关闭文件
    23. }
    24. //修改密码
    25. void CInfoFile::WritePwd(char* name, char* pwd)
    26. {
    27. ofstream ofs; //创建文件输出对象
    28. ofs.open(_F_LOGIN); //打开文件
    29. if (!ofs.is_open())
    30. {
    31. cout << "文件打开失败" << endl;
    32. }
    33. ofs << name << endl; //name写入文件
    34. ofs << pwd << endl; //pwd写入文件
    35. ofs.close(); //关闭文件
    36. }
    37. //读取商品的信息
    38. void CInfoFile::ReadDocline()
    39. {
    40. ifstream ifs(_F_STOCK); //读取方式打开文件
    41. char buf[1024] = { 0 };
    42. num = 0; //初始化商品数量为0
    43. ls.clear();
    44. //取出表头
    45. ifs.getline(buf, sizeof(buf));
    46. while (!ifs.eof()) //没到文件结尾
    47. {
    48. msg tmp;
    49. ifs.getline(buf, sizeof(buf)); //读取一行
    50. num++; //商品数量加一
    51. //AfxMessageBox(CString(buf));
    52. char *sst = strtok(buf, "|"); //以"|"分隔
    53. if (sst != NULL)
    54. {
    55. tmp.id = atoi(sst); //商品id
    56. }
    57. else
    58. {
    59. break;
    60. }
    61. sst = strtok(NULL, "|");
    62. tmp.name = sst; //商品名称
    63. sst = strtok(NULL, "|");
    64. tmp.price = atoi(sst); //商品价格
    65. sst = strtok(NULL, "|");
    66. tmp.num = atoi(sst); //商品数目
    67. ls.push_back(tmp); //放在链表的后面
    68. }
    69. ifs.close(); //关闭文件
    70. }
    71. //商品写入文件
    72. void CInfoFile::WriteDocline()
    73. {
    74. ofstream ofs(_F_STOCK); //输出方式打开文件
    75. string bt = "商品ID|商品名|单价|库存";
    76. if (ls.size() > 0) //商品链表有内容才执行
    77. {
    78. ofs << bt << endl; //写入表头
    79. //通过迭代器取出链表内容,写入文件,以"|"分割,结尾加换行
    80. for (list::iterator it = ls.begin(); it != ls.end(); it++)
    81. {
    82. ofs << it->id << "|";
    83. ofs << it->name << "|";
    84. ofs << it->price << "|";
    85. ofs << it->num << endl;
    86. }
    87. }
    88. ofs.close();
    89. }
    90. //添加新商品
    91. //name:商品名称,num:库存,price:价格
    92. void CInfoFile::Addline(CString name, int num, int price)
    93. {
    94. msg tmp;
    95. if (ls.size() > 0)
    96. {
    97. //商品名称,库存,价格有效
    98. if (!name.IsEmpty() && num > 0 && price > 0)
    99. {
    100. tmp.id = ls.size() + 1; //id自动加1
    101. CStringA str;
    102. str = name; //CString 转CStringA
    103. tmp.name = str.GetBuffer();//CString 转为char *, 商品名称
    104. tmp.num = num; //库存
    105. tmp.price = price; //价格
    106. ls.push_back(tmp); //放在链表的后面
    107. }
    108. }
    109. }

    (1)、功能测试

     

    修改账号密码成功,弹出的新的账号密码。

    5、登录功能的实现:

    (1)、插入对话框

    (2)、修改对话框ID 

    (3)、修改对话框标题(caption)

    (4)、添加控件

    密码的Edit Control属性设置为密码不可见

    (5)、布局调整

    (6)、登录窗口添加类

    (7)、创建登录窗口以模态形式弹出

    问题1:关闭选项,关闭进入主窗口

    问题2:在edit里面按下回车直接进入主窗口

    (8)、实现登录功能

    鼠标点击登录按钮事件

    1. void CLoginDlg::OnBnClickedButton1()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. //登录按钮点击事件
    5. //控件中的内容同步到变量中,也就是密码同步到变量中
    6. UpdateData(TRUE);
    7. //1、判断俩个账号密码都不为空
    8. if (m_user.IsEmpty() || m_pwd.IsEmpty())
    9. {
    10. MessageBox(TEXT("输入内容不为空"));
    11. return;
    12. }
    13. //CInfoFile类可以获取账号密码
    14. CInfoFile file;
    15. CString pwd,name;
    16. file.ReadLogin(name, pwd);//用户名,密码
    17. if (name == m_user)//用户名一致
    18. {
    19. if (pwd == m_pwd)//密码一致
    20. {
    21. //关闭当前的对话框
    22. MessageBox(TEXT("登陆成功!"));
    23. CDialog::OnCancel();
    24. }
    25. else
    26. {
    27. MessageBox(TEXT("密码错误"));
    28. }
    29. }
    30. else
    31. {
    32. MessageBox(TEXT("用户名错误"));
    33. }
    34. }

    (9)、保存账号密码

    默认直接有账号密码

    1. BOOL CLoginDlg::OnInitDialog()
    2. {
    3. CDialogEx::OnInitDialog();
    4. // TODO: 在此添加额外的初始化
    5. //默认登录信息
    6. CInfoFile file;
    7. CString name, pwd;
    8. file.ReadLogin(name, pwd);
    9. m_user = name;
    10. m_pwd = pwd;
    11. //同步到控件中
    12. UpdateData(FALSE);
    13. return TRUE; // return TRUE unless you set the focus to a control
    14. // 异常: OCX 属性页应返回 FALSE
    15. }

    (10)、取消功能实现

    (11)、解决问题1和问题2

    问题1 窗口关闭直接跳转主窗口

    更改消息里面的WM_CLOSE函数

    问题2回车不能跳转页面

    重写OnOK()函数

    OnOK()函数回关闭当前对话框,直接注释掉。

    6、静态拆分窗口:

    (1)、添加类

    (2)、添加拆分窗口对象

     (3)、重写客户端

    先引入头文件

    1. #include"SelectView.h"
    2. #include "DispalyView.h"

    重写拆分事件

    1. //拆成一行俩列
    2. m_spliter.CreateStatic(this, 1, 2);
    3. //左侧右侧具体显示的信息
    4. m_spliter.CreateView(0,0,RUNTIME_CLASS(CSelectView),CSize(200,500),pContext);
    5. m_spliter.CreateView(0,1, RUNTIME_CLASS(CDispalyView), CSize(200, 500), pContext);
    6. return TRUE;//代表用户自己拆分

    7、树视图的功能:

    1. //初始化树视图
    2. //获取树控件
    3. m_treeCtrl = &GetTreeCtrl();
    4. //1、准备图片集合
    5. HICON icon = AfxGetApp()->LoadIconW(IDI_ICON_RE);
    6. m_imageList.Create(30, 30, ILC_COLOR32, 1, 1);
    7. m_imageList.Add(icon);
    8. m_treeCtrl->SetImageList(&m_imageList, TVSIL_NORMAL);
    9. //2、添加节点
    10. m_treeCtrl->InsertItem(TEXT("个人信息"),0,0,NULL);
    11. m_treeCtrl->InsertItem(TEXT("销售管理"), 0, 0, NULL);
    12. m_treeCtrl->InsertItem(TEXT("库存信息"), 0, 0, NULL);
    13. m_treeCtrl->InsertItem(TEXT("库存添加"), 0, 0, NULL);
    14. m_treeCtrl->InsertItem(TEXT("库存删除"), 0, 0, NULL);

    InsertItem函数原型:

    HTREEITEM InsertItem

    (

    LPCTSTR lpszItem,        //显示的文本

    int nImage,                      //节点的图像索引

    int nSelectedImage,        //节点被选中时图像的索引

    HTREEITEM hParent     //指定该节点作为哪个节点的子节点

                                             //NULL代表是根节点,root代表父节点,parent代表子节点

    );
     

    create()函数原型: 

    1. //获取当前的选中项
    2. HTREEITEM item = m_treeCtrl->GetSelectedItem();
    3. //获取选中项里面的内容
    4. CString name = m_treeCtrl->GetItemText(item);
    5. MessageBox(name);

    8、个人信息界面搭建:

    (1)UI以及属性的设置

     

    (2)、新创建的dialog添加类

    (3)、关联变量

    9、自定义消息以及界面的挂载:

    (1)、添加自定义的消息

    从CSelectView.cpp中发送信息 

    (2)、挂载界面

    1)、引入要挂载界面的头文件

    #include "UserDlg.h"

    2)、代码部分

    1. CCreateContext Context;
    2. if (wParam == NM_A)
    3. {
    4. //MessageBox(L"个人信息界面挂载");
    5. //挂在界面
    6. Context.m_pNewViewClass = RUNTIME_CLASS(CUserDlg);
    7. Context.m_pCurrentFrame = this;
    8. Context.m_pLastView = (CFormView *)m_spliter.GetPane(0,1);
    9. m_spliter.DeleteView(0, 1);
    10. m_spliter.CreateView(0, 1, RUNTIME_CLASS(CUserDlg), CSize(600, 500),&Context);
    11. CUserDlg *pNewView = (CUserDlg *) m_spliter.GetPane(0,1);
    12. m_spliter.RecalcLayout();
    13. pNewView->OnInitialUpdate();
    14. m_spliter.SetActivePane(0,1);
    15. }

    10、个人信息功能完善:

    (1)、完善我的信息

    1. void CUserDlg::OnInitialUpdate()
    2. {
    3. CFormView::OnInitialUpdate();
    4. //初始化
    5. m_user = TEXT("销售员");
    6. CInfoFile file;
    7. CString name, pwd;
    8. file.ReadLogin(name, pwd);
    9. m_name = name;//获取名称
    10. UpdateData(FALSE);//变量同步到控件上
    11. // TODO: 在此添加专用代码和/或调用基类
    12. }

    (2)、完善修改密码

    1. void CUserDlg::OnBnClickedButton1()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. //修改密码功能
    5. UpdateData(TRUE);//拿到最新的值
    6. if (m_newPwd.IsEmpty() || m_surePwd.IsEmpty())
    7. {
    8. MessageBox(TEXT("输入的内容不能为空!"));
    9. return;
    10. }
    11. //新密码和确定密码要一致
    12. if (m_newPwd != m_surePwd)
    13. {
    14. MessageBox(TEXT("新密码与确定密码要一致!"));
    15. return;
    16. }
    17. //获取旧密码。
    18. CInfoFile file;
    19. CString name, pwd;
    20. file.ReadLogin(name, pwd);
    21. if (m_newPwd == pwd)
    22. {
    23. MessageBox(TEXT("新密码和旧密码不能一致!"));
    24. return;
    25. }
    26. //WritePwd写要求的char *类型
    27. CStringA tmp;
    28. tmp = name;
    29. CStringA tmp1;
    30. tmp1 = m_newPwd;//现在放进去的应该是新的密码,不是旧的密码
    31. file.WritePwd(tmp.GetBuffer(), tmp1.GetBuffer());
    32. MessageBox(L"修改成功!");
    33. //情况内容
    34. m_newPwd.Empty();
    35. m_surePwd.Empty();
    36. UpdateData(FALSE);
    37. }

    修改成功。

    (3)、取消修改

    直接清空密码

    1. void CUserDlg::OnBnClickedButton2()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. //清空内容
    5. m_newPwd.Empty();
    6. m_surePwd.Empty();
    7. UpdateData(FALSE);
    8. }

    11、销售管理功能的实现:

    (1)、创建对话框并且更改属性

    (2)、为对话框添加类

     (3)、为控件添加变量

    (4)、挂载窗口

    (5)、完善窗口内容

    在入口函数初始化下拉列表

    1. void CSellDlg1::OnInitialUpdate()
    2. {
    3. CFormView::OnInitialUpdate();
    4. // TODO: 在此添加专用代码和/或调用基类
    5. //初始化销售订单窗口
    6. //初始化下拉框
    7. CInfoFile file;
    8. //把商品读到对象中
    9. file.ReadDocline();
    10. list::iterator it = file.ls.begin();
    11. for (;it != file.ls.end();it++)
    12. {
    13. //遍历商品容器,把容器放到下拉框中
    14. //string->CString
    15. m_combo.AddString(CString(it->name.c_str()));
    16. }
    17. //默认选中第一个
    18. m_combo.SetCurSel(0);
    19. }

    (6)、如果出现乱码

    可以使用getline函数获取文件文本中的内容,文件是以ANSI编码保存的则不会出现问题,如果采用其他编码格式(UTF-8,UTF-16会出现乱码),一般存放在string类型的对象中,如果要处理更加复杂的多字节字符集(UTF-8,UTF-16)可以使用wstring来处理。

    (7)、重写一个改变的事件

    重写改变事件的目睹为了在切换下拉框的时候跟新其他的信息。

    1. void CSellDlg1::OnCbnSelchangeCombo1()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. //先获取商品的名称
    5. int index = m_combo.GetCurSel();
    6. CString name;
    7. m_combo.GetLBText(index,name);
    8. CInfoFile file;
    9. //根据商品名称获取到商品的价格和库存,并且显示到控件中
    10. //把商品读到对象中
    11. file.ReadDocline();
    12. list::iterator it = file.ls.begin();
    13. for (; it != file.ls.end(); it++)
    14. {
    15. if ((CString)it->name.c_str() == name)
    16. {
    17. m_price = it->price;
    18. m_left = it->num;
    19. //同步到控件上
    20. UpdateData(FALSE);
    21. }
    22. }

    由于第一个商品的单价库存没有同步,我们可以手动调用一次这个改变事件

    (8)、添加购买的点击事件

    实现购买功能

    1. void CSellDlg1::OnBnClickedButton2()
    2. {
    3. //UpdateData(TRUE);//没有获取最新数据
    4. // TODO: 在此添加控件通知处理程序代码
    5. //购买功能实现
    6. if (m_num <= 0)
    7. {
    8. MessageBox(L"购买数量要大于0");
    9. return;
    10. }
    11. //购买的数量不能大于库存
    12. if (m_num > m_left)
    13. {
    14. MessageBox(L"购买数量不能大于库存");
    15. return;
    16. }
    17. //购买
    18. //获取到具体要买的商品名称
    19. int indx = m_combo.GetCurSel();
    20. CString name;
    21. m_combo.GetLBText(indx, name);
    22. CInfoFile file;
    23. file.ReadDocline();
    24. list::iterator it = file.ls.begin();
    25. for (; it != file.ls.end(); it++)
    26. {
    27. //遍历的商品和这个商品一致减少库存
    28. if ((CString)it->name.c_str() == name)
    29. {
    30. //同步库存量
    31. it->num -= m_num;
    32. m_left = it->num;//控件上的库存量
    33. //告诉用户具体的购买信息
    34. CString str;
    35. str.Format(_T("商品: %s \r\n单价: %d \r\n个数: %d \r\n总价: %d"), name, m_price, m_num, m_price*m_num);
    36. m_selfInfo = str;
    37. UpdateData(FALSE);
    38. MessageBox(L"购买成功");
    39. }

    (9)、购买之后清空数据

    (10)、数据写到文件中

    我们购买之后库存并没有减少,所以我们要把数据写到文件中去

    (11)、取消直接清空单价库存个数

    1. void CSellDlg1::OnBnClickedButton3()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. //取消按钮
    5. m_num = 0;
    6. UpdateData(FALSE);
    7. //默认选中第一个
    8. m_combo.SetCurSel(0);
    9. OnCbnSelchangeCombo1();//更新第一个商品里面的数据
    10. }

    12、添加商品的个数功能实现:

    (1)UI设计

    (2)、dlg添加类

    (3)、控件添加变量

     商品添加变量

    单价添加变量 

    (4)、界面挂载

    头文件引入

    #include "ADddDlg.h"

    实现挂载

    1. else if (wParam == NM_D)
    2. {
    3. //MessageBox(L"库存添加界面挂载");
    4. Context.m_pNewViewClass = RUNTIME_CLASS(ADddDlg);
    5. Context.m_pCurrentFrame = this;
    6. Context.m_pLastView = (CFormView *)m_spliter.GetPane(0, 1);
    7. m_spliter.DeleteView(0, 1);
    8. m_spliter.CreateView(0, 1, RUNTIME_CLASS(ADddDlg), CSize(600, 500), &Context);
    9. ADddDlg *pNewView = (ADddDlg *)m_spliter.GetPane(0, 1);
    10. m_spliter.RecalcLayout();
    11. pNewView->OnInitialUpdate();
    12. m_spliter.SetActivePane(0, 1);
    13. }

    (5)、初始化界面

    1. void ADddDlg::OnInitialUpdate()
    2. {
    3. CFormView::OnInitialUpdate();
    4. // TODO: 在此添加专用代码和/或调用基类
    5. //初始化下拉框
    6. CInfoFile file;
    7. //把商品读到对象中
    8. file.ReadDocline();
    9. list::iterator it = file.ls.begin();
    10. for (; it != file.ls.end(); it++)
    11. {
    12. //遍历商品容器,把容器放到下拉框中
    13. //string->CString
    14. m_combo.AddString(CString(it->name.c_str()));
    15. }
    16. //默认选中第一个商品
    17. m_combo.SetCurSel(0);
    18. OnCbnSelchangeCombo1();//手动调用更新第一个商品数据
    19. }
    20. void ADddDlg::OnCbnSelchangeCombo1()
    21. {
    22. // TODO: 在此添加控件通知处理程序代码
    23. //先获取商品的名称
    24. int index = m_combo.GetCurSel();
    25. CString name;
    26. m_combo.GetLBText(index, name);
    27. CInfoFile file;
    28. //根据商品名称获取到商品的价格和库存,并且显示到控件中
    29. //把商品读到对象中
    30. file.ReadDocline();
    31. list::iterator it = file.ls.begin();
    32. for (; it != file.ls.end(); it++)
    33. {
    34. if ((CString)it->name.c_str() == name)
    35. {
    36. m_price1 = it->price;
    37. //同步到控件上
    38. UpdateData(FALSE);
    39. }
    40. }

    (6)、添加功能实现

    添加事件代码

    1. void ADddDlg::OnBnClickedButton3()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. //添加商品按钮功能实现
    5. //拿到最新的数据
    6. UpdateData(TRUE);
    7. if (m_num1 <= 0)
    8. {
    9. MessageBox(L"添加的数量必须大于0!");
    10. return;
    11. }
    12. //先获取你要添加的商品名称
    13. int indx = m_combo.GetCurSel();
    14. CString name;
    15. m_combo.GetLBText(indx, name);
    16. CInfoFile file;
    17. file.ReadDocline();
    18. list::iterator it = file.ls.begin();
    19. for (; it != file.ls.end(); it++)
    20. {
    21. if ((CString)it->name.c_str() == name)
    22. {
    23. //添加库存
    24. it->num += m_num1;
    25. m_num1 = 0;
    26. UpdateData(FALSE);
    27. MessageBox(L"添加成功!");
    28. }
    29. //把商品同步到文件中
    30. file.WriteDocline();
    31. }

    运行效果

    (7)、取消添加按钮事件

    1. void ADddDlg::OnBnClickedButton4()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. m_num1 = 0;
    5. UpdateData(FALSE);
    6. m_combo.SetCurSel(0);
    7. OnCbnSelchangeCombo1();
    8. }

    (8)、添加新商品的添加按钮

    1. void ADddDlg::OnBnClickedButton5()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. //拿到最新的数据
    5. UpdateData(TRUE);
    6. //验证添加新商品
    7. //验证数据的有效性
    8. if (m_name2.IsEmpty() || m_num2 <= 0 || m_price2 <= 0)
    9. {
    10. MessageBox(L"你输入的信息有误!");
    11. return;
    12. }
    13. CInfoFile file;
    14. file.ReadDocline();
    15. file.Addline(m_name2, m_num2, m_price2);
    16. file.WriteDocline();
    17. MessageBox(L"商品添加成功!");
    18. //同步到左侧下拉框中
    19. m_combo.InsertString(0, m_name2);
    20. m_combo.SetCurSel(0);
    21. OnCbnSelchangeCombo1();
    22. //清空添加的新数据
    23. m_name2.Empty();
    24. m_num2 = 0;
    25. m_price2 = 0;
    26. UpdateData(FALSE);
    27. }

    (9)、添加商品的取消按钮

    1. void ADddDlg::OnBnClickedButton6()
    2. {
    3. // TODO: 在此添加控件通知处理程序代码
    4. m_num2 = 0;
    5. m_name2.Empty();
    6. m_price2 = 0;
    7. UpdateData(FALSE);
    8. }

  • 相关阅读:
    jQuery实现下拉菜单
    孟菲斯风格知道吗?如何应用在UI设计领域
    ExcelPatternTool 开箱即用的Excel工具包现已发布!
    金蝶云星空套打设计平台导出套打模板和导入套打模板
    【云原生】使用nginx反向代理后台多服务器
    WebAssembly开启的微服务新时代
    软件测试基本流程有哪些?权威的第三方软件检测机构推荐
    iOS开发-自定义下拉刷新控件PullDownRefreshView
    是时候丢掉BeanUtils了
    shell_74.Linux创建使用函数
  • 原文地址:https://blog.csdn.net/qq_59328991/article/details/133884694