MFC——对话框的创建及使用

文章目录

  • MFC对话框的创建实例
    • 对话框程序的创建过程:
    • 对话框应用程序框架介绍
      • 设计界面和工具箱
  • MFC常用控件
    • 静态文本框CStatic
    • 普通按钮 CButton
    • 编辑框 CEdit
    • 组合框(下拉框)CComboBox
    • 列表控件 CListCtrl
    • 树控件 CTreeCtrl
    • 标签控件 CTabCtrl
  • 综合案例
    • 项目总体框架
    • 文件处理
    • 登录对话框
    • 静态拆分窗口
    • 左侧选择界面树视图实现
      • 功能节点消息处理
    • 个人信息管理窗口
    • 销售管理窗口
    • 库存信息窗口
    • 库存添加窗口
    • 库存删除窗口
    • 菜单栏实现
    • 最终实现


MFC对话框的创建实例

对话框程序的创建过程:

  • 选择“文件 | 新建 | 项目”菜单;

  • 在“新建项目”对话框中,选择“ MFC 应用程序 ”,输入工程名称,选择“确定”。
    MFC——对话框的创建及使用_第1张图片

  • 选择“ 基于对话框”,即创建基于对话框的应用程序,选择“完成”。
    MFC——对话框的创建及使用_第2张图片

对话框应用程序框架介绍

资源视图
用 AppWizard 创建基于对话框的应用程序框架(假定工程名为 Dialog )后,项目工作区上增加了一个“资源视图”选项卡。
MFC——对话框的创建及使用_第3张图片
或者,通过视图找到“资源视图”选项卡:
MFC——对话框的创建及使用_第4张图片

在 MFC中,与用户进行交互的对话框界面被认为是一种资源。展开“Dialog”,可以看到有一个ID为IDD_ DIALOG _DIALOG(中间部分(DIALOG)与项目名称相同)的资源,对应中间的对话框设计界面。不管在何时,只要双击对话框资源的ID,对话框设计界面就会显示在中间。

类视图
在类视图中,可以看到生成了3 个类:CAboutDlg、CDialogApp和CDialogDlg。
MFC——对话框的创建及使用_第5张图片

  • CAboutDlg:对应生成的版本信息对话框。
  • CDialogApp:应用程序类,从 CWinApp 继承过来,封装了初始化、运行、终止该程序的代码。
  • CDialogDlg:对话框类,从CdialogEx继承过来的,在程序运行时看到的对话框就是它的一个具体对象。
  • DoDataExchange函数:该函数主要完成对话框数据的交换和校验。
  • OnInitDialog函数:相当于对对话框进行初始化处理。

设计界面和工具箱

MFC——对话框的创建及使用_第6张图片
模态对话框
当模态对话框显示时,程序会暂停执行,直到关闭这个模态对话框之后,才能执行程序中的其他任务。

  • 1)通过工具箱在界面上放一个Button,双击此按钮即可跳转到按钮处理函数:

MFC——对话框的创建及使用_第7张图片

//按钮处理函数
void CDialogDlg::OnBnClickedButton1()
{
	// TODO:  在此添加控件通知处理程序代码
}
  • 2)资源视图 -> Dialog -> 右击 -> 插入 Dialog:

MFC——对话框的创建及使用_第8张图片MFC——对话框的创建及使用_第9张图片

  • 3)修改对话框ID:
    MFC——对话框的创建及使用_第10张图片

  • 4)点击对话框模板 -> 右击 -> 添加类:
    MFC——对话框的创建及使用_第11张图片MFC——对话框的创建及使用_第12张图片

  • 5)类视图中多了一个自定义类:
    MFC——对话框的创建及使用_第13张图片

6)按钮处理函数创建对话框,以模态方式运行。
实现模态对话框的创建需要调用CDialog类的成员函数CDialog::DoModel,该函数的功能就是创建并显示一个对话框:

//启动模态对话框按钮
void CDialogDlg::OnBnClickedButton1()
{
	//需要包含头文件:#include "DlgExec.h"
	CDlgExec dlg;
	dlg.DoModal(); //以模态方式运行
}

非模态对话框
当非模态对话框显示时,运行转而执行程序中的其他任务,而不用关闭这个对话框。

图形界面操作过程和模态对话框一样,只是,非模态对话框实现方式不一样,先创建(CDialog::Create)一次,然后再显示(CWnd::ShowWindow)。

  • 1)主对话框.h类中声明对话框对象:
    MFC——对话框的创建及使用_第14张图片

  • 2)创建对话框放在主对话框类的构造函数或OnCreate()函数,目的只创建一次对话框:

//主对话框构造函数
CDialogDlg::CDialogDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CDialogDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	m_dlg.Create(IDD_DIALOG_SHOW); //IDD_DIALOG_SHOW为对话框ID
}
  • 3)按钮处理函数显示对话框:
//启动非模态对话框按钮
void CDialogDlg::OnBnClickedButton2()
{
	// TODO:  在此添加控件通知处理程序代码

	m_dlg.ShowWindow(SW_SHOWNORMAL); //显示非模态对话框
}

MFC常用控件

静态文本框CStatic

MFC——对话框的创建及使用_第15张图片静态文本框是最简单的控件,它主要用来显示文本信息,不能接受用户输入,一般不需要连接变量,也不需要处理消息。

静态文本框的重要属性有:

  • ID:所有静态文本框的缺省ID都是IDC_STATIC,静态ID,不响应任何消息(事件)
  • Caption:修改显示的内容
接口 功能
CWnd::SetWindowText 设置控件内容
CWnd::GetWindowText 获取控件内容
CStatic::SetBitmap 设置位图(后缀为bmp的图片)

关联控件变量
由于XXX_STATIC静态ID是不能关联变量,故需把ID修改后,再关联变量:
MFC——对话框的创建及使用_第16张图片MFC——对话框的创建及使用_第17张图片MFC——对话框的创建及使用_第18张图片在主对话框类OnInitDialog()中,完成相应接口测试:

MFC——对话框的创建及使用_第19张图片

//设置静态控件内容为Tom
	m_label.SetWindowText(TEXT("Tom"));

	//获取静态控件的内容
	CString str;
	m_label.GetWindowText(str);
	MessageBox(str);

	//设置静态控件窗口风格为位图居中显示
	m_label.ModifyStyle(0xf, SS_BITMAP | SS_CENTERIMAGE);

	//通过路径获取bitmap句柄
#define HBMP(filepath,width,height) (HBITMAP)LoadImage(AfxGetInstanceHandle(),filepath,IMAGE_BITMAP,width,height,LR_LOADFROMFILE|LR_CREATEDIBSECTION)

	//静态控件设置bitmap
	m_label.SetBitmap(HBMP(TEXT("./1.bmp"), 300, 250));

普通按钮 CButton

MFC——对话框的创建及使用_第20张图片按钮是最常见的、应用最广泛的一种控件。在程序执行期间,当单击某个按钮后就会执行相应的消息处理函数。

按钮的主要属性是Caption,来设置在按钮上显示的文本。

命令按钮处理的最多的消息是:BN_CLICKED,双击按钮即可跳转到处理函数。或者,通过按钮属性 -> 控制事件 -> 选择所需事件,添加处理函数:
MFC——对话框的创建及使用_第21张图片

//按钮BN_CLICKED事件处理函数
void CMFCApplication2Dlg::OnBnClickedButton1()
{
	// TODO:  在此添加控件通知处理程序代码
}

常用接口:

接口 功能
CWnd::SetWindowText 设置控件内容
CWnd::GetWindowText 获取控件内容
CWnd::EnableWindow 设置控件是否变灰

关联控件变量
MFC——对话框的创建及使用_第22张图片在主对话框类OnInitDialog()中,完成相应接口测试:
MFC——对话框的创建及使用_第23张图片

//获取按钮的内容
	CString str;
	m_button.GetWindowText(str);
	MessageBox(str);

	//设置按钮内容
	m_button.SetWindowText(TEXT("^_^"));

	//设置按钮状态为灰色
	m_button.EnableWindow(FALSE);
	m_button.EnableWindow(TRUE);

编辑框 CEdit

MFC——对话框的创建及使用_第24张图片
常用属性设置:

属性 含义
Number True只能输入数字
Password True密码模式
Want return True接收回车键,自动换行,只有在多行模式下,才能换行
Multiline True多行模式
Auto VScroll True 当垂直方向字符太多,自动出现滚动条,同时设置Vertical Scroll才有效
Vertical Scroll True当垂直方向字符太多,自动出现滚动条,和Auto VScroll配合使用
Horizontal Scroll True当垂直方向字符太多,自动出现滚动条,和Auto HScroll配合使用
Read Only True 只读

常用接口:

接口 功能
CWnd::SetWindowText 设置控件内容
CWnd::GetWindowText 获取控件内容

关联控件变量
MFC——对话框的创建及使用_第25张图片在主对话框类OnInitDialog()中,完成相应接口测试:

//设置按钮内容
	m_edit.SetWindowText(TEXT("this is a test"));

	//获取按钮的内容
	CString str;
	m_edit.GetWindowText(str);
	MessageBox(str);

管理基本类型变量
MFC——对话框的创建及使用_第26张图片若一个编辑框连接了一个Value类别的变量,则该变量就表示这个编辑框,编辑框中显示的内容就是变量的值。

但是,改变了编辑框的内容并不会自动更新对应的变量的值,同样,改变了变量的值也不会自动刷新编辑框的内容。若要保持一致,需要使用UpdateData()函数更新:

  • 若编辑框的内容改变了,则应使用语句UpdateData(TRUE) 获取对话框数据
  • 若变量的值改变了,则应使用语句UpdateData(FALSE) 初始化对话框控件
    MFC——对话框的创建及使用_第27张图片在主对话框类OnInitDialog()中,完成相应代码测试:
	m_e1 = 10.11;
	UpdateData(FALSE); //FALSE说明把m_e1的值更新到对应的控件中

	UpdateData(TRUE); //TRUE说明把控件的值更新到m_e1变量中

组合框(下拉框)CComboBox

MFC——对话框的创建及使用_第28张图片常用属性设置:

属性 含义
data 设置内容,不同内容间用英文的分号“;”分隔
type 显示风格
Sort True 内容自动排序

常用接口:

接口 功能
CComboBox::AddString 组合框添加一个字符串
CComboBox::SetCurSel 设置当前选择项(当前显示第几项),下标从0开始
CComboBox::GetCurSel 获取组合框中当前选中项的下标
CComboBox::GetLBText 获取指定位置的内容
CComboBox::DeleteString 删除指定位置的字符串
CComboBox::InsertString 在指定位置插入字符串

关联控件变量后,测试接口:
MFC——对话框的创建及使用_第29张图片

//添加字符串内容
	m_combo.AddString(TEXT("可乐")); 
	m_combo.AddString(TEXT("雪碧"));

	m_combo.SetCurSel(1);//显示显示第1项

	//获取组合框中当前选中项的下标
	int index = m_combo.GetCurSel(); 
	CString str;
	m_combo.GetLBText(index, str); //获取指定下标的内容
	MessageBox(str);
	m_combo.DeleteString(0); //删除第0项字符串
	
	m_combo.InsertString(0, _T("hello")); //在第0位置插入“hello”

组合框常用的事件为:CBN_SELCHANGE,当选择组合框某一项时,自动触发此事件。
MFC——对话框的创建及使用_第30张图片

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

列表控件 CListCtrl

MFC——对话框的创建及使用_第31张图片常用属性设置:view -> Report(报表方式)
MFC——对话框的创建及使用_第32张图片

常用接口:

接口 功能
CListCtrl::SetExtendedStyle 设置列表风格
CListCtrl::GetExtendedStyle 获取列表风格
CListCtrl::InsertColumn 插入某列内容,主要用于设置标题
CListCtrl::InsertItem 在某行插入新项内容
CListCtrl::SetItemText 设置某行某列的子项内容
CListCtrl::GetItemText 获取某行某列的内容

关联控件变量后,测试接口:
MFC——对话框的创建及使用_第33张图片

//设置风格样式
	//LVS_EX_GRIDLINES 网格
	//LVS_EX_FULLROWSELECT 选中整行
	m_list.SetExtendedStyle(m_list.GetExtendedStyle()
		| LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);

	//插入标题
	CString head[] = { TEXT("姓名"), TEXT("年龄"), TEXT("性别") };

	//插入列
	m_list.InsertColumn(0, head[0], LVCFMT_LEFT, 100);
	m_list.InsertColumn(1, head[1], LVCFMT_LEFT, 100);
	m_list.InsertColumn(2, head[2], LVCFMT_LEFT, 100);

	//插入正文内容,先确定行,再确定列
	for (int i = 0; i < 10; i++)
	{
		CString str;
		str.Format(TEXT("张三_%d"), i );

		//确定行
		m_list.InsertItem(i, str);

		//设置列
		int j = 0;
		m_list.SetItemText(i, ++j, TEXT("男"));
		m_list.SetItemText(i, ++j, TEXT("23"));
	}

程序效果图:
MFC——对话框的创建及使用_第34张图片

树控件 CTreeCtrl

MFC——对话框的创建及使用_第35张图片
常用属性设置:

属性 含义
has buttons True 有展开按钮
has lines True 有展开线
lines at root True 有根节点

常用接口:

接口 功能
AfxGetApp() 获取应用程序对象指针
CWinApp::LoadIcon 加载自定义图标
CImageList::Create 创建图像列表
CImageList::Add 图像列表追加图标
CTreeCtrl::SetImageList 设置图形状态列表
CTreeCtrl::InsertItem 插入节点
CTreeCtrl::SelectItem 设置默认选中项
CTreeCtrl::GetSelectedItem 获取选中项
CTreeCtrl::GetItemText 获取某项内容
  • 关联控件变量
    MFC——对话框的创建及使用_第36张图片
  • 添加图标资源(icon)
    MFC——对话框的创建及使用_第37张图片
  • 资源视图 -> Icon -> 添加资源:
    MFC——对话框的创建及使用_第38张图片
  • 导入ico文件
    MFC——对话框的创建及使用_第39张图片MFC——对话框的创建及使用_第40张图片MFC——对话框的创建及使用_第41张图片
  • 3)通过代码加载图标
	//加载图标
	HICON icon[3];
	icon[0] = AfxGetApp()->LoadIconW(IDI_ICON1);
	icon[1] = AfxGetApp()->LoadIconW(IDI_ICON2);
	icon[2] = AfxGetApp()->LoadIconW(IDI_ICON3);

  • 创建图像列表
    .h文件中定义图形列表(CImageList)对象
CImageList m_imageList; //图像列表

.cpp文件中OnInitDialog()函数中完成图像列表的创建、图标的追加

//图像列表,程序完毕不能释放, 创建
	//30, 30: 图片的宽度和高度
	//ILC_COLOR32:样式
	// 3, 3: 有多少图片写多少
	m_imageList.Create(30, 30, ILC_COLOR32, 3, 3);

	//给图像列表添加图片
	for (int i = 0; i < 3; i++)
	{
		//图片列表加载图标
		m_imageList.Add(icon[i]);
	}

  • 树控件的相应操作
	//树控件设置图片列表
	m_treeCtrl.SetImageList(&m_imageList, TVSIL_NORMAL);

	//给树创建节点
	//根节点,父节点,子节点
	HTREEITEM root = m_treeCtrl.InsertItem(TEXT("中国"), 0, 0, NULL);
	HTREEITEM fathter = m_treeCtrl.InsertItem(TEXT("北京"), 1, 1, root);
	HTREEITEM son = m_treeCtrl.InsertItem(TEXT("海淀"), 2, 2, fathter);

	//设置某个节点被选中
	m_treeCtrl.SelectItem(fathter);

程序效果图
MFC——对话框的创建及使用_第42张图片树控件常用事件为:TVN_SELCHANGED,当选择某个节点时,自动触发此事件。
MFC——对话框的创建及使用_第43张图片

void CMy01_TreeCtrlDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
	// TODO:  在此添加控件通知处理程序代码
	*pResult = 0;

	HTREEITEM selItem;
	//获得选择项
	selItem = m_treeCtrl.GetSelectedItem();
	//获取选中的内容
	CString cs = m_treeCtrl.GetItemText(selItem);
	MessageBox(cs);
}

标签控件 CTabCtrl

MFC——对话框的创建及使用_第44张图片

  • 在UI工具箱拖放 Tab Control
    MFC——对话框的创建及使用_第45张图片

  • 把 TabSheet.h和TabSheet.cpp 放在项目文件同级目录,并且添加到工程目录中
    MFC——对话框的创建及使用_第46张图片

  • 给UI上 Tab Control 关联Control类型(CTabSheet)
    MFC——对话框的创建及使用_第47张图片

  • 添加对话框

    • 资源视图 -> Dialog -> 右击 -> 插入 Dialog
    • 设置相应属性:
      Style -> Child (子窗口)
      Border -> None (无边框)
    • 自定义类:点击对话框模板 -> 右击 -> 添加类(MyDlg1、MyDlg2)
    • 主对话框类中, 定义自定义类对象,需要相应头文件
	//给tab控件添加对话框
//IDD_DIALOG1为dlg1资源ID
	m_tabCtrl.AddPage(TEXT("系统管理"), &dlg1, IDD_DIALOG1); 

//IDD_DIALOG1为dlg2资源ID
	m_tabCtrl.AddPage(TEXT("系统设置"), &dlg2, IDD_DIALOG2); 

	//显示tab控件
	m_tabCtrl.Show();

程序效果图
MFC——对话框的创建及使用_第48张图片

综合案例

  • 通过MFC向导创建综合案例(销售信息管理系统)项目。

项目总体框架

整个项目分为登录界面、主界面。而主界面分裂成两个界面显示,分别为左侧选择界面和右侧显示界面。功能上分别有个人信息管理、销售管理窗口、库存信息窗口、库存添加窗口、库存删除窗口以及菜单栏。

文件处理

项目中使用到将数据保存到文件进行保存的功能,这部分设计成一个单独的文件处理类CInfoFile。
在解决方案中添加类–>CInfoFile。

  • CInfoFole.h
#pragma once

#include 
#include 
#include 
#include 
#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),添加所需控件:
MFC——对话框的创建及使用_第49张图片选中对话框 -> 右击 -> 添加类 -> 类名:CLoginDlg,添加关联变量。
MFC——对话框的创建及使用_第50张图片具体功能实现:

  • 需要重写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;
}
  • 显示如下:
    MFC——对话框的创建及使用_第51张图片

左侧选择界面树视图实现

  • 添加树视图图标。
  • 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);


}

MFC——对话框的创建及使用_第52张图片

功能节点消息处理

当左侧窗口点击树节点,会发送对应的消息给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:
    MFC——对话框的创建及使用_第53张图片MFC——对话框的创建及使用_第54张图片
  • 选中对话框 -> 右击 -> 添加类 -> 类名:CUserDlg,基类选择CFormView
  • 根据需求,控件关联所需变量
    身份编辑区关联CString m_user,用户名编辑框关联CString m_name,
    新密码编辑框关联CString m_newPwd,确定密码编辑框关联CString m_surePwd。
    MFC——对话框的创建及使用_第55张图片
  • 重写界面初始化函数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);
}

销售管理窗口

  • 添加新对话框,
    MFC——对话框的创建及使用_第56张图片
  • 选中对话框 -> 右击 -> 添加类 -> 类名:CSellDlg,基类选择CFormView
  • 根据需求,控件关联所需变量
    商品名组合框关联CComboBox m_combo,单价编辑框关联int m_price,个数编辑框关联int m_num,销售信息编辑框关联CString m_sellInfo。
    MFC——对话框的创建及使用_第57张图片
  • 重写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(报表表模式):
    MFC——对话框的创建及使用_第58张图片
  • 选中对话框 -> 右击 -> 添加类 -> 类名: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),添加所需控件。
    MFC——对话框的创建及使用_第59张图片
  • 选中对话框 -> 右击 -> 添加类 -> 类名:CAddDlg,基类选择CFormView
  • 根据需求,控件关联所需变量添加个数:商品组合框关联CComboBox m_combo,单价编辑框关联int m_price1,个数编辑框关联int m_num1。
    添加新产品:商品组合框关联CString m_name2,单价编辑框关联int m_price2,个数编辑框关联int m_num2。
    MFC——对话框的创建及使用_第60张图片
  • 重写 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),添加所需控件。
    MFC——对话框的创建及使用_第61张图片
  • 选中对话框 -> 右击 -> 添加类 -> 类名:CDelDlg,基类选择CFormView
  • 根据需求,控件关联所需变量
    商品名组合框关联CComboBox m_combo,单价编辑框关联int m_price,个数编辑框关联int m_num。
    MFC——对话框的创建及使用_第62张图片
  • 重写 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,删除掉所有默认(帮助除外):
    MFC——对话框的创建及使用_第63张图片MFC——对话框的创建及使用_第64张图片
  • 右键菜单栏项,添加事件处理程序,选择COMMAND 消息类型,添加至CMainFrame框架类中。
    MFC——对话框的创建及使用_第65张图片MFC——对话框的创建及使用_第66张图片
  • 处理事件函数中发送消息给主框架实现界面切换。

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);
}

最终实现

你可能感兴趣的:(MFC)