MFC工控项目实例之六CFile添加菜单栏

本程序基于前期我的博客文章《MFC工控项目实例之五CFile类读写系统参数》

添加两个对话框如下

具体添加菜单栏参考我的博客文章MFC_ CFile类实现下拉菜单读写实例(源码下载)

这里给出相关代码

在 SEAL_PRESSURE.h文件中添加

cpp 复制代码
#include <afxtempl.h>
...
class CProductPara
{
public:
	union
	{
		struct
		{
			char	m_strTypeName[24];
			char	m_strBrand[24];			
			char	m_strRemark[64];
		};
		char len[1024];
	};
};
class CSEAL_PRESSUREApp : public CWinApp
{
public:
	...

	int m_nProductSel;
	CArray<CProductPara,CProductPara> m_allPara;
	CString	m_strWorkPath,m_strCurDataPath,m_strDataPath;
	CString m_strControlCFGFileName;
	CString	m_strTypeCFGFileName;
    void LoadTypeCFG(void);
	void SaveTypeCFG(void);
	...

在 SEAL_PRESSUREDlg.h文件中添加

cpp 复制代码
class CSEAL_PRESSUREDlg : public CDialog
{
// Construction
public:
	...
	CMenu m_menuType;
    int m_nProductSel;
	int m_nTypeIndex;
	CArray<CProductPara,CProductPara> m_allPara;
	CString	m_strWorkPath;
	CString m_strControlCFGFileName;
	CString	m_strTypeCFGFileName;
	CBitmap m_bmSel,m_bmList;
	void OnTypeChange(UINT nID);
    void UpdateButton(void);
    ...
    }

在TypDlg.h文件中添加

cpp 复制代码
class CTypDlg : public CDialog
{
// Construction
public:
	CProductPara * m_pPara;
	BOOL UpdatePara(BOOL);
	CTypDlg(CWnd* pParent = NULL);   // standard constructor
    CMenu m_menuType;
    int m_nProductSel;
	int m_nTypeIndex;
// Dialog Data
	//{{AFX_DATA(CTypDlg)
	enum { IDD = IDD_TYP_CHOICE };
	CListCtrl	m_ctrlType;
	//}}AFX_DATA


// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CTypDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:

	// Generated message map functions
	//{{AFX_MSG(CTypDlg)
	virtual BOOL OnInitDialog();
	afx_msg void OnButton1();
	afx_msg void OnButton2();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

在TypData.h文件中添加

cpp 复制代码
class CTypData : public CDialog
{
// Construction
public:
	CProductPara * m_pPara;
	BOOL UpdatePara(BOOL);
	CTypData(CWnd* pParent = NULL);   // standard constructor

// Dialog Data
	//{{AFX_DATA(CTypData)
	enum { IDD = IDD_TYP_DATA };
	CString	m_strTypeName;
	CString	m_strBrand;
	CString	m_strRemark;
		// NOTE: the ClassWizard will add data members here
	//}}AFX_DATA


// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CTypData)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:

	// Generated message map functions
	//{{AFX_MSG(CTypData)
    virtual BOOL OnInitDialog();
	virtual void OnOK();
		// NOTE: the ClassWizard will add member functions here
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

TypDlg.cpp文件中代码

cpp 复制代码
// TypDlg.cpp : implementation file
//

#include "stdafx.h"
#include "SEAL_PRESSURE.h"

#include "TypDlg.h"
#include "TypData.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CTypDlg dialog


CTypDlg::CTypDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTypDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTypDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CTypDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTypDlg)
	DDX_Control(pDX, IDC_LIST1, m_ctrlType);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CTypDlg, CDialog)
	//{{AFX_MSG_MAP(CTypDlg)
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)

	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CTypDlg message handlers

BOOL CTypDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	DWORD dwExStyles = m_ctrlType.GetExtendedStyle();
	m_ctrlType.SetExtendedStyle(
		dwExStyles |
		LVS_EX_GRIDLINES |
		LVS_EX_FULLROWSELECT | 
		LVS_EX_FLATSB |
		LVS_EX_ONECLICKACTIVATE
		);


	LVCOLUMN cloumn;
	int i;
	cloumn.mask = LVCF_TEXT|LVCF_WIDTH;
	cloumn.pszText = "型号名称";
	cloumn.cx = 90;
	i = m_ctrlType.InsertColumn(0,&cloumn);
	cloumn.mask = LVCF_TEXT|LVCF_WIDTH;
	cloumn.pszText = "产品商标";
	cloumn.cx = 90;
	i = m_ctrlType.InsertColumn(1,&cloumn);
	cloumn.pszText = "      备        注";
	cloumn.cx = 160;
	i = m_ctrlType.InsertColumn(2,&cloumn);
 
int nItem;
	LV_ITEM item;
	item.mask = LVIF_TEXT|LVIF_IMAGE;

	char buf[255];
	for(i = 0; i < theApp.m_allPara.GetSize() ; i ++)
	{
		nItem = m_ctrlType.GetItemCount();
		item.iItem = nItem;
		item.iSubItem = 0;
		sprintf(buf,"%s",theApp.m_allPara[i].m_strTypeName);
		item.pszText = buf;
		item.iImage = 0;
		m_ctrlType.InsertItem(&item);
		item.iSubItem = 1;
		sprintf(buf,"%s",theApp.m_allPara[i].m_strBrand);
		item.pszText = buf;
		m_ctrlType.SetItem(&item);
		item.iSubItem = 2;
		sprintf(buf,"%s",theApp.m_allPara[i].m_strRemark);
		item.pszText = buf;
		m_ctrlType.SetItem(&item);
	}
	
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	
	// TODO: Add extra initialization here
	 
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CTypDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
	
	  CTypData dlg;
	CProductPara paraBuf;	
	memset(&paraBuf,0,sizeof(CProductPara));
	dlg.m_pPara = &paraBuf;
	if(dlg.DoModal() == IDOK)
	{
		int nItem;
		if(m_nTypeIndex > -1)
			nItem = m_nTypeIndex + 1;
		else
			nItem = theApp.m_allPara.GetSize();
		theApp.m_allPara.InsertAt(nItem,paraBuf);

		LV_ITEM item;
		item.mask = LVIF_TEXT;
		item.iItem = nItem;
		item.iSubItem = 0;
		item.pszText = theApp.m_allPara[nItem].m_strTypeName;
		item.iImage = 0;
		m_ctrlType.InsertItem(&item);
		item.iSubItem = 1;
		item.pszText = theApp.m_allPara[nItem].m_strBrand;
		m_ctrlType.SetItem(&item);
		item.iSubItem = 2;
		item.pszText = theApp.m_allPara[nItem].m_strRemark;
		m_ctrlType.SetItem(&item);

	}	
}

TypData.cpp文件中代码

cpp 复制代码
// TypData.cpp : implementation file
//

#include "stdafx.h"
#include "SEAL_PRESSURE.h"
#include "TypData.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CTypData dialog


CTypData::CTypData(CWnd* pParent /*=NULL*/)
	: CDialog(CTypData::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTypData)
	m_strTypeName = _T("");
	m_strBrand = _T("");
	m_strRemark = _T("");
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CTypData::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTypData)
	DDX_Text(pDX, IDC_EDIT1, m_strTypeName);
	DDX_Text(pDX, IDC_EDIT2, m_strBrand);
	DDX_Text(pDX, IDC_EDIT3, m_strRemark);
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CTypData, CDialog)
	//{{AFX_MSG_MAP(CTypData)
		// NOTE: the ClassWizard will add message map macros here
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CTypData message handlers
BOOL CTypData::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	UpdatePara(FALSE);
//	UpdatePara(1);

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

BOOL CTypData::UpdatePara(BOOL bUpdate)
{
	if(m_pPara == NULL)
		return TRUE;
	if(bUpdate)
	{
		if(!UpdateData())
			return FALSE;
		sprintf(m_pPara->m_strTypeName,"%s", m_strTypeName);
		sprintf(m_pPara->m_strRemark,"%s", m_strRemark);
		sprintf(m_pPara->m_strBrand,"%s", m_strBrand);
	}
			else
	{
		m_strTypeName = m_pPara->m_strTypeName;
		m_strRemark = m_pPara->m_strRemark;
		m_strBrand = m_pPara->m_strBrand;
		
		UpdateData(FALSE);

	}

	return TRUE;
}



void CTypData::OnOK() 
{
	// TODO: Add extra validation here
	
	if(!UpdatePara(TRUE))
		return;
	
	CDialog::OnOK();
	UpdateData(TRUE);
}

SEAL_PRESSURE.cpp文件代码

cpp 复制代码
// SEAL_PRESSURE.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "SEAL_PRESSURE.h"
#include "SEAL_PRESSUREDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CSEAL_PRESSUREApp

BEGIN_MESSAGE_MAP(CSEAL_PRESSUREApp, CWinApp)
	//{{AFX_MSG_MAP(CSEAL_PRESSUREApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG
	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/
// CSEAL_PRESSUREApp construction

CSEAL_PRESSUREApp::CSEAL_PRESSUREApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
		TCHAR exeFullPath[MAX_PATH];
	GetModuleFileName(NULL,exeFullPath,MAX_PATH);
	m_Path = exeFullPath;
	for(int i = m_Path.GetLength() - 1; i > 0 ; i --)
	{
		if(m_Path.GetAt(i) == '\\')
			break;
	}
	SetCurrentDirectory(m_Path);
	m_Path = m_Path.Left(i);
	m_DataPath = m_Path + "\\DATA\\";
	m_TempPath = m_Path + "\\TEMP\\";
	m_LibPath = m_Path + "\\LIB\\";	
	CreateDirectory(m_LibPath,FALSE);
	CreateDirectory(m_DataPath,FALSE);
	CreateDirectory(m_TempPath,FALSE);
	m_CFGFileName = m_Path + "\\CFG.PAR";

	m_strTypeCFGFileName = m_Path + "\\TYPE.CFG";
	m_strDataPath = m_Path + "\\DATA\\";
	CreateDirectory(m_strDataPath,FALSE);
	}

/
// The one and only CSEAL_PRESSUREApp object

CSEAL_PRESSUREApp theApp;

/
// CSEAL_PRESSUREApp initialization

BOOL CSEAL_PRESSUREApp::InitInstance()
{
	AfxEnableControlContainer();

	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.

#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	LoadCFGFile();
   	LoadTypeCFG();
   
	CSEAL_PRESSUREDlg dlg;
	m_pMainWnd = &dlg;
	int nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO: Place code here to handle when the dialog is
		//  dismissed with OK
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: Place code here to handle when the dialog is
		//  dismissed with Cancel
	}

	// Since the dialog has been closed, return FALSE so that we exit the
	//  application, rather than start the application's message pump.
    SaveCFGFile();
	SaveTypeCFG();
	return FALSE;
}

void CSEAL_PRESSUREApp::LoadCFGFile()
{
		CFile file;
	if(file.Open(m_CFGFileName,CFile::modeRead))
	{
		if(!file.Read(&m_sys_data,sizeof(m_sys_data)))
		{
			memset(&m_sys_data,0,sizeof(m_sys_data));
		}
		file.Close();
	}
	else
	{
		memset(&m_sys_data,0,sizeof(m_sys_data));
	}
}

void CSEAL_PRESSUREApp::SaveCFGFile()
{
		CFile file;
	if(file.Open(m_CFGFileName,CFile::modeCreate|CFile::modeWrite))
	{
		file.Write(&m_sys_data,sizeof(m_sys_data));
		file.Close();
	}
}


void CSEAL_PRESSUREApp::SaveTypeCFG()
{
	CFile file;
	CProductPara paraBuf;
	file.Open(m_strTypeCFGFileName,CFile::modeCreate|CFile::modeWrite);
	for(int i = 0 ; i < theApp.m_allPara.GetSize() ; i ++)
	{
		paraBuf = m_allPara[i];
		file.Write(&paraBuf,sizeof(m_allPara[i]));
	}
	file.Close();
}


void CSEAL_PRESSUREApp::LoadTypeCFG()
{
CFile file;
	int nProductCount = 0;
	CProductPara paraBuf;
	if(file.Open(m_strTypeCFGFileName,CFile::modeRead))
	{
		nProductCount = file.GetLength() / sizeof(CProductPara);
	
		for(int i = 0 ; i < nProductCount ; i ++)
		{
			file.Read(&paraBuf,sizeof(m_allPara[i]));
			m_allPara.Add(paraBuf);
		}
		file.Close();
	}

		

	if(nProductCount ==0)
	{
		memset(&paraBuf,0,sizeof(CProductPara));
		strcpy(paraBuf.m_strTypeName,"默认值");
		strcpy(paraBuf.m_strRemark,"默认值");
		strcpy(paraBuf.m_strBrand,"默认值");
		m_allPara.Add(paraBuf);
		}
}

在SEAL_PRESSUREDlg.cpp文件中添加

cpp 复制代码
BOOL CSEAL_PRESSUREDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	...
	 m_menuType.LoadMenu(IDR_MENU1);	
	return TRUE;  // return TRUE  unless you set the focus to a control
}
void CSEAL_PRESSUREDlg::OnTypChoice() 
{
	// TODO: Add your control notification handler code here
//	CTypDlg dlg;
//	dlg.DoModal();
		int	m_nActivePlace = 0;
int	ID_DEF_PRODUCT =5000;

	CRect rect;
	GetDlgItem(IDC_TYP_CHOICE)->GetWindowRect(&rect);
		while(m_menuType.GetSubMenu(0)->GetMenuItemCount() >2)
	{
		m_menuType.GetSubMenu(0)->RemoveMenu(2,MF_BYPOSITION);
	}
	for(int i = 0 ; i < theApp.m_allPara.GetSize() -1; i ++)
	{
		CString str;
		if(strlen(theApp.m_allPara[i + 1].m_strBrand) > 0)
			str.Format("%s(%s)",theApp.m_allPara[i + 1].m_strTypeName,theApp.m_allPara[i + 1].m_strBrand);
		else
			str.Format("%s",theApp.m_allPara[i + 1].m_strTypeName,theApp.m_allPara[i + 1].m_strBrand);
		m_menuType.GetSubMenu(0)->AppendMenu(MF_STRING,ID_DEF_PRODUCT + i,str);
	
	}
	if(theApp.m_nProductSel > 0)
		m_menuType.GetSubMenu(0)->CheckMenuItem(2 + theApp.m_nProductSel - 1,MF_CHECKED|MF_BYPOSITION);
	m_menuType.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON,
	   rect.left,rect.bottom,this);
}
	
相关推荐
怀澈1221 小时前
高性能服务器模型之Reactor(单线程版本)
linux·服务器·网络·c++
chnming19872 小时前
STL关联式容器之set
开发语言·c++
威桑2 小时前
MinGW 与 MSVC 的区别与联系及相关特性分析
c++·mingw·msvc
熬夜学编程的小王2 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list
yigan_Eins2 小时前
【数论】莫比乌斯函数及其反演
c++·经验分享·算法
Mr.132 小时前
什么是 C++ 中的初始化列表?它的作用是什么?初始化列表和在构造函数体内赋值有什么区别?
开发语言·c++
阿史大杯茶2 小时前
AtCoder Beginner Contest 381(ABCDEF 题)视频讲解
数据结构·c++·算法
C++忠实粉丝2 小时前
计算机网络socket编程(3)_UDP网络编程实现简单聊天室
linux·网络·c++·网络协议·计算机网络·udp
我们的五年3 小时前
【Linux课程学习】:进程描述---PCB(Process Control Block)
linux·运维·c++
程序猿阿伟3 小时前
《C++ 实现区块链:区块时间戳的存储与验证机制解析》
开发语言·c++·区块链