dinput: Use PostMessage instead of SendMessage. Remove message window.

oldstable
Vitaliy Margolen 2007-07-15 10:38:05 -06:00 committed by Alexandre Julliard
parent 894343268c
commit 233cd46a22
1 changed files with 35 additions and 64 deletions

View File

@ -848,22 +848,31 @@ static LRESULT CALLBACK LL_hook_proc( int code, WPARAM wparam, LPARAM lparam )
return CallNextHookEx( 0, code, wparam, lparam ); return CallNextHookEx( 0, code, wparam, lparam );
} }
static LRESULT CALLBACK dinput_hook_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) static DWORD WINAPI hook_thread_proc(void *param)
{ {
static HHOOK kbd_hook, mouse_hook; static HHOOK kbd_hook, mouse_hook;
UINT kbd_cnt = 0, mice_cnt = 0; MSG msg;
TRACE("got message %x %p %p\n", message, (LPVOID)wParam, (LPVOID)lParam); /* Force creation of the message queue */
switch (message) PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE );
SetEvent(*(LPHANDLE)param);
while (GetMessageW( &msg, 0, 0, 0 ))
{ {
case WM_USER+0x10: UINT kbd_cnt = 0, mice_cnt = 0;
if (msg.message == WM_USER+0x10)
{ {
IDirectInputImpl *dinput; IDirectInputImpl *dinput;
if (!wParam && !lParam) TRACE( "Processing hook change notification lp:%ld\n", msg.lParam );
if (!msg.wParam && !msg.lParam)
{ {
DestroyWindow( hWnd ); if (kbd_hook) UnhookWindowsHookEx( kbd_hook );
return 0; if (mouse_hook) UnhookWindowsHookEx( mouse_hook );
kbd_hook = mouse_hook = NULL;
break;
} }
EnterCriticalSection( &dinput_hook_crit ); EnterCriticalSection( &dinput_hook_crit );
@ -906,46 +915,15 @@ static LRESULT CALLBACK dinput_hook_WndProc(HWND hWnd, UINT message, WPARAM wPar
mouse_hook = NULL; mouse_hook = NULL;
} }
} }
return 0; TranslateMessage(&msg);
DispatchMessageW(&msg);
case WM_DESTROY:
if (kbd_hook) UnhookWindowsHookEx(kbd_hook);
if (mouse_hook) UnhookWindowsHookEx(mouse_hook);
kbd_hook = mouse_hook = NULL;
PostQuitMessage(0);
} }
return DefWindowProcW(hWnd, message, wParam, lParam);
}
static HWND hook_thread_hwnd;
static HANDLE hook_thread;
static const WCHAR classW[]={'H','o','o','k','_','L','L','_','C','L',0};
static DWORD WINAPI hook_thread_proc(void *param)
{
MSG msg;
HWND hwnd;
hwnd = CreateWindowExW(0, classW, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, 0);
hook_thread_hwnd = hwnd;
SetEvent(*(LPHANDLE)param);
if (hwnd)
{
while (GetMessageW(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
DestroyWindow(hwnd);
}
else ERR("Error creating message window\n");
UnregisterClassW(classW, DINPUT_instance);
return 0; return 0;
} }
static DWORD hook_thread_id;
static CRITICAL_SECTION_DEBUG dinput_critsect_debug = static CRITICAL_SECTION_DEBUG dinput_critsect_debug =
{ {
0, 0, &dinput_hook_crit, 0, 0, &dinput_hook_crit,
@ -956,26 +934,17 @@ static CRITICAL_SECTION dinput_hook_crit = { &dinput_critsect_debug, -1, 0, 0, 0
static BOOL check_hook_thread(void) static BOOL check_hook_thread(void)
{ {
static HANDLE hook_thread;
EnterCriticalSection(&dinput_hook_crit); EnterCriticalSection(&dinput_hook_crit);
TRACE("IDirectInputs left: %d\n", list_count(&direct_input_list)); TRACE("IDirectInputs left: %d\n", list_count(&direct_input_list));
if (!list_empty(&direct_input_list) && !hook_thread) if (!list_empty(&direct_input_list) && !hook_thread)
{ {
DWORD tid;
HANDLE event; HANDLE event;
/* Create window class */
WNDCLASSEXW wcex;
memset(&wcex, 0, sizeof(wcex));
wcex.cbSize = sizeof(wcex);
wcex.lpfnWndProc = dinput_hook_WndProc;
wcex.lpszClassName = classW;
wcex.hInstance = DINPUT_instance;
if (!RegisterClassExW(&wcex))
ERR("Error registering window class\n");
event = CreateEventW(NULL, FALSE, FALSE, NULL); event = CreateEventW(NULL, FALSE, FALSE, NULL);
hook_thread = CreateThread(NULL, 0, hook_thread_proc, &event, 0, &tid); hook_thread = CreateThread(NULL, 0, hook_thread_proc, &event, 0, &hook_thread_id);
if (event && hook_thread) if (event && hook_thread)
{ {
HANDLE handles[2]; HANDLE handles[2];
@ -983,29 +952,31 @@ static BOOL check_hook_thread(void)
handles[1] = hook_thread; handles[1] = hook_thread;
WaitForMultipleObjects(2, handles, FALSE, INFINITE); WaitForMultipleObjects(2, handles, FALSE, INFINITE);
} }
LeaveCriticalSection(&dinput_hook_crit);
CloseHandle(event); CloseHandle(event);
} }
else if (list_empty(&direct_input_list) && hook_thread) else if (list_empty(&direct_input_list) && hook_thread)
{ {
HWND hwnd = hook_thread_hwnd; DWORD tid = hook_thread_id;
hook_thread_hwnd = 0;
SendMessageW(hwnd, WM_USER+0x10, 0, 0); hook_thread_id = 0;
PostThreadMessageW(tid, WM_USER+0x10, 0, 0);
LeaveCriticalSection(&dinput_hook_crit);
/* wait for hook thread to exit */ /* wait for hook thread to exit */
WaitForSingleObject(hook_thread, INFINITE); WaitForSingleObject(hook_thread, INFINITE);
CloseHandle(hook_thread); CloseHandle(hook_thread);
hook_thread = NULL; hook_thread = NULL;
} }
LeaveCriticalSection(&dinput_hook_crit); else
LeaveCriticalSection(&dinput_hook_crit);
return hook_thread_hwnd != 0; return hook_thread_id != 0;
} }
void check_dinput_hooks(LPDIRECTINPUTDEVICE8A iface) void check_dinput_hooks(LPDIRECTINPUTDEVICE8A iface)
{ {
HWND hwnd;
EnterCriticalSection(&dinput_hook_crit); EnterCriticalSection(&dinput_hook_crit);
hwnd = hook_thread_hwnd; PostThreadMessageW( hook_thread_id, WM_USER+0x10, 1, 0 );
LeaveCriticalSection(&dinput_hook_crit); LeaveCriticalSection(&dinput_hook_crit);
SendMessageW(hwnd, WM_USER+0x10, 1, 0);
} }