文章目录
- CListCtrl类
- CFile类
- 员工管理系统示例代码如下
- Employer.h 应用主程序的头文件
- Employer.cpp
- EmployerDlg.h: 头文件
- EmployerDlg.cpp: 实现文件
- CLogin.h: 实现文件
- CLogin.cpp: 实现文件
CListCtrl类
CListCtrl是MFC中的一个控件类,用于显示列表数据。它继承自CWnd类,并提供了许多功能,如列标题、排序、多选等。下面是CListCtrl常用的函数方法和属性样式。
CListCtrl获取多个选中的方法:
a)GetFirstSelectedItemPosition和GetNextSelectItem。
b)while (++i < nCount) CListCtrl::GetItemState
c)CListCtrl::GetNextItemCListCtrl::Create 创建一个列表控件并将它附加到 CListCtrl 对象。(不是用对话框资源拖入的)
CListCtrl::CreateEx:加强版的创建(扩展风格)
CListCtrl::DeleteAllItems:删除全部行数据(内部数据结构体是CArray)等价于RemoveAllCListCtrl::DeleteItem:删除单行数据CListCtrl::EditLabel:在项上显示一个编辑框
CListCtrl::GetEditControl:基于以上EditLabel
CListCtrl::GetBkColor和CListCtrl::SetBkColor:设置和获取背景色
CListCtrl::GetBkImage和CListCtrl::SetBkImage:背景图片
CListCtrl::GetCheck和CListCtrl::SetCheck:设置和获取打勾(需要设置扩展风格)CListCtrl::GetExtendedStyle和CListCtrl::SetExtendedStyle:设置和获取扩展风格GetFirstSelectedItemPosition:获取选中的多行数据,内部数据结构是单项链表
CListCtrl::GetNextSelectedItem:和以上函数配合形成循环获取所有选中项
CListCtrl::GetSelectedCount:选中的个数CListCtrl::GetHeaderCtrl:获取表头控件,又是一个类CHeaderCtrlCListCtrl::GetImageList和CListCtrl::SetImageList:设置和获取列表的图标
CListCtrl::GetItem和CListCtrl::SetItem:设置和获取完整项数据,包括图标,文字,选中状态,隐含数据等。
CListCtrl::GetItemCount和CListCtrl::SetItemCount:获取和设置数据的总行数。CListCtrl::GetItemData和CListCtrl::GetItemData:获取项内隐含数据CListCtrl::GetItemRect:获取项的位置(RECT)
CListCtrl::GetSubItemRect:获取某行列的小矩形
CListCtrl::SetItemText和CListCtrl::GetItemText:获取和设置某行列的文字
CListCtrl::SetItemState和CListCtrl::GetItemState:设置和获取项的状态。CListCtrl::InsertItem:插入一项(包括文字和图标等)
CListCtrl::SortItems和CListCtrl::SortItemsEx:按照某列排序
#define WC_LISTVIEWA "SysListView32"
#define WC_LISTVIEWW L"SysListView32"#ifdef UNICODE
#define WC_LISTVIEW WC_LISTVIEWW
#else
#define WC_LISTVIEW WC_LISTVIEWA
#endif#else
#define WC_LISTVIEW "SysListView" LVS
#endif// begin_r_commctrl#define LVS_ICON 0x0000
#define LVS_REPORT 0x0001
#define LVS_SMALLICON 0x0002
#define LVS_LIST 0x0003
以上是视图格式:大图标,小图标,详细列表等。
#define LVS_TYPEMASK 0x0003
#define LVS_SINGLESEL 0x0004 单选
#define LVS_SHOWSELALWAYS 0x0008
#define LVS_SORTASCENDING 0x0010 正向排序(主要以列表项文字作为规则,多个列时最左测的)
#define LVS_SORTDESCENDING 0x0020 反向排序
#define LVS_SHAREIMAGELISTS 0x0040
#define LVS_NOLABELWRAP 0x0080
#define LVS_AUTOARRANGE 0x0100
#define LVS_EDITLABELS 0x0200 可以编辑的属性(主要以列表项文字作为规则,多个列时最左测的)
#define LVS_OWNERDATA 0x1000 海量列表的属性(当有几亿个数据插入都需要十几分钟)
#define LVS_NOSCROLL 0x2000#define LVS_TYPESTYLEMASK 0xfc00#define LVS_ALIGNTOP 0x0000
#define LVS_ALIGNLEFT 0x0800
#define LVS_ALIGNMASK 0x0c00#define LVS_OWNERDRAWFIXED 0x0400 自绘(在第十章讲解)
#define LVS_NOCOLUMNHEADER 0x4000 在详细资料REPROT模式下多列却没有标头
#define LVS_NOSORTHEADER 0x8000 没有排序标头
CFile类
CFile类是MFC中的一个文件操作类,提供了对文件的读写、查找、定位等操作.
由于对开发的员工系统的数据需要进行本地保存,需要用到CFile类,下面是CFile类的基本方法和打开模式:
1、CFile类的重要方法:
CFile::Open 函数功能:打开一个文件并返回一个文件句柄。
BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL);参数说明:
lpszFileName:要打开的文件名。
nOpenFlags:打开文件的模式。可以是以下几个值之一:CFile::modeRead:以只读方式打开文件。CFile::modeWrite:以写入方式打开文件。如果文件不存在,则创建一个新文件;如果文件已存在,则截断文件长度为0。CFile::modeReadWrite:以读写方式打开文件。如果文件不存在,则创建一个新文件;如果文件已存在,则保留原文件内容。CFile::modeCreate:创建一个新文件并以写入方式打开它。如果文件已存在,则截断文件长度为0。CFile::modeNoTruncate:不截断现有文件的长度。CFile::shareCompat:允许其他进程打开文件。CFile::shareExclusive:不允许其他进程打开文件。
pError:一个指向CFileException异常对象的指针,用于接收打开文件过程中可能出现的错误信息。返回值:打开文件是否成功。CFile::Open:内部封装CreateFile产生句柄记录在m_hFile;CFile::Close:内部CloseHandle 关闭文件CFile::Read:内部ReadFile 函数功能:从文件中读取指定数量的字节,并将它们存储在缓冲区中。
UINT Read(void* lpBuf, UINT nCount);参数说明:
lpBuf:指向接收数据的缓冲区的指针。
nCount:要读取的字节数。
返回值:实际读取的字节数。CFile::Write:内部WriteFile 函数功能:将指定数量的字节从缓冲区写入文件中。
void Write(const void* lpBuf, UINT nCount);参数说明:
lpBuf:指向要写入文件的数据的缓冲区的指针。
nCount:要写入的字节数。CFile::Seek 函数功能:移动文件指针到指定位置。
LONG Seek(LONG lOff, UINT nFrom);参数说明:
lOff:要移动的字节数。如果nFrom是CFile::begin,则此参数是从文件开头算起的字节数;如果nFrom是CFile::current,则此参数是相对于当前文件指针的字节数;如果nFrom是CFile::end,则此参数是从文件结尾算起的字节数。
nFrom:指定从哪个位置开始移动文件指针。可以是以下值之一:CFile::begin:从文件开头计算。CFile::current:从当前文件指针位置计算。CFile::end:从文件结尾计算。
返回值:新的文件指针位置。
CFile打开模式:
以下打开模式可以通过按位或(|)的方式一起使用,来达到更灵活的文件操作效果。例如,可以使用
CFile::modeReadWrite | CFile::shareExclusive的方式打开一个文件,实现独占方式的读写操作。//表示如果文件不存在则创建文件,如果文件存在则清空文件内容并写入新数据
modeCreate|modeWrite联合等价于fopen("wb")模式 modeRead :等价于"rb"模式以下是打开的一些模式:
enum OpenFlags {modeRead = (int) 0x00000, 以只读方式打开文件。modeWrite = (int) 0x00001, 以只写方式打开文件。如果文件已经存在,将会清除文件内容,如果文件不存在,则会创建一个新的文件。modeReadWrite = (int) 0x00002, 以读写方式打开文件。如果文件不存在,则会创建一个新的文件。shareCompat = (int) 0x00000,shareExclusive = (int) 0x00010, 独占方式打开文件,其他程序无法访问已经打开的文件shareDenyWrite = (int) 0x00020, 拒绝其他程序读取已经打开的文件。shareDenyRead = (int) 0x00030, 拒绝其他程序写入已经打开的文件。shareDenyNone = (int) 0x00040, 允许其他程序读写已经打开的文件。modeNoInherit = (int) 0x00080,
#ifdef _UNICODEtypeUnicode = (int) 0x00400, // used in derived classes (e.g. CStdioFile) only
#endifmodeCreate = (int) 0x01000, 创建一个新的文件。如果文件已经存在,则会清除文件内容。modeNoTruncate = (int) 0x02000, 打开一个已经存在的文件,但不清除文件内容,可以在文件末尾追加新的数据。typeText = (int) 0x04000, // used in derived classes (e.g. CStdioFile) onlytypeBinary = (int) 0x08000, // used in derived classes (e.g. CStdioFile) onlyosNoBuffer = (int) 0x10000,osWriteThrough = (int) 0x20000,osRandomAccess = (int) 0x40000,osSequentialScan = (int) 0x80000,};
提示:以下是本篇文章正文内容,下面案例可供参考
员工管理系统示例代码如下
Employer.h 应用主程序的头文件
#pragma once
#ifndef __AFXWIN_H__#error "在包含此文件之前包含 'pch.h' 以生成 PCH"
#endif
#include "resource.h" // 主符号class CEmployerApp : public CWinApp
{
public:CEmployerApp();public:virtual BOOL InitInstance();DECLARE_MESSAGE_MAP()
};
extern CEmployerApp theApp;
Employer.cpp
#include "pch.h"
#include "framework.h"
#include "Employer.h"
#include "EmployerDlg.h"
#include "CLogin.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endifBEGIN_MESSAGE_MAP(CEmployerApp, CWinApp)ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
CEmployerApp::CEmployerApp()
{m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
}CEmployerApp theApp;// 唯一的 CEmployerApp 对象BOOL CEmployerApp::InitInstance()// CEmployerApp 初始化
{CWinApp::InitInstance();CLogin LogDlg;if (IDCANCEL == LogDlg.DoModal())return false; CEmployerDlg dlg;m_pMainWnd = &dlg;INT_PTR nResponse = dlg.DoModal();return FALSE;
}
EmployerDlg.h: 头文件
#pragma once
struct SData
{//CString sNumb;//指针变量 这里面存的是指针的地址,而不是内容 不能这样用int nNumb;TCHAR sName[20];float fSalary;TCHAR sDate[20];
};
class CEmployerDlg : public CDialogEx // CEmployerDlg 对话框
{
// 构造
public:CEmployerDlg(CWnd* pParent = nullptr); // 标准构造函数int CheckNumb(CString str);void Load();#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_MAIN_DIG };// 对话框数据 类向导通过这个去关联
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnPaint();DECLARE_MESSAGE_MAP()
public:afx_msg void OnClickedAdd();afx_msg void OnClickedDel();afx_msg void OnClickedModeify();afx_msg void OnBnClickedSave();
};
EmployerDlg.cpp: 实现文件
#include "pch.h"
#include "framework.h"
#include "Employer.h"
#include "EmployerDlg.h"
#include "afxdialogex.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif// CEmployerDlg 对话框 弹出对话框用的CEmployerDlg::CEmployerDlg(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_MAIN_DIG, pParent)
{m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CEmployerDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CEmployerDlg, CDialogEx)ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_ADD, &CEmployerDlg::OnClickedAdd)ON_BN_CLICKED(IDC_DEL, &CEmployerDlg::OnClickedDel)ON_BN_CLICKED(IDC_MODEIFY, &CEmployerDlg::OnClickedModeify)ON_BN_CLICKED(IDC_SAVE, &CEmployerDlg::OnBnClickedSave)
END_MESSAGE_MAP()// CEmployerDlg 消息处理程序BOOL CEmployerDlg::OnInitDialog()
{CDialogEx::OnInitDialog();auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);pList->InsertColumn(0, L"工号", LVCFMT_CENTER, 120);pList->InsertColumn(1, L"姓名", LVCFMT_CENTER, 120);pList->InsertColumn(2, L"工资", LVCFMT_CENTER, 130);pList->InsertColumn(3, L"入职日期", LVCFMT_CENTER, 180);pList->SetExtendedStyle(LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT); //Extended List-View Styles列表控件的额外样式SetIcon(m_hIcon, TRUE); // 设置大图标SetIcon(m_hIcon, FALSE); // 设置小图标Load();// TODO: 在此添加额外的初始化代码return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}void CEmployerDlg::OnPaint()
{CPaintDC dc(this); // 用于绘制的设备上下文
}
int CEmployerDlg::CheckNumb(CString str)
{auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);int nCount = pList->GetItemCount();while (nCount--){if (pList->GetItemText(nCount, 0) == str)return nCount; //0代表第一个 3 代表第四个}return -1; //代表不存在
}void CEmployerDlg::OnClickedAdd() //首先获取列表控件 对编辑框中的文字进行获取 插入到列表控件
{//通过GetItemCount来获取当前列表视图控件项的数目 依次排序auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);CString str;GetDlgItemText(IDC_NUMB, str);int nIndex = CheckNumb(str);if (nIndex >= 0){MessageBox(L"你输入的工号已存在,请重新输入", L"提示");return;}int nCount = pList->GetItemCount();pList->InsertItem(nCount,str);GetDlgItemText(IDC_NAME, str);pList->SetItemText(nCount, 1, str);GetDlgItemText(IDC_SALARY, str);pList->SetItemText(nCount, 2, str);GetDlgItemText(IDC_DATETIME, str);pList->SetItemText(nCount, 3, str);OnBnClickedSave();
}
void CEmployerDlg::OnClickedDel()
{auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);int nCount = pList->GetSelectedCount();if (nCount<=0){//::MessageBox 加了::就是强制指定全局变量和函数的用法 参数全部添上// 不加::的话默认靠this这个句柄来MessageBox(L"请先选中一行再进行删除"); return;}auto pos = pList->GetFirstSelectedItemPosition();while (pos){int nItem = pList->GetNextSelectedItem(pos);CString str = pList->GetItemText(nItem, 0);str += L" ";str += pList->GetItemText(nItem, 1);str += L" ";str += pList->GetItemText(nItem, 2);if (IDYES == MessageBox(str+ L"\r\n你确定要删除吗?", L"提示", MB_YESNO)){pList->DeleteItem(nItem);}}OnBnClickedSave();
}void CEmployerDlg::OnClickedModeify()
{auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);auto pos = pList->GetFirstSelectedItemPosition();if(!pos){ MessageBox(L"请先选中一行再进行修改");return;}if (IDYES == MessageBox(L"\r\n你确定要修改吗?", L"提示", MB_YESNO)){CString str;int nItem = pList->GetNextSelectedItem(pos);GetDlgItemText(IDC_NUMB, str);pList->SetItemText(nItem, 0, str);GetDlgItemText(IDC_NAME, str);pList->SetItemText(nItem, 1, str);GetDlgItemText(IDC_SALARY, str);pList->SetItemText(nItem, 2, str);GetDlgItemText(IDC_DATETIME, str);pList->SetItemText(nItem, 3, str);}OnBnClickedSave();
}void CEmployerDlg::Load()
{CFile file;if (!file.Open(L"./Data.txt", CFile::modeRead)){MessageBox(L"打开文件失败");return;}SData d;CString str;auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);pList->DeleteAllItems();int i = 0;while (file.Read(&d,sizeof(d)) ==sizeof(d)){str.Format(L"%d", d.nNumb);pList->InsertItem(i, str);pList->SetItemText(i, 1, d.sName);str.Format(L"%g", d.fSalary);pList->SetItemText(i, 2,str);pList->SetItemText(i, 3, d.sDate);++i;}file.Close();
}
void CEmployerDlg::OnBnClickedSave()
{CFile file;if (!file.Open(L"./Data.txt", CFile::modeCreate | CFile::modeWrite)){MessageBox(L"打开文件失败");return;}auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);int i = -1, nCount = pList->GetItemCount();SData d;while (++i<nCount){d.nNumb = _tstoi(pList->GetItemText(i, 0));//CString 的核心是WCAHR* pData; operatot LPCTSTRwcscpy_s(d.sName,pList->GetItemText(i, 1));d.fSalary = (float)_tstof(pList->GetItemText(i, 2));wcscpy_s(d.sDate, pList->GetItemText(i, 3));file.Write(&d, sizeof(d));}file.Close();//可以不用执行,因为有析构函数
}
CLogin.h: 实现文件
#pragma once
#include "afxdialogex.h"class CLogin : public CDialogEx // CLogin 对话框
{DECLARE_DYNAMIC(CLogin)public:CLogin(CWnd* pParent = nullptr); // 标准构造函数virtual ~CLogin();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_LOGIN_DLG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持DECLARE_MESSAGE_MAP()
public:afx_msg void OnBnClickedOk();
};
CLogin.cpp: 实现文件
#include "pch.h"
#include "Employer.h"
#include "afxdialogex.h"
#include "CLogin.h"IMPLEMENT_DYNAMIC(CLogin, CDialogEx)CLogin::CLogin(CWnd* pParent /*=nullptr*/) // CLogin 对话框: CDialogEx(IDD_LOGIN_DLG, pParent)
{}CLogin::~CLogin()
{
}void CLogin::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CLogin, CDialogEx)ON_BN_CLICKED(IDOK, &CLogin::OnBnClickedOk)
END_MESSAGE_MAP()void CLogin::OnBnClickedOk() // CLogin 消息处理程序
{CString sName, sPass;GetDlgItemText(IDC_USERNAME, sName);GetDlgItemText(IDC_PASS, sPass);if (sName=="abc"&&"123"==sPass){EndDialog(IDOK);return;}else{MessageBox(L"你的账号或者密码输入错误,请重新输入。");SetDlgItemText(IDC_USERNAME, L"");SetDlgItemText(IDC_PASS, L"");GetDlgItem(IDC_USERNAME)->SetFocus();}//CDialogEx::OnOK();
}
本文链接:https://my.lmcjl.com/post/5451.html
展开阅读全文
4 评论