MFC学习笔记--案例

创建

单个文档,MFC标准;
不使用传统停靠工具栏;
注意: 微软在vs2013中不建议使用c/c++传统函数:scanf,strcpy,sprintf等,所以直接使用这些库函数会提示c4996错误。

vs建议使用_s的函数,如scanf_s、strcpy_s,这些不是标准的c/c++函数,需要添加预定义**_CRT_SECURE_NO_WARNINGS**

项目–> 属性→c/c++→预处理器→预处理器定中添加_CRT_SECURE_NO_WARNINGS

添加图片

资源视图→icon→右键→添加资源→icon→导入,选择要导入的图片,一般提前导入到项目文件的res文件夹下,修改图片id;

修改图标

MainFrm框架中的初始化函数OnCreate中添加代码:

//修改图标
//窗口句柄,修改的内容(GCL_HICON 图标;GCL_CURSOR 光标;GCL_BACKGROUND 背景 )
SetClassLong(m_hWnd, GCL_HICON, (LONG)AfxGetApp()->LoadIconW(IDI_head));

运行会提示加载新的资源
在这里插入图片描述

修改标题

在MainFrm框架中的初始化函数OnCreate中添加代码:

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

在Doc类的OnNewDocument中添加代码

SetTitle(TEXT("大宝宝"));//设置左侧标题

设置窗口大小、位置

MainFrm框架中的初始化函数OnCreate中添加代码:

//设置窗口大小
	MoveWindow(0, 0, 800, 500);
	//设置居中显示
	CenterWindow();

文件操作类

需要添加文件操作类
头文件CInfoFile.h
注意txt文件的编码格式为ANSI

#pragma once

#include<list>
#include<fstream>
#include<iostream>
#include<string>

#define _F_LOGIN "./login.ini"
#define _F_STOCK "./stock.txt"

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;		//记录商品个数
};

cpp文件

#include"stdafx.h"
#include"CInfoFile.h"

CInfoFile::CInfoFile()
{
}

CInfoFile::~CInfoFile()
{}

//读取登录信息
void CInfoFile::ReadLogin(CString &name, CString &pwd)
{
	ifstream ifs;//创建文件输入对象
	ifs.open(_F_LOGIN);//打开文件

	char buf[1024] = { 0 };
	ifs.getline(buf, sizeof(buf));//读取一行内容
	name = CString(buf);		//char * 转换为CString

	ifs.getline(buf, sizeof(buf));
	pwd = CString(buf);
	ifs.close();//关闭文件
}

//修改密码
void CInfoFile::WritePwd(char *name, char *pwd)
{
	ofstream ofs; //创建文件输出对象
	ofs.open(_F_LOGIN);//打开文件

	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++;//商品数目加一

		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);//输出方式打开文件

	if (ls.size() > 0)//商品链表有内容才执行
	{
		ofs << "商品ID|商品名称|商品价格|库存" << 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();//关闭文件
}

//添加新商品
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、新建窗口DIALOG_LOGIN,为其创建类CDialog_Login;
2、创建主窗口代码在CApp类的IniInstence()函数中,引用登录窗口头文件,在此前创建新建的模态登录窗口;

	//模态方式创建登录窗口
	CDialog_Login loginw;
	loginw.DoModal();
	//创建主窗口
	CWinApp::InitInstance();

3、为用户名与密码输入框添加私有、value类型、CString类型的成员m_user与m_pwd,密码框可设置Password属性为true,密文显示;
4、登录按钮点击事件增加代码判断用户名密码,应用CInfoFile类;

void CDialog_Login::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	//登录按钮点击事件
	UpdateData(TRUE);//获取输入框最新值
	if (m_user.IsEmpty() || m_pwd.IsEmpty())
	{
		MessageBox(TEXT("输入内容不能为空"));
		return;
	}
	//获取值
	CInfoFile file;
	CString name, pwd;
	file.ReadLogin(name, pwd);
	if (name == m_user)
	{
		if (pwd == m_pwd)
		{
			//关闭当前窗口(登录窗口)
			CDialog::OnCancel();
		}
		else
		{
			MessageBox(TEXT("密码错误"));
		}
	}
	else
	{
		MessageBox(TEXT("用户名错误"));
	}
}

5、增加用户名、密码初始化默认值,在登录对话框选择属性,重写,OnInitionalDialog增加;

	//添加默认登录信息(正确的密码)
	CInfoFile file;
	CString name, pwd;
	file.ReadLogin(name, pwd);
	m_user = name;
	m_pwd = pwd;
	//更新到控件中
	UpdateColors(false);

6、取消按钮,退出系统

void CDialog_Login::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	//退出系统
	exit(0);
}

7、输入框回车时退出窗口问题,登录窗口类,右键属性,重新,OnOk,屏蔽CDialogEx::OnOK();
8、点击窗口右上角红叉时,触发WM_CLOSE消息,调用OnClose事件,执行代码CDialogEx::OnClose();屏蔽以上代码,添加exit(0);

void CDialog_Login::OnClose()
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	//CDialogEx::OnClose();
	exit(0);
}

静态拆分窗口

1、自定义两个类:CSelectView和CDisplayView(基类为视图类)。
CSelectView继承于CTreeView,CDisplayView继承于CFormView;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2、CMainFrame中声明CSplitterWnd类型对象

private:
	CSplitterWnd m_split;

3、重写框架类CMainFrame的OnCreateClient函数
需要包含头文件
#include"SelectView.h"
#include"DisplayView.h"

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
	// TODO: 在此添加专用代码和/或调用基类

	//return CFrameWnd::OnCreateClient(lpcs, pContext);//屏蔽源代码

	//拆分为一行两列
	m_split.CreateStatic(this, 1, 2);
	//左右两侧显示的内容
	m_split.CreateView(0, 0, RUNTIME_CLASS(CSelectView), CSize(200, 500), pContext);//0行0列
	m_split.CreateView(0, 1, RUNTIME_CLASS(CDisplayView), CSize(600, 500), pContext);//0行1列

	return TRUE;//自己拆分
}

树视图

1、CSelectView类中声明相应的变量

private:
	CTreeCtrl *m_treeCtrl;//树控件
	CImageList m_imageList;//图标列表

2、重写OnInitUpate函数
在这里插入图片描述

void CSelectView::OnInitialUpdate()
{
	CTreeView::OnInitialUpdate();

	// TODO: 在此添加专用代码和/或调用基类
	//初始化 树视图
	//获取树控件
	m_treeCtrl = &GetTreeCtrl();
	//1、准备图片集合
	HICON icon = AfxGetApp()->LoadIconW(IDI_device);
	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);

}

3、选项改变事件
在这里插入图片描述

void CSelectView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
	//获取当前选中项
	HTREEITEM item = m_treeCtrl->GetSelectedItem();
	//获取选中项中的内容
	CString str = m_treeCtrl->GetItemText(item);
	MessageBox(str);
}

操作界面

个人信息界面

1、ui设计,添加对话框资源(ID修改为DIALOG_USER),添加所需控件。窗口属性修改Border为None,Style为Child。
2、对话框,右键,添加类,类名:CUserDlg,基类选择CFormView。
3、根据需要,关联变量。身份关联CString m_user,用户名关联CString m_name,新密码关联m_newPwd,确定密码关联CString m_surePwd。身份、用户名为ReadOnly;新密码和确认为PassWord;

界面挂载

  1. 在CMainFrame框架类中自定义消息宏
//自定义消息
//WM_USER是用户自定义消息的起始值
//WM_USER+100是为了区分系统消息和用户消息,避免冲突

#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)
  1. 自定义消息处理函数
    声明:
    afx_msg LRESULT OnMyChange(WPARAM wParam, LPARAM lParam);

  2. 在CMainFrame框架类,在BEGIN_MESSAGE_MAP和 END_MESSAGE_MAP之间添加自定义消息入口,与自定义消息处理函数绑定。

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	ON_WM_CREATE()

	//ON_MESSAGE相应的是自定义消息
	//产生NM_X消息,自动调用OnMyChange函数
	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)

END_MESSAGE_MAP()
  1. 在CSelectView的OnTvnSelchanged函数中,发送自定义信号:
void CSelectView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
	//获取当前选中项
	HTREEITEM item = m_treeCtrl->GetSelectedItem();
	//获取选中项中的内容
	CString str = m_treeCtrl->GetItemText(item);
	if (str == TEXT("个人信息"))
	{
		//MessageBox(str);
		//需要包含框架类头文件#include“MainFrm.h"
		//CWnd::PostMessage将一个消息放入窗口的消息队列
		//AfxGetMainWnd():框架窗口对象的指针
		//NM_A:发送自定义消息
		//(WPARAM)NM_A:指定了附加的消息信息
		//(LPARAM)0:指定了附加的消息信息,此参数没有意义
		::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);
	}
	
	
}
  1. 完善OnMyChange的实现
LRESULT CMainFrame::OnMyChange(WPARAM wParam, LPARAM lParam)
{
	CCreateContext Context;
	if (wParam == NM_A)
	{
		//挂载界面
		//需要声明 CCreateContext Context
		//包含头文件 UserDlg.h
		Context.m_pNewViewClass = RUNTIME_CLASS(CUserDlg);
		Context.m_pCurrentFrame = this;
		Context.m_pLastView = (CFormView*)m_split.GetPane(0, 1);
		m_split.DeleteView(0, 1);
		m_split.CreateView(0, 1, RUNTIME_CLASS(CUserDlg), CSize(600, 500), &Context);
		CUserDlg *pNewView = (CUserDlg *)m_split.GetPane(0, 1);
		m_split.RecalcLayout();
		pNewView->OnInitialUpdate();
		m_split.SetActivePane(0, 1);

	}
	return 0;
 }

个人信息

CUserDlg右键,属性,重写,OnInitialUpdate:
在这里插入图片描述

void CUserDlg::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();
	//初始化
	m_user = TEXT("销售");
	//头文件#include "CInfoFile.h"
	CInfoFile info;
	CString name, pwd;
	info.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 info;
	CString name, pwd;
	info.ReadLogin(name, pwd);
	if (m_newPwd == pwd)
	{
		MessageBox(TEXT("新旧密码不能一样"));
		return;
	}
	
	CStringA temp; 
	CStringA temppwd;
	temp = name;
	temppwd = m_newPwd;
	info.WritePwd(temp.GetBuffer(), temppwd.GetBuffer());
	
	//info.WritePwd(name.GetBuffer, m_newPwd.GetBuffer);
	MessageBox(TEXT("修改成功"));
	//清空内容
	m_newPwd.Empty();
	m_surePwd.Empty();
	UpdateData(FALSE);
}

取消按钮

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

在这里插入图片描述

销售信息

  1. 添加对话框资源(ID修改为DIALOG_SELL),添加所需控件。
    在这里插入图片描述
    窗口属性中,Border改为None,Style改为Child;
    在这里插入图片描述

  2. 对话选中,右击,添加类,类名:CSellDlg,基类选择CFormView

  3. 控件关联变量
    商品名下拉框关联CComboBox m_combo,单价编辑框关联int m_price,个数编辑框关联int m_num,销售信息编辑框关联CString m_sellInfo。

  4. 界面挂载,在CMainFrame类中OnMyChange函数中,添加代码:

else if (wParam == NM_B)
	{

		Context.m_pNewViewClass = RUNTIME_CLASS(CSellDlg);
		Context.m_pCurrentFrame = this;
		Context.m_pLastView = (CFormView*)m_split.GetPane(0, 1);
		m_split.DeleteView(0, 1);
		m_split.CreateView(0, 1, RUNTIME_CLASS(CSellDlg), CSize(600, 500), &Context);
		CSellDlg *pNewView = (CSellDlg *)m_split.GetPane(0, 1);
		m_split.RecalcLayout();
		pNewView->OnInitialUpdate();
		m_split.SetActivePane(0, 1);

	}
  1. 功能实现
    初始化SellDlg的cpp中:
void CSellDlg::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();

	// TODO: 在此添加专用代码和/或调用基类
	//初始化销售管理
	//下拉框
	CInfoFile info;
	info.ReadDocline();
	for (list<msg>::iterator it = info.ls.begin();it != info.ls.end(); it++)
	{
		//遍历商品,把容器名称放到下拉框
		m_combo.AddString(CString(it->name.c_str()));
	}
	//默认选中第一个商品
	m_combo.SetCurSel(0);
	//更新第一个商品的数据
	OnCbnSelchangeCombo1();
}

下拉框切换事件:
在这里插入图片描述

void CSellDlg::OnCbnSelchangeCombo1()
{
	// TODO: 在此添加控件通知处理程序代码
	//切换商品触发事件
	//获取商品名称
	int index = m_combo.GetCurSel();
	CString name;
	m_combo.GetLBText(index, name);
	//根据商品名称获取该商品的价格和库存 并显示到控件中
	CInfoFile info;
	info.ReadDocline();
	for (list<msg>::iterator it = info.ls.begin();it != info.ls.end();it++)
	{
		if (CString(it->name.c_str()) == name)
		{
			m_price = it->price;
			m_left = it->num;
			//同步到控件中
			UpdateData(FALSE);
			return;
		}
	}
}

购买按钮的点击事件

void CSellDlg::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(TRUE);
	//购买功能实现
	if (m_num <= 0)
	{
		MessageBox(TEXT("购买数量需要大于0"));
		return;
	}
	if (m_num > m_left)
	{
		MessageBox(TEXT("购买数量需要小于库存"));
		return;
	}
	//获取商品名称
	int index = m_combo.GetCurSel();
	CString name;
	m_combo.GetLBText(index, name);

	CInfoFile info;
	info.ReadDocline();
	for (list<msg>::iterator it = info.ls.begin();it != info.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单价:%f ,\r\n个数:%d ,\r\n总价:%d"), name, m_price, m_num, m_price*m_num);
			m_sellInfo = str;
			UpdateData(FALSE);
			MessageBox(TEXT("购买成功"));
		}
	}
	//清空数据
	m_num = 0;
	m_sellInfo.Empty();
	UpdateData(FALSE);
	info.WriteDocline();
}

取消按钮:

void CSellDlg::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	//清空数据
	m_num = 0;
	m_sellInfo.Empty();
	//默认选中第一个商品
	m_combo.SetCurSel(0);
	//更新第一个商品的数据
	OnCbnSelchangeCombo1();
	UpdateData(FALSE);
}

库存信息

  1. 添加对话框(ID:DIALOG_INFO),修改窗口属性border,style
    View属性为Report(报表);

  2. 对话框添加类CInfoDlg,基类CFormView

  3. 添加控件关联变量,CListCtrl m_list;

  4. 界面挂载
    在CMainFrame类中OnMyChange函数中增加代码

	else if (wParam == NM_C)
	{

		Context.m_pNewViewClass = RUNTIME_CLASS(CInfoDlg);
		Context.m_pCurrentFrame = this;
		Context.m_pLastView = (CFormView*)m_split.GetPane(0, 1);
		m_split.DeleteView(0, 1);
		m_split.CreateView(0, 1, RUNTIME_CLASS(CInfoDlg), CSize(600, 500), &Context);
		CInfoDlg *pNewView = (CInfoDlg *)m_split.GetPane(0, 1);
		m_split.RecalcLayout();
		pNewView->OnInitialUpdate();
		m_split.SetActivePane(0, 1);

	}
  1. 实现
    初始化:
void CInfoDlg::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();

	// TODO: 在此添加专用代码和/或调用基类
	//设置扩展风格
	//LVS_EX_FULLROWSELECT选中整行,LVS_EX_GRIDLINES网格
	m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
	//初始化表头
	CString field[] = { _T("商品ID"),_T("商品名称"), _T("商品价格"), _T("库存数量") };
	for (int i = 0; i < sizeof(field) / sizeof(field[0]);i++)
	{
		m_list.InsertColumn(i,field[i],LVCFMT_CENTER,90);
	}
	//需要包含头文件infofile
	CInfoFile info;
	info.ReadDocline();
	//添加数据
	int i = 0;
	CString str;
	for (list<msg>::iterator it = info.ls.begin();it != info.ls.end();it++)
	{
		str.Format(_T("%d"), it->id);
		m_list.InsertItem(i, str);
		int column = 1;
		m_list.SetItemText(i, column++, (CString)it->name.c_str());
		str.Format(_T("%d"), it->price);
		m_list.SetItemText(i, column++, str);
		str.Format(_T("%d"), it->num);
		m_list.SetItemText(i, column++, str);
		i++;
	}
}

库存添加

  1. 添加对话框(ID:DIALOG_ADD),修改窗口属性border,style
    在这里插入图片描述

  2. 对话框添加类CADDDlg,基类CFormView

  3. 添加控件关联变量,添加个数:
    商品组合框:CComboBox m_combo,单价编辑框:int m_price1,个数编辑框:int m_num1;
    添加新商品:商品组合框:CString m_name2,单价编辑框:int m_price2,个数编辑框:int m_num2。

  4. 界面挂载
    在CMainFrame类中OnMyChange函数中增加代码

	else if (wParam == NM_D)
	{

		Context.m_pNewViewClass = RUNTIME_CLASS(CADDDlg);
		Context.m_pCurrentFrame = this;
		Context.m_pLastView = (CFormView*)m_split.GetPane(0, 1);
		m_split.DeleteView(0, 1);
		m_split.CreateView(0, 1, RUNTIME_CLASS(CADDDlg), CSize(600, 500), &Context);
		CADDDlg *pNewView = (CADDDlg *)m_split.GetPane(0, 1);
		m_split.RecalcLayout();
		pNewView->OnInitialUpdate();
		m_split.SetActivePane(0, 1);

	}
  1. 功能实现
    初始化和下拉框变化事件代码同销售管理界面。
    添加已有商品按钮事件
void CADDDlg::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	//添加商品功能实现
	UpdateData(TRUE);
	if (m_num1 <= 0)
	{
		MessageBox(TEXT("添加数量需要大于0"));
		return;
	}
	//获取名称
	int index = m_combo.GetCurSel();
	CString str;
	m_combo.GetLBText(index, str);
	CInfoFile info;
	info.ReadDocline();
	for (list<msg>::iterator it = info.ls.begin();it != info.ls.end();it++)
	{
		if (CString(it->name.c_str()) == str)
		{
			//添加库存
			it->num += m_num1;
			m_num1 = 0;
			UpdateData(FALSE);
			MessageBox(TEXT("添加成功"));
		}
	}
	//商品同步到文件中
	info.WriteDocline();
}

取消按钮

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

添加新商品按钮事件

void CADDDlg::OnBnClickedButton6()
{
	// TODO: 在此添加控件通知处理程序代码
	//验证
	UpdateData(TRUE);
	if (m_name2.IsEmpty())
	{
		MessageBox(TEXT("商品名称不能为空"));
		return;
	}
	if (m_num2 <=0)
	{
		MessageBox(TEXT("商品数量错误"));
		return;
	}
	if (m_price2 <= 0)
	{
		MessageBox(TEXT("商品价格错误"));
		return;
	}
	CInfoFile info;
	info.ReadDocline();
	info.Addline(m_name2, m_num2, m_price2);
	info.WriteDocline();
	MessageBox(TEXT("新商品添加成功"));
	
	//同步到左侧数据
	m_combo.InsertString(0, m_name2);
	m_combo.SetCurSel(0);
	OnCbnSelchangeCombo1();

	m_name2.Empty();
	m_num2 = 0;
	m_price2 = 0;
	UpdateData(FALSE);
}

取消按钮

m_name2.Empty();
	m_num2 = 0;
	m_price2 = 0;
	UpdateData(FALSE);

库存删除

  1. 添加对话框(ID:DIALOG_DEL),修改窗口属性border,style
    在这里插入图片描述

  2. 对话框添加类CDelDlg,基类CFormView

  3. 添加控件关联变量
    商品组合框:CComboBox m_combo,单价编辑框:int m_price,个数编辑框:int m_num。

  4. 界面挂载
    在CMainFrame类中OnMyChange函数中增加代码

	else if (wParam == NM_E)
	{

		Context.m_pNewViewClass = RUNTIME_CLASS(CDelDlg);
		Context.m_pCurrentFrame = this;
		Context.m_pLastView = (CFormView*)m_split.GetPane(0, 1);
		m_split.DeleteView(0, 1);
		m_split.CreateView(0, 1, RUNTIME_CLASS(CDelDlg), CSize(600, 500), &Context);
		CDelDlg *pNewView = (CDelDlg *)m_split.GetPane(0, 1);
		m_split.RecalcLayout();
		pNewView->OnInitialUpdate();
		m_split.SetActivePane(0, 1);

	}
  1. 功能实现
    初始化
void CDelDlg::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();

	// TODO: 在此添加专用代码和/或调用基类
	//读取文件,获取商品名,给组合框添加字符串
	//需要包含头文件
	CInfoFile info;
	info.ReadDocline();
	for (list<msg>::iterator it = info.ls.begin();it != info.ls.end();it++)
	{
		m_combo.AddString(CString(it->name.c_str()));
	}
	//设置默认选中项
	m_combo.SetCurSel(0);
	OnCbnSelchangeCombo1();
}

下拉框选项变化事件

void CDelDlg::OnCbnSelchangeCombo1()
{
	// TODO: 在此添加控件通知处理程序代码
	int index = m_combo.GetCurSel();
	CString name;
	m_combo.GetLBText(index, name);
	CInfoFile info;
	info.ReadDocline();
	for (list<msg>::iterator it = info.ls.begin();it != info.ls.end();it++)
	{
		if (CString(it->name.c_str()) == name)
		{
			m_left =it->num;
			m_price = it->price;
			m_num = 0;
			UpdateData(FALSE);
			break;
		}
	}
}

确定按钮

void CDelDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(TRUE);
	if (m_num <= 0 || m_num > m_left)
	{
		MessageBox(TEXT("请输入正确的数量"));
		return;
	}
	CInfoFile info;
	info.ReadDocline();
	//修改余量
	int index = m_combo.GetCurSel();
	CString name;
	m_combo.GetLBText(index, name);

	for (list<msg>::iterator it = info.ls.begin();it != info.ls.end();it++)
	{
		if (CString(it->name.c_str()) == name)
		{
			it->num -= m_num;
			m_left = it->num;
			UpdateData(FALSE);
			MessageBox(TEXT("修改成功"));
			break;
		}
	}
	info.WriteDocline();
	//清空
	m_combo.SetCurSel(0);
	OnCbnSelchangeCombo1();
	m_num = 0;
	UpdateData(FALSE);
}

菜单栏

资源视图–>项目中的menu;

  1. 可以直接界面中输入来增加菜单、子菜单,或者右键选择删除,拖动可以修改位置

  2. 菜单项右键,添加事件处理程序
    在这里插入图片描述
    选择处理的窗口类,函数名称可以修改
    在这里插入图片描述

  3. 在生成的函数中添加代码


void CMainFrame::On32771()
{
	// TODO: 在此添加命令处理程序代码
	//退出按钮
	exit(0);
}


void CMainFrame::On32772()
{
	// TODO: 在此添加命令处理程序代码
	//个人信息

		//CWnd::PostMessage将一个消息放入窗口的消息队列
		//AfxGetMainWnd():框架窗口对象的指针
		//NM_A:发送自定义消息
		//(WPARAM)NM_A:指定了附加的消息信息
		//(LPARAM)0:指定了附加的消息信息,此参数没有意义
		::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_A, (WPARAM)NM_A, (LPARAM)0);
	
}


void CMainFrame::On32773()
{
	// TODO: 在此添加命令处理程序代码
	//销售管理
	::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_B, (WPARAM)NM_B, (LPARAM)0);
}


void CMainFrame::On32774()
{
	// TODO: 在此添加命令处理程序代码
	//库存信息
	::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_C, (WPARAM)NM_C, (LPARAM)0);
}


void CMainFrame::On32775()
{
	// TODO: 在此添加命令处理程序代码
	//库存添加
	::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_D, (WPARAM)NM_D, (LPARAM)0);
}


void CMainFrame::On32776()
{
	// TODO: 在此添加命令处理程序代码
	//库存删除
	::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_E, (WPARAM)NM_E, (LPARAM)0);
}

文化建设

来时无迹去无踪
去与来时是一同
何须更问浮生事
只此浮生是梦中
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值