使用MFC创建一个SaleSystem

news2024/11/19 20:37:04

目录

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

代码部分:

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

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

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

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

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

(2)、设置标题

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


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

//设置标题(右侧标题)
	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

#pragma once

#include <list>
#include <fstream>
#include <iostream>
#include <string>
//#include <afx.h>
//#include "stdafx.h"

#define _F_LOGIN "./login.ini"//自定义宏_F_LOGIN代表打开login文件。
#define _F_STOCK "./stock.txt"//自定义宏_F_STOCK代表打开stock文件。

using namespace std;

struct msg
{
	int id; //商品id
	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);

	list<msg> ls;	//存储商品容器
	int num;			//用来记录商品个数

};


InfoFile.cpp


#include "stdafx.h"
#include "InfoFile.h"


CInfoFile::CInfoFile()
{
}

CInfoFile::~CInfoFile()
{
}

//读取登录信息
void CInfoFile::ReadLogin(CString &name, CString &pwd)
{
	ifstream ifs; //创建文件输入对象
	ifs.open(_F_LOGIN);
	char buf[1024] = { 0 };
    if (!ifs.is_open()) {
		cout << "文件打开失败" << endl;
	}

	ifs.getline(buf, sizeof(buf));	//读取一行内容
	name = CString(buf);	//将char* 转换为CString

	ifs.getline(buf, sizeof(buf));	//读取一行内容
	pwd = CString(buf);	//将char* 转换为CString

	ifs.close();	//关闭文件
}

//修改密码
void CInfoFile::WritePwd(char* name, char* pwd)
{
	ofstream ofs; //创建文件输出对象
	ofs.open(_F_LOGIN); //打开文件
    if (!ofs.is_open())
	{
		cout << "文件打开失败" << endl;
	}

	ofs << name << endl;	//name写入文件
	ofs << pwd << endl;	//pwd写入文件

	ofs.close();	//关闭文件
}

//读取商品的信息
void CInfoFile::ReadDocline()
{
	ifstream ifs(_F_STOCK); //读取方式打开文件

	char buf[1024] = { 0 };
	num = 0;	//初始化商品数量为0
	ls.clear();
	//取出表头
	ifs.getline(buf, sizeof(buf));

	while (!ifs.eof())	//没到文件结尾
	{
		msg tmp;

		ifs.getline(buf, sizeof(buf));	//读取一行
		num++;	//商品数量加一

				//AfxMessageBox(CString(buf));
		char *sst = strtok(buf, "|");	//以"|"分隔
		if (sst != NULL)
		{
			tmp.id = atoi(sst);	//商品id
		}
		else
		{
			break;
		}

		sst = strtok(NULL, "|");
		tmp.name = sst;	//商品名称

		sst = strtok(NULL, "|");
		tmp.price = atoi(sst);	//商品价格

		sst = strtok(NULL, "|");
		tmp.num = atoi(sst);	//商品数目

		ls.push_back(tmp);	//放在链表的后面
	}

	ifs.close();	//关闭文件

}


//商品写入文件
void CInfoFile::WriteDocline()
{
	ofstream ofs(_F_STOCK); //输出方式打开文件
	string bt = "商品ID|商品名|单价|库存";

	if (ls.size() > 0)	//商品链表有内容才执行
	{
		ofs << bt << endl;	//写入表头

							//通过迭代器取出链表内容,写入文件,以"|"分割,结尾加换行
		for (list<msg>::iterator it = ls.begin(); it != ls.end(); it++)
		{
			ofs << it->id << "|";
			ofs << it->name << "|";
			ofs << it->price << "|";
			ofs << it->num << endl;
		}
	}
	ofs.close();

}


//添加新商品
//name:商品名称,num:库存,price:价格
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;	//id自动加1
			CStringA str;
			str = name;					//CString 转CStringA
			tmp.name = str.GetBuffer();//CString 转为char *, 商品名称
			tmp.num = num;			//库存
			tmp.price = price;		//价格

			ls.push_back(tmp);			//放在链表的后面
		}
	}
}

(1)、功能测试

 

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

5、登录功能的实现:

(1)、插入对话框

(2)、修改对话框ID 

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

(4)、添加控件

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

(5)、布局调整

(6)、登录窗口添加类

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

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

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

(8)、实现登录功能

鼠标点击登录按钮事件

void CLoginDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码

	//登录按钮点击事件
	//控件中的内容同步到变量中,也就是密码同步到变量中
	UpdateData(TRUE);
	//1、判断俩个账号密码都不为空
	if (m_user.IsEmpty() || m_pwd.IsEmpty()) 
	{
		MessageBox(TEXT("输入内容不为空"));
		
		return;
	}
	//CInfoFile类可以获取账号密码
	CInfoFile file;
	CString pwd,name;
	file.ReadLogin(name, pwd);//用户名,密码

	if (name == m_user)//用户名一致
	{
		if (pwd == m_pwd)//密码一致
		{
			//关闭当前的对话框
			MessageBox(TEXT("登陆成功!"));
			CDialog::OnCancel();
		}
		else 
		{
			MessageBox(TEXT("密码错误"));
		}
	}
	else
	{
		MessageBox(TEXT("用户名错误"));
	}
}

(9)、保存账号密码

默认直接有账号密码

BOOL CLoginDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化

	//默认登录信息
	CInfoFile file;
	CString name, pwd;
	file.ReadLogin(name, pwd);

	m_user = name;
	m_pwd = pwd;
	//同步到控件中
	UpdateData(FALSE);
		

	return TRUE;  // return TRUE unless you set the focus to a control
				  // 异常: OCX 属性页应返回 FALSE
}

(10)、取消功能实现

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

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

更改消息里面的WM_CLOSE函数

问题2回车不能跳转页面

重写OnOK()函数

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

6、静态拆分窗口:

(1)、添加类

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

 (3)、重写客户端

先引入头文件

#include"SelectView.h"
#include "DispalyView.h"

重写拆分事件

//拆成一行俩列
	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(CDispalyView), CSize(200, 500), pContext);

	return TRUE;//代表用户自己拆分

7、树视图的功能:

//初始化树视图
	//获取树控件
	m_treeCtrl = &GetTreeCtrl();

	//1、准备图片集合
	HICON icon = AfxGetApp()->LoadIconW(IDI_ICON_RE);
	m_imageList.Create(30, 30, ILC_COLOR32, 1, 1);
	m_imageList.Add(icon);

	m_treeCtrl->SetImageList(&m_imageList, TVSIL_NORMAL);
	//2、添加节点
	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);

InsertItem函数原型:

HTREEITEM InsertItem

(

LPCTSTR lpszItem,        //显示的文本

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

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

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

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

);
 

create()函数原型: 

//获取当前的选中项
	HTREEITEM item = m_treeCtrl->GetSelectedItem();

	//获取选中项里面的内容
	CString name = m_treeCtrl->GetItemText(item);
	MessageBox(name);

8、个人信息界面搭建:

(1)UI以及属性的设置

 

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

(3)、关联变量

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

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

从CSelectView.cpp中发送信息 

(2)、挂载界面

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

#include "UserDlg.h"

2)、代码部分

CCreateContext Context;
	if (wParam == NM_A)
	{
		//MessageBox(L"个人信息界面挂载");
		//挂在界面
		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);

	}

10、个人信息功能完善:

(1)、完善我的信息

void CUserDlg::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();

	//初始化
	m_user = TEXT("销售员");

	CInfoFile file;
	CString name, pwd;
	file.ReadLogin(name, pwd);
	m_name = name;//获取名称

	UpdateData(FALSE);//变量同步到控件上

	// TODO: 在此添加专用代码和/或调用基类
}

(2)、完善修改密码

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;
	}
	//WritePwd写要求的char *类型
	CStringA tmp;
	tmp = name;
	
	CStringA tmp1;
	tmp1 = m_newPwd;//现在放进去的应该是新的密码,不是旧的密码
	file.WritePwd(tmp.GetBuffer(), tmp1.GetBuffer());
	MessageBox(L"修改成功!");

	//情况内容
	m_newPwd.Empty();
	m_surePwd.Empty();
	UpdateData(FALSE);
}

修改成功。

(3)、取消修改

直接清空密码

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

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

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

(2)、为对话框添加类

 (3)、为控件添加变量

(4)、挂载窗口

(5)、完善窗口内容

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

void CSellDlg1::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();

	// TODO: 在此添加专用代码和/或调用基类
	//初始化销售订单窗口
	//初始化下拉框
	CInfoFile file;
	//把商品读到对象中
	file.ReadDocline();
	list<msg>::iterator it = file.ls.begin();
	for (;it != file.ls.end();it++)
	{	
		//遍历商品容器,把容器放到下拉框中
		//string->CString
		m_combo.AddString(CString(it->name.c_str()));
	}
	
	//默认选中第一个
	m_combo.SetCurSel(0);

}

(6)、如果出现乱码

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

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

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

void CSellDlg1::OnCbnSelchangeCombo1()
{
	// TODO: 在此添加控件通知处理程序代码

	//先获取商品的名称
	
	int index = m_combo.GetCurSel();
	CString name;
	m_combo.GetLBText(index,name);
	
	CInfoFile file;
	//根据商品名称获取到商品的价格和库存,并且显示到控件中
	//把商品读到对象中
	file.ReadDocline();
	list<msg>::iterator it = file.ls.begin();
	for (; it != file.ls.end(); it++)
	{
		if ((CString)it->name.c_str() == name) 
		{
			m_price = it->price;
			m_left = it->num;
			//同步到控件上
			UpdateData(FALSE);
		}
		
	}

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

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

实现购买功能

void CSellDlg1::OnBnClickedButton2()

{
	//UpdateData(TRUE);//没有获取最新数据
	// TODO: 在此添加控件通知处理程序代码
	//购买功能实现
	if (m_num <= 0)
	{
		MessageBox(L"购买数量要大于0");
		return;
	}
	//购买的数量不能大于库存
	if (m_num > m_left)
	{
		MessageBox(L"购买数量不能大于库存");
		return;
	}
	//购买
	//获取到具体要买的商品名称
	int indx = m_combo.GetCurSel();
	CString name;
	m_combo.GetLBText(indx, name);
	
	CInfoFile file;
	
	file.ReadDocline();
	list<msg>::iterator it = file.ls.begin();
	for (; it != file.ls.end(); it++)
	{
		//遍历的商品和这个商品一致减少库存
		if ((CString)it->name.c_str() == name) 
		{
			//同步库存量
			it->num -= m_num;
			m_left = it->num;//控件上的库存量
			//告诉用户具体的购买信息

			CString str;
			str.Format(_T("商品: %s \r\n单价: %d  \r\n个数: %d \r\n总价: %d"), name, m_price, m_num, m_price*m_num);
			m_selfInfo = str;
			UpdateData(FALSE);
			MessageBox(L"购买成功");


		}

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

(10)、数据写到文件中

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

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

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

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

(1)UI设计

(2)、dlg添加类

(3)、控件添加变量

 商品添加变量

单价添加变量 

(4)、界面挂载

头文件引入

#include "ADddDlg.h"

实现挂载

else if (wParam == NM_D)
	{
		//MessageBox(L"库存添加界面挂载");
		Context.m_pNewViewClass = RUNTIME_CLASS(ADddDlg);
		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(ADddDlg), CSize(600, 500), &Context);
		ADddDlg *pNewView = (ADddDlg *)m_spliter.GetPane(0, 1);
		m_spliter.RecalcLayout();
		pNewView->OnInitialUpdate();
		m_spliter.SetActivePane(0, 1);
	}

(5)、初始化界面

void ADddDlg::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();

	// TODO: 在此添加专用代码和/或调用基类

	//初始化下拉框
	CInfoFile file;
	//把商品读到对象中
	file.ReadDocline();
	list<msg>::iterator it = file.ls.begin();
	for (; it != file.ls.end(); it++)
	{
		//遍历商品容器,把容器放到下拉框中
		//string->CString
		m_combo.AddString(CString(it->name.c_str()));
	}

	//默认选中第一个商品
	m_combo.SetCurSel(0);
	OnCbnSelchangeCombo1();//手动调用更新第一个商品数据
}


void ADddDlg::OnCbnSelchangeCombo1()
{
	// TODO: 在此添加控件通知处理程序代码
	//先获取商品的名称

	int index = m_combo.GetCurSel();
	CString name;
	m_combo.GetLBText(index, name);

	CInfoFile file;
	//根据商品名称获取到商品的价格和库存,并且显示到控件中
	//把商品读到对象中
	file.ReadDocline();
	list<msg>::iterator it = file.ls.begin();
	for (; it != file.ls.end(); it++)
	{
		if ((CString)it->name.c_str() == name)
		{
			m_price1 = it->price;
			
			//同步到控件上
			UpdateData(FALSE);
		}

	}

(6)、添加功能实现

添加事件代码

void ADddDlg::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码

	//添加商品按钮功能实现
	//拿到最新的数据
	UpdateData(TRUE);

	if (m_num1 <= 0)
	{
		MessageBox(L"添加的数量必须大于0!");
		return;
	}
	//先获取你要添加的商品名称
	int indx = m_combo.GetCurSel();
	CString name;
	m_combo.GetLBText(indx, name);
	CInfoFile file;
	file.ReadDocline();
	list<msg>::iterator it = file.ls.begin();
	for (; it != file.ls.end(); it++)
	{
		if ((CString)it->name.c_str() == name)
		{
			//添加库存
			it->num += m_num1;
			m_num1 = 0;
			UpdateData(FALSE);
			MessageBox(L"添加成功!");
		}
		//把商品同步到文件中
		file.WriteDocline();

	}

运行效果

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

void ADddDlg::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	m_num1 = 0;
	UpdateData(FALSE);
	m_combo.SetCurSel(0);
	OnCbnSelchangeCombo1();

}

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

void ADddDlg::OnBnClickedButton5()
{
	// TODO: 在此添加控件通知处理程序代码
	//拿到最新的数据
	UpdateData(TRUE);
	//验证添加新商品
	//验证数据的有效性
	if (m_name2.IsEmpty() || m_num2 <= 0 || m_price2 <= 0) 
	{
		MessageBox(L"你输入的信息有误!");
		return;
	}

	CInfoFile file;
	file.ReadDocline();

	file.Addline(m_name2, m_num2, m_price2);
	file.WriteDocline();
	MessageBox(L"商品添加成功!");

	//同步到左侧下拉框中
	m_combo.InsertString(0, m_name2);
	m_combo.SetCurSel(0);
	OnCbnSelchangeCombo1();

	//清空添加的新数据
	m_name2.Empty();
	m_num2 = 0;
	m_price2 = 0;
	UpdateData(FALSE);
}

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1112341.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【文献copilot】调用文心一言api对论文逐段总结

文献copilot&#xff1a;调用文心一言api对论文逐段总结 当我读文献的时候&#xff0c;感觉读得太慢了&#xff0c;看翻译软件翻译的又觉得翻译的不好。于是我就写了个程序辅助我读文献&#xff0c;它可以逐段总结&#xff0c;输出格式是&#xff1a;原文一句话总结分段总结&a…

Kafka与MySQL的组合使用

根据上面给出的student表&#xff0c;编写Python程序完成如下操作&#xff1a; &#xff08;1&#xff09;读取student表的数据内容&#xff0c;将其转为JSON格式&#xff0c;发送给Kafka&#xff1b; 创建Student表的SQL语句如下&#xff1a; create table student( sno ch…

基于深度学习网络的蔬菜水果种类识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1数据集准备 4.2构建深度学习模型 4.3模型训练 4.4模型评估 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 clc; clear; close all; wa…

【C++】C++学习(模板+排序+测时)

本文主要记录使用模板函数来编写排序算法&#xff0c;并计算运行时间。 模板函数&#xff08;Template Function&#xff09;是一种通用函数&#xff0c;可以在其定义时不指定具体的参数类型&#xff0c;在调用时再根据需要指定具体类型。模板函数可以接受不同类型的参数&…

057:mapboxGL中layout,paint等属性的函数表达说明

第057个 点击查看专栏目录 本篇文章是mapbox的layer中layout,paint等属性的函数表达 mapbox中 Function 是什么 函数 Function 可以作为其 layout布局类属性和 paint 绘制类属性的属性值。在使用 Function 作为属性值时,实际上是一个对象。 layers的3种函数类型 Function …

error: unable to read askpass response from

报错信息 解决方法&#xff1a; 中文&#xff1a;文件-->设置-->版本控制-->Git-->勾选使用凭证帮助程序 英文&#xff1a;File -> Settings -> Version Control -> Git / Check "User credential Helper" 因为我的webstrom是中文版的&#…

Simulink 最基础教程(四)模型参数与全局变量

4.1模型参数 上面介绍常用模块的时候&#xff0c;都是找到模块&#xff0c;双击模块&#xff0c;设置参数。这些参数都是模块参数。与之相对的&#xff0c;是模型参数。一些说明&#xff1a; 1&#xff09;模型参数和模块参数并不是隶属关系&#xff0c;而是配合关系。当模型参…

起重机控制电路接线 - 基础与进阶(修订中...)

1.基础篇 起重机电气接线 - 理论与实践 - 知乎1.现场配电箱这是一台10吨电动葫芦的电器箱。你能看出这个起重机用到了几个电机吗&#xff1f;先看空开和继电器。 电机为了控制正反转&#xff0c;一般每个电机需要用到两个继电器。这上面有7个继电器&#xff0c;所以&#xff0…

数字图像处理实验记录四(图像的空间域增强-平滑处理)

前言&#xff1a;要是是实验报告赶工的话&#xff0c;建议总结上网抄&#xff0c;或者重构我的总结&#xff0c;仅供学习参考&#xff0c;不要照抄 文章目录 一、基础知识1&#xff0c;噪声2&#xff0c;椒盐噪声3&#xff0c;高斯噪声4&#xff0c;滤波器5&#xff0c;均值滤…

[云原生1.] Docker容器的简单介绍和基本管理

1. Docker容器的基本概述 1.1 简介 Docker是一个开源的应用容器引擎&#xff0c;基于go语言开发并遵循了apache2.0协议开源。Docker是在Linux容器里运行应用的开源工具&#xff0c;是一种轻量级的“虚拟机”。Docker 的容器技术可以在一台主机上轻松为任何应用创建一个轻量级…

Unity之ShaderGraph如何实现无贴图水球效果

前言 我们今天来实现一个无贴图水球效果&#xff0c;如下图所示&#xff1a; 主要节点 UVSplit&#xff1a;可以获得UV在RGB三个颜色分别的分量 Remap&#xff1a;重映射节点 基于输入 In 值在输入In Min Max的 x 和 y 分量之间的线性插值&#xff0c;返回输入Out Min Max…

爬虫三大库

Requests库安装 Requests库的作用是请求网站获得网页数据 在pycharm中安装方式如下&#xff1a; 选择settings 选择Project Interpreter&#xff0c;单击号添加第三方库 BeautifulSoup库按同样方式安装。 Requests库 pycharm返回结果为<Response [200]>,说明请求网址成…

简单秒表设计仿真verilog跑表,源码/视频

名称&#xff1a;简单秒表设计仿真 软件&#xff1a;Quartus 语言&#xff1a;Verilog 代码功能&#xff1a; 秒表显示最低计时为10ms&#xff0c;最大为59:99&#xff0c;超出返回00&#xff1a;00 具有复位、启动、暂停三个按键 四个数码管分别显示4个时间数字。 演示…

了解 Elasticsearch 自动生成的文档 _id:重复是一个问题吗?

Elasticsearch 中自动生成的文档 ID 当你在未指定 ID 的情况下对文档建立索引时&#xff0c;Elasticsearch 会自动为该文档生成唯一的 ID。 该 ID 是 Base64 编码的 UUID&#xff0c;由多个部分组成&#xff0c;每个部分都有特定的用途。 ID 生成过程针对索引速度和存储效率进…

互联网Java工程师面试题·Java 总结篇·第九弹

目录 75、阐述 JDBC 操作数据库的步骤。 76、Statement 和 PreparedStatement 有什么区别&#xff1f;哪个性 能更好&#xff1f; 77、使用 JDBC 操作数据库时&#xff0c;如何提升读取数据的性能&#xff1f;如何提升更新数据的性能&#xff1f; 78、在进行数据库编程时&a…

git 查看本地秘钥

第一步&#xff1a; 1&#xff0c;打开终端或者命令行窗口&#xff0c;输入一下命令&#xff1a; cd ~/.ssh进入ssh目录 2&#xff0c;查看该目录下的所有文件&#xff0c;输入以下命令: ls -al该命令将显示ssh目录下的所有文件&#xff0c;包括秘钥文件和配置文件,如果不存…

100天掌握网络安全知识点!

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一、是市场需求量高&#xff1b; 二、则是发展相对成熟…

C++ Primer 第十一章 关联容器 重点解读

1 map自定义排序 #include <map> #include <iostream> #include <functional> using namespace std; int main() {function<bool(pair<int, int>, pair<int, int>)> cmp [&](pair<int, int> p1, pair<int, int> p2) -&g…

设计模式-综合应用(一)

介绍 使用jQuery做一个模拟购物车的示例 用到的设计模式 工厂模式 单例模式装饰器模式 观察者模式状态模式 模板方法模式 代理模式 UML类图

leetcode - 319. Bulb Switcher

Description There are n bulbs that are initially off. You first turn on all the bulbs, then you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it’s off or turning off if it’s on). For the ith round, you toggl…