MFC第七天 单机版数据库增删改的方法和用户登录(密码修改)、权限管理功能的员工管理系统的应用 以及 CCombox类的属性和方法

员工管理系统的应用

补充CListCtrl类

1、CListCtrl::GetItemState的调用方法:
Mask 多种状态你要哪一个
a)mask开关:可以同时带入多个开关,返回值再探测是否含有哪个标识。
b)LVIS_FOCUSED 代表 多行列表的焦点项(只有能有一个)
c)LVIS_SELECTED  代表蓝色选中项(可以有多个);
d)CListCtrl::GetSelectionMark是指LVIS_FOCUSED,单一的焦点行所在位置。


#define LVIS_FOCUSED            0x0001
#define LVIS_SELECTED           0x0002
#define LVIS_CUT                0x0004
#define LVIS_DROPHILITED        0x0008
#define LVIS_GLOW               0x0010
#define LVIS_ACTIVATING         0x0020

对TCHAR类型简介:

a)窄字符串:typedef const char* LPCSTR;
b)宽字符串:typedef const wchar_t* LPCWSTR;
c)自适应字符串:typedef TCHAR* LPCTSTR;

#ifdef  UNICODE                     // r_winnt
typedef wchar_t TCHAR;
typedef const wchar_t* LPCTSTR;
#else
typedef char TCHAR;
typedef const char* LPCTSTR;
#endif

全面对项目实施TCHAR类型:

a)从常量上看:
LPCSTR p= “abc”;
LPCWSTR str = “abc”;
ifdef _UNICODE
#define __T(x) L ## x
else
#define __T(x) (x)
b)API:
#ifdef UNICODE
#define SetWindowText SetWindowTextW
#else
#define SetWindowText SetWindowTextA
#endif // !UNICODE

c)C语言库函数
#ifdef UNICODE
#define _tfopen _wfopen
#else
#define _tfopen fopen
#endif
d)C++字符串提供了string和wstring版本,没办法TCHAR版本。
#define _T(x) __T(x)
#define _TEXT(x) __T(x)

Unicode软件开发中的文字转换方式有三种

1、使用sprintf(”%S") 进行转换,不过限制于ASCII码0-127不包括中文

	wchar_t s1[] =L"asdbsadkjq231";  //不含有汉字,纯ASCII码  如何转换为窄的
	char s2[200];

	sprintf(s2, "%s", "bbbb");
	swprintf(s1, L"%s", L"bbbb"); //小写s只能将宽的转为宽, 窄的转为窄的

	sprintf(s2, "%S", s1); //可以通过sprintf(%S);来进行转换 只限制于纯英文格式的 汉字转换不了

2、可以使用CString 来进行转换

#include<atlbase.h>
void Test()
{
	wchar_t s1[] = L"asdbsadkjq231";
	char s2[200] = "abcd";

	//使用W2A A2W T2A T2W A2T W2T时需要前面加上	USES_CONVERSION 包含的头文件#include<atlbase.h>
	//可以实现对宽窄的转换, 适用于中文
	USES_CONVERSION;
	auto p = W2A(s1);
	auto q = A2W(s2);
}

int main()		
{
	Test();
	_CrtDumpMemoryLeaks();//用于检测内存泄露函数
	
	//当CString加上explicit之后不能使用隐式转换,要使用显示的
	//同时CStringT 有部分的转换能力,支持双入口的构造函数,但不支持双出口类型转换。 
	//进来可以时可以是A或者W 出去的时候要是它的原类型,或者使用LPCTSTR

	CString s1 = "萨洛芬妮";
	CString s2 = L"萨洛芬妮";
	CString s3("萨洛芬妮");
	LPCTSTR q = s1;
	LPCWSTR p = s2;
	return 0;
	
	/*关键字explicit主要用于解决隐式类型转换问题。默认情况下,C++编译器会进行一些隐式类型转换,
	例如将一个整数类型变量赋值给一个双精度浮点数类型变量,
	或者将一个自定义类型的对象传递给一个需要该类型对象的函数。
	而使用explicit关键字可以禁止这种隐式的类型转换,只能使用显式类型转换*/

class A
{
public:
	explicit A(int n) {};
	A();
	~A();

private:

};
	A a1 = 2;
	A a2(2);
	A a3 = (A)3;
	fun(3);
	fun(A(3));
	//在上面的示例中,类A的构造函数使用了explicit关键字,
	//因此只有在显式进行类型转换时才能创建对象。对于在函数中传递对象,也必须使用显式类型转换。
}

第三种为使用 _bstr_t 可以双通道的转换

CComboBox控件属性和类库介绍

CBS_组合框控件属性

Box:框 盒子 n.
原始的组合框是一个编辑框和一个ListBox组成,后来变为下拉。
下拉之后分为纯下拉(DropList)和带编辑框的下拉(Dropdown)

/*
 * Combo Box styles
 */
#define CBS_SIMPLE            0x0001L (原始状态的组合框)
#define CBS_DROPDOWN          0x0002L (带编辑框的下拉)
#define CBS_DROPDOWNLIST      0x0003L (不带编辑框的纯下拉)


#define CBS_OWNERDRAWFIXED    0x0010L	自绘下拉(第十章)固定高宽
#define CBS_OWNERDRAWVARIABLE 0x0020L	自绘下拉(第十章)动态高宽
#define CBS_AUTOHSCROLL       0x0040L
#define CBS_OEMCONVERT        0x0080L
#define CBS_SORT              0x0100L		排序的属性(非常不好)
#define CBS_HASSTRINGS        0x0200L
#define CBS_NOINTEGRALHEIGHT  0x0400L
#define CBS_DISABLENOSCROLL   0x0800L
#if(WINVER >= 0x0400)
#define CBS_UPPERCASE         0x2000L		组合框内的编辑框(大写)
#define CBS_LOWERCASE         0x4000L		组合框内的编辑框(小写)
#endif /* WINVER >= 0x0400 */

#endif  /* !NOWINSTYLES */

CComboBox常用方法

class CComboBox : public CWnd
{Edit和ListBox
	DECLARE_DYNAMIC(CComboBox)

// Constructors
public:
	CComboBox();
	virtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
	//代码创建下拉控件

	// manipulating listbox items
	int AddString(LPCTSTR lpszString); //加一行
	int DeleteString(UINT nIndex);//删除一行
	int InsertString(_In_ int nIndex, _In_z_ LPCTSTR lpszString); //插入一行
	void ResetContent(); //清空列表
// Attributes
	// for entire combo box
	int GetCount() const; 列表项总数
	int GetCurSel() const; //获取列表当前选中 -1代表没选中
	int SetCurSel(int nSelect); 设置列表当前选中
// Win4
	int GetTopIndex() const; 当大量列表数据,滚动后最上方的索引
	int SetTopIndex(int nIndex); //设置滚动位置
	
	int SetDroppedWidth(UINT nWidth); 设置下拉宽度
	int GetDroppedWidth() const; 获取下拉宽度

	

	// for edit control
	DWORD GetEditSel() const;  获取编辑框内的选中文字,
	BOOL SetEditSel(_In_ int nStartChar, _In_ int nEndChar);  设置 选中
	BOOL LimitText(int nMaxChars);  编辑框的文字长度限制
	
//LB 就是ListBox
	int GetLBText(_In_ int nIndex, _Pre_notnull_ _Post_z_ LPTSTR lpszText) const;//列表第几行的文字
	void GetLBText(int nIndex, CString& rString) const;
	int GetLBTextLen(int nIndex) const;//第几行文字的长度

	// for combobox item
	DWORD_PTR GetItemData(int nIndex) const;//获取每一行的隐藏数据(可能是结构体指针)
	int SetItemData(int nIndex, DWORD_PTR dwItemData);//设置隐藏数据
	void* GetItemDataPtr(int nIndex) const;//对以上函数加强版(指针)
	int SetItemDataPtr(int nIndex, void* pData);/对以上函数加强版(指针)


	int SetItemHeight(int nIndex, UINT cyItemHeight);//设置第几行的行高
	int GetItemHeight(int nIndex) const;
	
	BOOL GetDroppedState() const;

	// for drop-down combo boxes
	void ShowDropDown(BOOL bShowIt = TRUE); //弹出对话框

	int Dir(_In_ UINT attr, _In_ LPCTSTR lpszWildCard);

	// selection helpers
	int FindString(_In_ int nStartAfter, _In_z_ LPCTSTR lpszString) const;
	int SelectString(int nStartAfter, LPCTSTR lpszString);

	// 编辑框内的 Clipboard operations
	void Clear();
	void Copy();
	void Cut();
	void Paste();

// Overridables (must override draw, measure and compare for owner draw)自绘相关
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
	virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
	virtual int CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct);
	virtual void DeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct);
};


员工管理系统示例代码如下

对话框中的控件可以进行快速编号的调整使用Ctrl+D快捷键
项目框架如下:
在这里插入图片描述在这里插入图片描述

账号管理对话框:
在这里插入图片描述
修改密码对话框:
在这里插入图片描述

用户登录对话框:
在这里插入图片描述
数据录入对话框:点击修改按钮是时此对话框会变成数据修改对话框如下所示:在这里插入图片描述
数据修改对话框:
在这里插入图片描述

主对话框:
在这里插入图片描述

Employer_sql.h

// Employer_sql.h: PROJECT_NAME 应用程序的主头文件
#pragma once
#ifndef __AFXWIN_H__
	#error "在包含此文件之前包含 'pch.h' 以生成 PCH"
#endif
#include "resource.h"		// 主符号

// CApp:	 有关此类的实现,请参阅 Employer_sql.cpp

class CApp : public CWinApp
{
	BOOL ConnectDB(); //数据库的连接
public:
	CApp();
	MYSQL m_sql;
	CString m_sName, m_sPass;
	int m_nPrior{ -1 };
// 重写
public:
	virtual BOOL InitInstance();
	static void DisplayError(CString sSQL); //加上static就不用theApp可以直接通过名称来调用
	DECLARE_MESSAGE_MAP()// 实现
};
extern CApp theApp;

Employer_sql.cpp

// Employer_sql.cpp: 定义应用程序的类行为。
#include "pch.h"
#include "framework.h"
#include "Employer_sql.h"
#include "MainDlg.h"
#include "CLoginDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW 
#endif

BEGIN_MESSAGE_MAP(CApp, CWinApp)
	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()

// CApp 构造
BOOL CApp::ConnectDB()
{
	auto conn = mysql_init(&m_sql);
	if (conn == NULL)
	{
		::MessageBox(nullptr, L"mysql_init", L"提示", 0);
		return FALSE;
	}
	//host参数可以用:"localhost",".","192.168.0.88","127.0.0.1","teacher"
	if (mysql_real_connect(conn, "localhost", "root", "201105", "worker", 3307, NULL, 0) == NULL)
	{
		::MessageBox(nullptr, L"mysql_real_connect", L"提示", 0);
		return FALSE;
	}
	mysql_query(conn, "set names gbk");//utf-8和ansi(gb2312,gbk)
	//mysql_query(conn, "use worker");
	return TRUE;
}

CApp::CApp()
{
	// 支持重新启动管理器
	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
}

CApp theApp;// CApp 初始化	唯一的 CApp 对象

BOOL CApp::InitInstance()	// 将所有重要的初始化放置在 InitInstance 中
{
	if (!ConnectDB())
		return FALSE;	
	CLoginDlg ldlg;
	if (ldlg.DoModal() == IDOK)
	{
		CMainDlg dlg;
		INT_PTR nResponse = dlg.DoModal();
	}
	return FALSE;
}

void CApp::DisplayError(CString sSQL)
{
	CString str;
	str.Format(_T("错误(%d):"), mysql_errno(&theApp.m_sql));//获取错误编号
	str = str + (LPCTSTR)_bstr_t(mysql_error(&theApp.m_sql)) + _T("\r\n") + sSQL; //罗列错误信息
	MessageBox(NULL, str, _T("提示"), MB_OK | MB_ICONERROR);
}

CInputDlg .h

#pragma once
#include "afxdialogex.h"
#include "MainDlg.h"

// CInputDlg 对话框
class MainDlg;
class CInputDlg : public CDialogEx
{
	DECLARE_DYNAMIC(CInputDlg)
	MYSQL& m_sql{theApp.m_sql};
	CMainDlg* m_pDlg;
	MYSQL_RES* FindNumb(CString sNumb);

public:
	CInputDlg(CWnd* pParent = nullptr);   // 标准构造函数
	virtual ~CInputDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_INPUT_DLG };
#endif

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedOk();
};

CInputDlg.cpp: 实现文件

#include "pch.h"
#include "Employer_sql.h"
#include "afxdialogex.h"
#include "CInputDlg.h"
#include "MainDlg.h"
IMPLEMENT_DYNAMIC(CInputDlg, CDialogEx)

MYSQL_RES* CInputDlg::FindNumb(CString sNumb)
{
	CString sSQL;

	sSQL.Format(_T("SELECT * FROM t_worker WHERE f_numb=%s"), (LPCTSTR)sNumb);
	USES_CONVERSION;

	int n = mysql_query(&m_sql, T2A(sSQL));
	if (n)
	{
		CApp::DisplayError(sSQL);
		return nullptr;
	}
	auto res = mysql_store_result(&m_sql);
	if (res)
	{
		if (!mysql_num_rows(res))
		{
			mysql_free_result(res);
			res = nullptr;
		}
	}
	return res;
}

CInputDlg::CInputDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_INPUT_DLG, pParent)
{

}

CInputDlg::~CInputDlg()
{
}

void CInputDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CInputDlg, CDialogEx)
	ON_BN_CLICKED(IDOK, &CInputDlg::OnBnClickedOk)
END_MESSAGE_MAP()

void CInputDlg::OnBnClickedOk()
{
	CString sNumb;
	GetDlgItemText(IDC_NUMB, sNumb);
	auto res = FindNumb(sNumb);
	if (res)
	{
		auto row = mysql_fetch_row(res);
		CString str = CString(_T("你录入的工号已存在!\r\n")) +
			*row + _T(",") + row[1] + _T(",") + row[2] + _T(",") + row[3];
		MessageBox(str, _T("提示"), MB_ICONSTOP);
		mysql_free_result(res);
		SetFocus();
		return;
	}
	CString sSQL,sName,sSala,sDate;
	GetDlgItemText(IDC_NAME, sName);
	GetDlgItemText(IDC_SALARY, sSala);
	GetDlgItemText(IDC_DATETIME, sDate);
	CMainDlg::CorrentDate(sDate);
	sSQL.Format(_T("INSERT INTO t_worker VALUES(%s,'%s',%s,'%s')"), sNumb, sName, sSala, sDate);
	int n = mysql_query(&m_sql, (_bstr_t)sSQL);
	if (n)
	{
		CApp::DisplayError(sSQL);
		return;
	}	
	m_pDlg->Refresh();
	SetDlgItemText(IDC_NUMB, _T(""));
	SetDlgItemText(IDC_NAME, _T(""));
	SetDlgItemText(IDC_SALARY, _T(""));
	SetFocus();
}

MainDlg.h

#pragma once
class CMainDlg : public CDialogEx		// CMainDlg 对话框
{
// 构造
	void DeleteInfo(CString str);
	void ModifyInfo(CString sNumb);
	void Refresh();
	CString GetLine(int nItem);
	void InitTitle();
	MYSQL& m_sql = theApp.m_sql;
	static void CorrentDate(CString& str)
	{
		str.Replace(_T('年'), _T('-'));
		str.Replace(_T('月'), _T('-'));
		str.Replace(_T('日'), _T('\0'));
	}
public:
	CMainDlg(CWnd* pParent = nullptr);	// 标准构造函数

#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_MAIN_DIG};		// 对话框数据
#endif

	protected:
	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 OnBnClickedDel();
	afx_msg void OnBnClickedAdd();
	afx_msg void OnBnClickedModeify();
	afx_msg void OnBnClickedSave();
	afx_msg void OnBnClickedCount();
};

MainDlg.cpp: 实现文件

#include "pch.h"
#include "framework.h"
#include "Employer_sql.h"
#include "MainDlg.h"
#include "CAdminDlg.h"
#include "CPassDlg.h"
#include "CInputDlg.h"
#include "CModifyDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CMainDlg::CMainDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MAIN_DIG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMainDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CMainDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_DEL, &CMainDlg::OnBnClickedDel)
	ON_BN_CLICKED(IDC_ADD, &CMainDlg::OnBnClickedAdd)
	ON_BN_CLICKED(IDC_MODEIFY, &CMainDlg::OnBnClickedModeify)
	ON_BN_CLICKED(IDC_SAVE, &CMainDlg::OnBnClickedSave)
 
	ON_BN_CLICKED(IDC_COUNT, &CMainDlg::OnBnClickedCount)
END_MESSAGE_MAP()
BOOL CMainDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	CDialogEx::OnInitDialog();
	InitTitle();
	auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);
	pList->InsertColumn(0, L"工号", LVCFMT_LEFT, 120);
	pList->InsertColumn(1, L"姓名", LVCFMT_LEFT, 130);
	pList->InsertColumn(2, L"工资", LVCFMT_LEFT, 130);
	pList->InsertColumn(3, L"入职日期", LVCFMT_LEFT, 180);
	pList->SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
	Refresh();

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CMainDlg::OnPaint()
{
		CPaintDC dc(this); // 用于绘制的设备上下文
}

CString CMainDlg::GetLine(int nItem)
{
	auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);
	CString str;
	int i = -1;
	while (++i<4)
	{
		if (i > 0)
			str += _T(",");
		str += pList->GetItemText(nItem, i);
	}
	return str;
}

void CMainDlg::InitTitle()
{
	CString str;
	GetWindowText(str);
	str += _T("  当前账号:") + theApp.m_sName + _T("【") +
		(theApp.m_nPrior ? _T("普通") : _T("高级")) + _T("】");
	SetWindowText(str);
	if (theApp.m_nPrior)
		SetDlgItemText(IDC_COUNT,_T("修改密码"));
}

void CMainDlg::Refresh()
{
	auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);
	pList->DeleteAllItems();
	int n = mysql_query(&m_sql, "SELECT * FROM t_worker");
	if (n)
	{
		MessageBox(L"mysql_query");
		return;
	}
	auto res = mysql_store_result(&m_sql);
	if (!res)
	{
		MessageBox(L"mysql_store_result");
		return;
	}
	MYSQL_ROW row;
	int i = 0;
	while (row = mysql_fetch_row(res))//_bstr_t既可以从宽版转向窄版 双向通道
	{
		_bstr_t str(*row++);
		pList->InsertItem(i, str);
		str = *row++;
		pList->SetItemText(i, 1, str);
		str = *row++;
		pList->SetItemText(i, 2, str);
		str = *row++;
		pList->SetItemText(i, 3, str);
		++i;
	}

}

void CMainDlg::DeleteInfo(CString str)
{
	char sSQL[256];
	sprintf_s(sSQL,_countof(sSQL),"DELETE FROM t_worker WHERE f_numb ='%s'", (LPCSTR)_bstr_t(str));
	int n = mysql_query(&m_sql, sSQL);
	if (n)
	{
		MessageBox(_T("ModifyInfo"),_T("删除失败"),0);
		return;
	}
}

void CMainDlg::OnBnClickedDel()
{
	auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);
	POSITION pos = pList->GetFirstSelectedItemPosition(); 
	if (!pos)
	{
		MessageBox(_T("请选中一行再进行删除"), _T("提示"));
		return;
	}
	while (pos)	//不断地向下循环
	{
		int i = pList->GetNextSelectedItem(pos);
		CString str = GetLine(i);
		if (MessageBox(str + _T("\r\n你确定要删除这一行吗?"),_T("提示"),MB_YESNO)==IDYES)
		{
			DeleteInfo(pList->GetItemText(i, 0));
		}
	}
	Refresh();
}

void CMainDlg::OnBnClickedAdd()
{
	CInputDlg dlg;
	dlg.m_pDlg = this;
	dlg.DoModal();
}

void CMainDlg::OnBnClickedModeify()
{
	auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);
	POSITION pos = pList->GetFirstSelectedItemPosition();
	if (!pos)
	{
		MessageBox(_T("请选中一行再进行修改"), _T("提示"));
		return;
	}
	auto nItem = pList->GetNextSelectedItem(pos);
	CModifyDlg dlg;
	dlg.m_sNumb = pList->GetItemText(nItem, 0);
	dlg.m_sName = pList->GetItemText(nItem, 1);
	dlg.m_sSala = pList->GetItemText(nItem, 2);
	dlg.m_sDate = pList->GetItemText(nItem, 3);
	dlg.DoModal();  //doModal期间是不可以的, 但可以提前把数据放进去
	/*对话框doMoadl之前你想给对话框设置数据 ,你只能把数据传过去 而不能直接设置窗口的句柄   
	甚至控件句柄 都是不可操作的
	当我们需要给修改传入数据,我们只能把对象内的数据进行修改,让它再启动之后,去设置*/
}
   

void CMainDlg::OnBnClickedSave()
{

}

void CMainDlg::OnBnClickedCount()
{
	if (theApp.m_nPrior)
	{
		CPassDlg dlg;
		dlg.DoModal();
	}
	else
	{
		CAdminDlg dlg;
		dlg.DoModal();
	}
}

CLoginDlg.h

#pragma once
#include <afxdialogex.h>
class CLoginDlg :public CDialogEx
{
	DECLARE_DYNAMIC(CLoginDlg)
public:
	CLoginDlg(CWnd* pParent = nullptr);   // 标准构造函数
	virtual ~CLoginDlg();

#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_LOGIN_DLG };	// 对话框数据
#endif
protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	DECLARE_MESSAGE_MAP()
public:
	virtual BOOL OnInitDialog();
	afx_msg void OnBnClickedOk();
};

CLoginDlg.cpp: 实现文件

#include "pch.h"
#include "afxdialogex.h"
#include "CLoginDlg.h"
#include "Employer_sql.h"

IMPLEMENT_DYNAMIC(CLoginDlg, CDialogEx)
CLoginDlg::CLoginDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_LOGIN_DLG, pParent)		// CLoginDlg 对话框
{

}

CLoginDlg::~CLoginDlg()
{
}

void CLoginDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CLoginDlg, CDialogEx)
	ON_BN_CLICKED(IDOK, &CLoginDlg::OnBnClickedOk)
END_MESSAGE_MAP()

BOOL CLoginDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	HICON hIcon = theApp.LoadIcon(IDR_MAINFRAME);
	this->SetIcon(hIcon, FALSE);
	CEdit* pEdit = (CEdit*)GetDlgItem(IDC_USERNAME);
	pEdit->LimitText(10); 
	pEdit = (CEdit*)GetDlgItem(IDC_PASS);
	pEdit->LimitText(20);
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}
/*	float f = 988;
	int n = int(f);//构造C语言不支持
	int n = (int)f;//强转 C语言支持*/
void CLoginDlg::OnBnClickedOk()
{
	CString sName, sPass;
	GetDlgItemText(IDC_USERNAME, sName);
	GetDlgItemText(IDC_PASS, sPass);
	CString sSQL;
	//BINARY  的SQL语句代表区分大小写,默认是不区分
	sSQL.Format(_T("SELECT * FROM t_admin WHERE f_name='%s' AND BINARY f_pass='%s'"),
		(LPCTSTR)sName, (LPCTSTR)sPass);

	if (mysql_query(&theApp.m_sql, (LPCSTR)_bstr_t(sSQL))) //什么也不写代表!0 加!就是等于0
	{
		CApp::DisplayError(sSQL);
		return;
	}

	auto res = mysql_store_result(&theApp.m_sql);
	if (!res)
	{
		CApp::DisplayError(_T("获取结果集失败!"));
		return;
	}
	if (mysql_num_rows(res) > 0)
	{
		auto row = mysql_fetch_row(res);
		theApp.m_sName = *row++;
		theApp.m_sPass = *row++;
		theApp.m_nPrior = atoi(*row);
		EndDialog(IDOK);
	}
	else
	{
		MessageBox(_T("账号或密码错误,请重新输入!"), _T("提示"), MB_OK | MB_ICONERROR);
		SetDlgItemText(IDC_USERNAME, _T(""));
		SetDlgItemText(IDC_PASS, _T(""));
		this->SetFocus();
	}
}

CAdminDlg.h: 实现文件

#pragma once
#include "afxdialogex.h"
class CAdminDlg : public CDialogEx
{
	DECLARE_DYNAMIC(CAdminDlg)
	void Refresh();
	bool CheckName(CString sName);
public:
	CAdminDlg(CWnd* pParent = nullptr);   // 标准构造函数
	virtual ~CAdminDlg();

#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_COUNT };// 对话框数据
#endif
protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
	DECLARE_MESSAGE_MAP()
public:
	virtual BOOL OnInitDialog();
	afx_msg void OnBnClickedAdd();
	afx_msg void OnBnClickedDel();
	afx_msg void OnBnClickedUpdate();
};

CAdminDlg.cpp: 实现文件

#include "pch.h"
#include "Employer_sql.h"
#include "afxdialogex.h"
#include "CAdminDlg.h"
IMPLEMENT_DYNAMIC(CAdminDlg, CDialogEx)

CAdminDlg::CAdminDlg(CWnd* pParent /*=nullptr*/)// CAdminDlg 对话框
	: CDialogEx(IDD_COUNT, pParent)
{

}
CAdminDlg::~CAdminDlg()
{
}

void CAdminDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAdminDlg, CDialogEx)
	ON_BN_CLICKED(IDC_ADD, &CAdminDlg::OnBnClickedAdd)
	ON_BN_CLICKED(IDC_DEL, &CAdminDlg::OnBnClickedDel)
	ON_BN_CLICKED(IDC_UPDATE, &CAdminDlg::OnBnClickedUpdate)
END_MESSAGE_MAP()

void CAdminDlg::Refresh()
{
	auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);
	pList->DeleteAllItems();
	int n = mysql_query(&theApp.m_sql, "SELECT * FROM t_admin");
	if (n)
	{
		MessageBox(L"mysql_query");
		return;
	}
	auto res = mysql_store_result(& theApp.m_sql);
	if (!res)
	{
		MessageBox(L"mysql_store_result");
		return;
	}
	MYSQL_ROW row;
	int i = 0;
	while (row = mysql_fetch_row(res)) 
	{
		_bstr_t str(*row++);
		pList->InsertItem(i, str);
		str = *row++; 
		pList->SetItemText(i, 1, str);
	//	pList->SetItemText(i, 2, ('1'== **row)?_T("普通"):_T("高级"));
		pList->SetItemText(i, 2, atoi(*row) ? _T("普通") : _T("高级")); //指针数组和二级指针
		++i;
	}
	mysql_free_result(res);
}

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

	CComboBox* pCombox = (CComboBox*)GetDlgItem(IDC_PRIOR);
	pCombox->AddString(_T("普通")); //向尾部插入 关闭掉控件的排序属性,才会按照插入的顺序显示,否则会帮你对文字进行排序
	pCombox->AddString(_T("高级"));
	pCombox->SetCurSel(0);

	auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);
	pList->InsertColumn(0, L"账号", LVCFMT_LEFT, 150);
	pList->InsertColumn(1, L"密码", LVCFMT_LEFT, 160);
	pList->InsertColumn(2, L"权限", LVCFMT_LEFT, 160);
	pList->SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
	Refresh();
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}

bool CAdminDlg::CheckName(CString sName)
{
	auto pList = (CListCtrl*)GetDlgItem(IDC_LIST);
	pList->DeleteAllItems();
	CString sSQL= _T("SELECT * FROM t_admin WHERE f_name='")+sName+_T("'");
	int n = mysql_query(&theApp.m_sql, (_bstr_t)sSQL);
	if (n)
	{
		CApp::DisplayError(sSQL);
		return false;
	}
	auto res = mysql_store_result(&theApp.m_sql);
	if (!res)
	{
		CApp::DisplayError(_T("mysql_store_result"));
		return false;
	}
	bool b = mysql_num_rows(res) > 0;
	mysql_free_result(res);
	return b;
}

void CAdminDlg::OnBnClickedAdd()
{
	CString sName, sPass, sPrior;
	GetDlgItemText(IDC_NAME, sName);
	if (CheckName(sName))
	{
		MessageBox(_T("你输入的账号已存在,请重新输入"), _T("提示"), MB_ICONERROR);
		return;
	}
	GetDlgItemText(IDC_PASS, sPass);
	GetDlgItemText(IDC_PRIOR, sPrior);
	int nPrior = sPrior == _T("普通");
	CString sSQL;
	sSQL.Format(_T("INSERT INTO t_admin VALUES('%s','%s','%d')"), sName, sPass, nPrior);
	int n = mysql_query(&theApp.m_sql, (_bstr_t)sSQL);
	if (n)
		CApp::DisplayError(sSQL);
	else
		Refresh();

}

void CAdminDlg::OnBnClickedDel()
{
	 
}

void CAdminDlg::OnBnClickedUpdate()
{
	 
}

CPassDlg.h

#pragma once
#include "afxdialogex.h"
class CPassDlg : public CDialogEx
{
	DECLARE_DYNAMIC(CPassDlg)
	bool ChangePass(CString sPass);
public:
	CPassDlg(CWnd* pParent = nullptr);   // 标准构造函数
	virtual ~CPassDlg();

#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_PASS_DLG };
#endif
protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedOk();
};

CPassDlg.cpp: 实现文件

#include "pch.h"
#include "Employer_sql.h"
#include "afxdialogex.h"
#include "CPassDlg.h"
IMPLEMENT_DYNAMIC(CPassDlg, CDialogEx)

CPassDlg::CPassDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_PASS_DLG, pParent)
{

}
CPassDlg::~CPassDlg()
{
}
void CPassDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CPassDlg, CDialogEx)
	ON_BN_CLICKED(IDOK, &CPassDlg::OnBnClickedOk)
END_MESSAGE_MAP()

bool CPassDlg::ChangePass(CString sPass)
{
	CString sSQL;
	sSQL.Format(_T("UPDATE t_admin SET f_pass ='%s' WHERE f_name ='%s'"), (LPCTSTR)sPass,(LPCTSTR)theApp.m_sName);
	int n = mysql_query(&theApp.m_sql, (_bstr_t)sSQL);
	if (!n)
	{
		theApp.m_sPass = sPass;
		return true;
	}
	CApp::DisplayError(sSQL);
	return false;
}

void CPassDlg::OnBnClickedOk()
{
	CString sOld, sNew, sConf;
	GetDlgItemText(IDC_OLDPASS, sOld);
	if (sOld.IsEmpty())
	{
		MessageBox(_T("旧密码不能为空"), _T("提示"), MB_ICONERROR);
		SetFocus();
		return;
	}
	if (sOld!=theApp.m_sPass)
	{
		MessageBox(_T("旧密码错误"), _T("提示"), MB_ICONERROR);
		SetFocus();
		return;
	}
	GetDlgItemText(IDC_NEWPASS, sNew);
	if (sNew.IsEmpty())
	{
		MessageBox(_T("新密码不能为空"), _T("提示"), MB_ICONERROR);
		SetFocus();
		return;
	}
	GetDlgItemText(IDC_CONFPASS, sConf);
	if (sConf.IsEmpty())
	{
		MessageBox(_T("确认密码不能为空"), _T("提示"), MB_ICONERROR);
		SetFocus();
		return;
	}
	if (sConf!=sNew)
	{
		MessageBox(_T("两次密码输入的不一致,请重新输入"), _T("提示"), MB_ICONERROR);
		SetFocus();
		return;
	}
	if (ChangePass(sNew))
	{
		EndDialog(IDOK);
		MessageBox(_T("密码修改成功"), _T("提示"), MB_ICONINFORMATION);
	}
	else
	{
		MessageBox(_T("密码修改失败"), _T("提示"), MB_ICONINFORMATION);
	}
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jcrry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值