Windows核心编程学习八:事件内核对象

注:源码为学习《Windows核心编程》的一些尝试,非原创。若能有助于一二访客,幸甚。


1.程序框架

/*
 * 文件:Handshake.cpp
 * 时间:2013-07-10
 * 描述:学习《Windows核心编程》
 */

#include 
#include 
#include 
#include 
#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;
}

Windows核心编程学习八:事件内核对象_第1张图片


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;
}

Windows核心编程学习八:事件内核对象_第2张图片


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核心编程,笔记,读书摘要)