注:源码为学习《Windows核心编程》的一些尝试,非原创。若能有助于一二访客,幸甚。
/*
* 文件: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;
}
// 当客户端提交请求到服务器时触发的事件内核对象
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;
}
// 特殊字符串标示服务器线程退出
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;
}