void DisplayMessageQueue_Win32::allow_exceptions()
	{
		if (moduleKernel32 == 0)
		{
			// See http://support.microsoft.com/kb/976038
			// Required for exceptions and access violations not to be caught by DispatchMessage.
			moduleKernel32 = LoadLibrary(L"kernel32.dll");
			ptrSetProcessUserModeExceptionPolicy = (FuncSetProcessUserModeExceptionPolicy *)GetProcAddress(moduleKernel32, "SetProcessUserModeExceptionPolicy");
			ptrGetProcessUserModeExceptionPolicy = (FuncGetProcessUserModeExceptionPolicy *)GetProcAddress(moduleKernel32, "GetProcessUserModeExceptionPolicy");
			if (ptrSetProcessUserModeExceptionPolicy && ptrGetProcessUserModeExceptionPolicy)
			{
				DWORD flags = 0;
				if (ptrGetProcessUserModeExceptionPolicy(&flags))
					ptrSetProcessUserModeExceptionPolicy(flags & ~WIN32_PROCESS_CALLBACK_FILTER_ENABLED);
			}
		}
	}
void CL_DisplayMessageQueue_Win32::process_message()
{
	// We must use PeekMessage instead of GetMessage because GetMessage can
	// block even when MsgWaitForMultipleObjects reported messages to be
	// available.  This can happen because SendMessage between threads and
	// internal system events are processed when GetMessage and PeekMessage
	// are called and such messages are processed directly and not returned
	// by PeekMessage/GetMessage.  A call to GetMessage may therefore block
	// until a message intended for us arrives.
	//
	// PeekMessage+PM_REMOVE equals to a non-blocking GetMessage call.

	if (moduleKernel32 == 0)
	{
		// See http://support.microsoft.com/kb/976038
		// Required for exceptions and access violations not to be caught by DispatchMessage.
		moduleKernel32 = LoadLibrary(L"kernel32.dll");
		ptrSetProcessUserModeExceptionPolicy = (FuncSetProcessUserModeExceptionPolicy *)GetProcAddress(moduleKernel32, "SetProcessUserModeExceptionPolicy");
		ptrGetProcessUserModeExceptionPolicy = (FuncGetProcessUserModeExceptionPolicy *)GetProcAddress(moduleKernel32, "GetProcessUserModeExceptionPolicy");
		if (ptrSetProcessUserModeExceptionPolicy && ptrGetProcessUserModeExceptionPolicy)
		{
			DWORD flags = 0;
			if (ptrGetProcessUserModeExceptionPolicy(&flags))
				ptrSetProcessUserModeExceptionPolicy(flags & ~WIN32_PROCESS_CALLBACK_FILTER_ENABLED);
		}
	}

	MSG msg;
	memset(&msg, 0, sizeof(MSG));
	BOOL result = PeekMessage(&msg, 0, 0, 0, PM_REMOVE);
	if (result)
		DispatchMessage(&msg);
	
	CL_SharedPtr<ThreadData> data = get_thread_data();
	for (std::vector<CL_Win32Window *>::size_type i = 0; i < data->windows.size(); i++)
	{
		CL_InputContext context = data->windows[i]->get_ic();
		context.process_messages();
	}
}