Windows核心编程学习八:事件内核对象
2013-07-10 12:16
465 查看
注:源码为学习《Windows核心编程》的一些尝试,非原创。若能有助于一二访客,幸甚。
1.程序框架
/* * 文件:Handshake.cpp * 时间:2013-07-10 * 描述:学习《Windows核心编程》 */ #include <windows.h> #include <windowsx.h> #include <tchar.h> #include <StrSafe.h> #include "resource.h" #define chHANDLE_DLGMSG(hWnd, message, fn) \ case (message): return (SetDlgMsgResult(hWnd, uMsg, \ HANDLE_##message((hWnd), (wParam), (lParam), (fn)))) // Sets the dialog box icons inline void chSETDLGICONS(HWND hWnd, int idi) { SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM) LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(idi))); SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM) LoadIcon((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE), MAKEINTRESOURCE(idi))); } BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { chSETDLGICONS(hwnd, IDI_HANDSHAKE); Edit_SetText(GetDlgItem(hwnd, IDC_REQUEST), TEXT("Some test data")); return TRUE; } void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { switch (id) { case IDCANCEL: EndDialog(hwnd, id); break; case IDC_SUBMIT: break; } } INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog); chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand); } return FALSE; } int WINAPI _tWinMain(HINSTANCE hInstanceExe, HINSTANCE, PTSTR, int) { DialogBox(hInstanceExe, MAKEINTRESOURCE(IDD_HANDSHAKE), NULL, Dlg_Proc); return 0; }
2.事件内核对象的使用
// 当客户端提交请求到服务器时触发的事件内核对象 HANDLE g_hevtRequestSubmitted; // 当服务器端完成操作返回结果给客户端时触发的内核对象 HANDLE g_hevtResultReturned; // 客户端和服务器端共享的内存缓冲区 TCHAR g_szSharedRequestAndResultBuffer[1024];
typedef unsigned (__stdcall *PTHREAD_START) (void *); #define chBEGINTHREADEX(psa, cbStackSize, pfnStartAddr, \ pvParam, dwCreateFlags, pdwThreadId) \ ((HANDLE)_beginthreadex( \ (void *) (psa), \ (unsigned) (cbStackSize), \ (PTHREAD_START) (pfnStartAddr), \ (void *) (pvParam), \ (unsigned) (dwCreateFlags), \ (unsigned *) (pdwThreadId))) #define chHANDLE_DLGMSG(hWnd, message, fn) \ case (message): return (SetDlgMsgResult(hWnd, uMsg, \ HANDLE_##message((hWnd), (wParam), (lParam), (fn))))
// 服务器线程 DWORD WINAPI ServerThread(PVOID pvParam) { while (1) { // 等待客户端提交请求 WaitForSingleObject(g_hevtRequestSubmitted, INFINITE); // 完成反转字符串 _tcsrev(g_szSharedRequestAndResultBuffer); // 触发事件,告诉客户端处理完成,可以显示结果 SetEvent(g_hevtResultReturned); } return 0; }
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { switch (id) { case IDCANCEL: EndDialog(hwnd, id); break; case IDC_SUBMIT: // 获取编辑框中的字符串 Edit_GetText(GetDlgItem(hwnd, IDC_REQUEST), g_szSharedRequestAndResultBuffer, _countof(g_szSharedRequestAndResultBuffer)); // 触发事件内核对象,告诉服务器端有请求需要处理 SetEvent(g_hevtRequestSubmitted); // 等待服务器端处理完成 WaitForSingleObject(g_hevtResultReturned, INFINITE); // 显示结果 Edit_SetText(GetDlgItem(hwnd, IDC_RESULT), g_szSharedRequestAndResultBuffer); break; } }
int WINAPI _tWinMain(HINSTANCE hInstanceExe, HINSTANCE, PTSTR, int) { g_hevtRequestSubmitted = CreateEvent(NULL, FALSE, FALSE, NULL); g_hevtResultReturned = CreateEvent(NULL, FALSE, FALSE, NULL); DWORD dwThreadID; HANDLE hThreadServer = chBEGINTHREADEX(NULL, 0, ServerThread, NULL, 0, &dwThreadID); DialogBox(hInstanceExe, MAKEINTRESOURCE(IDD_HANDSHAKE), NULL, Dlg_Proc); CloseHandle(hThreadServer); CloseHandle(g_hevtRequestSubmitted); CloseHandle(g_hevtResultReturned); return 0; }
3.程序结束
// 特殊字符串标示服务器线程退出 TCHAR g_szServerShutdown[] = TEXT("Server Shutdown"); // 当收到退出信息时,服务器端检查主对话框是否已经退出 HWND g_hMainDlg;
// 服务器线程 DWORD WINAPI ServerThread(PVOID pvParam) { BOOL fShutdown = FALSE; while (!fShutdown) { // 等待客户端提交请求 WaitForSingleObject(g_hevtRequestSubmitted, INFINITE); fShutdown = (g_hMainDlg == NULL) && (_tcscmp(g_szSharedRequestAndResultBuffer, g_szServerShutdown) == 0); if (!fShutdown) { // 完成反转字符串 _tcsrev(g_szSharedRequestAndResultBuffer); } // 触发事件,告诉客户端处理完成,可以显示结果 SetEvent(g_hevtResultReturned); } return 0; }
int WINAPI _tWinMain(HINSTANCE hInstanceExe, HINSTANCE, PTSTR, int) { // 初始化事件内核对象,初始未触发,自动重置 g_hevtRequestSubmitted = CreateEvent(NULL, FALSE, FALSE, NULL); g_hevtResultReturned = CreateEvent(NULL, FALSE, FALSE, NULL); // 创建服务器端线程 DWORD dwThreadID; HANDLE hThreadServer = chBEGINTHREADEX(NULL, 0, ServerThread, NULL, 0, &dwThreadID); // 显示对话框 DialogBox(hInstanceExe, MAKEINTRESOURCE(IDD_HANDSHAKE), NULL, Dlg_Proc); // 主对话框退出,发送消息告诉服务器端线程退出 g_hMainDlg = NULL; _tcscpy_s(g_szSharedRequestAndResultBuffer, _countof(g_szSharedRequestAndResultBuffer), g_szServerShutdown); // 告诉服务器端线程有请求发送 SetEvent(g_hevtRequestSubmitted); // 等待服务器端线程退出 HANDLE h[2]; h[0] = g_hevtResultReturned; h[1] = hThreadServer; WaitForMultipleObjects(2, h, TRUE, INFINITE); // 关闭所有内核对象 CloseHandle(hThreadServer); CloseHandle(g_hevtRequestSubmitted); CloseHandle(g_hevtResultReturned); return 0; }
相关文章推荐
- windows核心编程-事件内核对象
- Windows核心编程学习九:利用内核对象进行线程同步
- Windows-核心编程-09-如何用内核对象进行线程同步-事件内核对象
- WINDOWS核心编程学习1------内核对象
- Windows核心编程_3.内核对象
- Windows核心编程--用内核对象进行线程同步(一)
- 【Windows 核心编程】Windows 核心编程 -- 内核对象
- windows 核心编程之9 内核对象用于线程同步
- windows核心编程心解--内核对象
- Windows-核心编程-09-如何用内核对象进行线程同步-信号内核对象
- windows核心编程---用内核对象进行线程同步
- Windows 核心编程内核对象同步之-Waitable timer
- Windows 核心编程之6 线程内核对象
- Windows编程--线程和内核对象的同步-事件内核对象
- 读Windows核心编程-3-内核对象
- windows核心编程--内核对象
- 指定的服务已标记为删除 寒江孤钓<<windows 内核安全编程>> 学习笔记
- Windows核心编程学习笔记----第二章 UNICODE
- windows 核心编程之 错误处理 -----学习笔记
- 【Windows】线程漫谈——线程同步之等待函数和事件内核对象