Chromium Code Reviews| Index: base/message_loop/message_pump_win.cc |
| diff --git a/base/message_loop/message_pump_win.cc b/base/message_loop/message_pump_win.cc |
| index 53df341e5fce09a65ed087837db2bacc2aa7b8f6..1f1c9c6efdddb0c8d61e6af13b8226eccf8c0772 100644 |
| --- a/base/message_loop/message_pump_win.cc |
| +++ b/base/message_loop/message_pump_win.cc |
| @@ -28,6 +28,128 @@ enum MessageLoopProblems { |
| MESSAGE_LOOP_PROBLEM_MAX, |
| }; |
| +// The following define pointer to user32 API's for the API's which are used |
| +// in this file. These are added to avoid directly depending on user32 from |
| +// base as there are users of base who don't want this. |
| +using TranslateMessageFunction = BOOL(WINAPI*)(const MSG*); |
| +using DispatchMessageFunction = LRESULT(WINAPI*)(const MSG*); |
| +using PeekMessageFunction = BOOL(WINAPI*)(MSG*, HWND, UINT, UINT, UINT); |
| +using PostMessageFunction = BOOL(WINAPI*)(HWND, UINT, WPARAM, LPARAM); |
| +using DefWindowProcFunction = LRESULT(WINAPI*)(HWND, UINT, WPARAM, LPARAM); |
| +using PostQuitFunction = void(WINAPI*)(int); |
| +using UnregisterClassFunction = BOOL(WINAPI*)(const wchar_t*, HINSTANCE); |
| +using RegisterClassFunction = ATOM(WINAPI*)(const WNDCLASSEX*); |
| +using CreateWindowExFunction = HWND(WINAPI*)(DWORD, |
| + const wchar_t*, |
| + const wchar_t*, |
| + DWORD, |
| + int, |
| + int, |
| + int, |
| + int, |
| + HWND, |
| + HMENU, |
| + HINSTANCE, |
| + void*); |
| +using DestroyWindowFunction = BOOL(WINAPI*)(HWND); |
| +using CallMsgFilterFunction = BOOL(WINAPI*)(MSG*, int); |
| +using GetQueueStatusFunction = DWORD(WINAPI*)(UINT); |
| +using MsgWaitForMultipleObjectsExFunction = |
| + DWORD(WINAPI*)(DWORD, const HANDLE*, DWORD, DWORD, DWORD); |
| +using SetTimerFunction = UINT_PTR(WINAPI*)(HWND, UINT_PTR, UINT, TIMERPROC); |
| +using KillTimerFunction = BOOL(WINAPI*)(HWND, UINT_PTR); |
| + |
| +// Pointers to user32 API's in this file. |
| +TranslateMessageFunction g_translate_message = nullptr; |
| +DispatchMessageFunction g_dispatch_message = nullptr; |
| +PeekMessageFunction g_peek_message = nullptr; |
| +PostMessageFunction g_post_message = nullptr; |
| +DefWindowProcFunction g_def_window_proc = nullptr; |
| +PostQuitFunction g_post_quit = nullptr; |
| +UnregisterClassFunction g_unregister_class = nullptr; |
| +RegisterClassFunction g_register_class = nullptr; |
| +CreateWindowExFunction g_create_window_ex = nullptr; |
| +DestroyWindowFunction g_destroy_window = nullptr; |
| +CallMsgFilterFunction g_call_msg_filter = nullptr; |
| +GetQueueStatusFunction g_get_queue_status = nullptr; |
| +MsgWaitForMultipleObjectsExFunction g_msg_wait_for_multiple_objects_ex = |
| + nullptr; |
| +SetTimerFunction g_set_timer = nullptr; |
| +KillTimerFunction g_kill_timer = nullptr; |
| + |
| +// Initializes the global pointers to user32 APIs for the API's used in this |
| +// file. |
| +void InitUser32APIs() { |
| + static bool init = false; |
|
grt (UTC plus 2)
2016/06/14 02:20:49
nit: the process will die if any of these fails, s
ananta
2016/06/14 03:24:05
Done.
|
| + if (init) |
| + return; |
| + |
| + HMODULE user32_dll = ::GetModuleHandle(L"user32.dll"); |
| + CHECK(user32_dll); |
| + |
| + g_translate_message = reinterpret_cast<TranslateMessageFunction>( |
| + ::GetProcAddress(user32_dll, "TranslateMessage")); |
| + CHECK(g_translate_message); |
| + |
| + g_dispatch_message = reinterpret_cast<DispatchMessageFunction>( |
| + ::GetProcAddress(user32_dll, "DispatchMessageW")); |
| + CHECK(g_dispatch_message); |
| + |
| + g_peek_message = reinterpret_cast<PeekMessageFunction>( |
| + ::GetProcAddress(user32_dll, "PeekMessageW")); |
| + CHECK(g_peek_message); |
| + |
| + g_post_message = reinterpret_cast<PostMessageFunction>( |
| + ::GetProcAddress(user32_dll, "PostMessageW")); |
| + CHECK(g_post_message); |
| + |
| + g_def_window_proc = reinterpret_cast<DefWindowProcFunction>( |
| + ::GetProcAddress(user32_dll, "DefWindowProcW")); |
| + CHECK(g_def_window_proc); |
| + |
| + g_post_quit = reinterpret_cast<PostQuitFunction>( |
| + ::GetProcAddress(user32_dll, "PostQuitMessage")); |
| + CHECK(g_post_quit); |
| + |
| + g_unregister_class = reinterpret_cast<UnregisterClassFunction>( |
| + ::GetProcAddress(user32_dll, "UnregisterClassW")); |
| + CHECK(g_unregister_class); |
| + |
| + g_register_class = reinterpret_cast<RegisterClassFunction>( |
| + ::GetProcAddress(user32_dll, "RegisterClassExW")); |
| + CHECK(g_register_class); |
| + |
| + g_create_window_ex = reinterpret_cast<CreateWindowExFunction>( |
| + ::GetProcAddress(user32_dll, "CreateWindowExW")); |
| + CHECK(g_create_window_ex); |
| + |
| + g_destroy_window = reinterpret_cast<DestroyWindowFunction>( |
| + ::GetProcAddress(user32_dll, "DestroyWindow")); |
| + CHECK(g_destroy_window); |
| + |
| + g_call_msg_filter = reinterpret_cast<CallMsgFilterFunction>( |
| + ::GetProcAddress(user32_dll, "CallMsgFilterW")); |
| + CHECK(g_call_msg_filter); |
| + |
| + g_get_queue_status = reinterpret_cast<GetQueueStatusFunction>( |
| + ::GetProcAddress(user32_dll, "GetQueueStatus")); |
| + CHECK(g_get_queue_status); |
| + |
| + g_msg_wait_for_multiple_objects_ex = |
| + reinterpret_cast<MsgWaitForMultipleObjectsExFunction>( |
| + ::GetProcAddress(user32_dll, "MsgWaitForMultipleObjectsEx")); |
| + CHECK(g_msg_wait_for_multiple_objects_ex); |
| + |
| + g_set_timer = reinterpret_cast<SetTimerFunction>( |
| + ::GetProcAddress(user32_dll, "SetTimer")); |
| + CHECK(g_set_timer); |
| + |
| + g_kill_timer = reinterpret_cast<KillTimerFunction>( |
| + ::GetProcAddress(user32_dll, "KillTimer")); |
| + CHECK(g_kill_timer); |
| + init = true; |
| +} |
| + |
| } // namespace |
| static const wchar_t kWndClassFormat[] = L"Chrome_MessagePumpWindow_%p"; |
| @@ -42,6 +164,10 @@ static const int kMessageFilterCode = 0x5001; |
| //----------------------------------------------------------------------------- |
| // MessagePumpWin public: |
| +MessagePumpWin::MessagePumpWin() : work_state_(READY), state_(NULL) { |
| + InitUser32APIs(); |
| +} |
| + |
| void MessagePumpWin::Run(Delegate* delegate) { |
| RunState s; |
| s.delegate = delegate; |
| @@ -96,8 +222,8 @@ MessagePumpForUI::MessagePumpForUI() |
| } |
| MessagePumpForUI::~MessagePumpForUI() { |
| - DestroyWindow(message_hwnd_); |
| - UnregisterClass(MAKEINTATOM(atom_), CURRENT_MODULE()); |
| + g_destroy_window(message_hwnd_); |
| + g_unregister_class(MAKEINTATOM(atom_), CURRENT_MODULE()); |
| } |
| void MessagePumpForUI::ScheduleWork() { |
| @@ -105,8 +231,8 @@ void MessagePumpForUI::ScheduleWork() { |
| return; // Someone else continued the pumping. |
| // Make sure the MessagePump does some work for us. |
| - BOOL ret = PostMessage(message_hwnd_, kMsgHaveWork, |
| - reinterpret_cast<WPARAM>(this), 0); |
| + BOOL ret = g_post_message(message_hwnd_, kMsgHaveWork, |
| + reinterpret_cast<WPARAM>(this), 0); |
| if (ret) |
| return; // There was room in the Window Message queue. |
| @@ -146,7 +272,7 @@ LRESULT CALLBACK MessagePumpForUI::WndProcThunk( |
| reinterpret_cast<MessagePumpForUI*>(wparam)->HandleTimerMessage(); |
| break; |
| } |
| - return DefWindowProc(hwnd, message, wparam, lparam); |
| + return g_def_window_proc(hwnd, message, wparam, lparam); |
| } |
| void MessagePumpForUI::DoRunLoop() { |
| @@ -187,7 +313,7 @@ void MessagePumpForUI::DoRunLoop() { |
| // don't want to disturb that timer if it is already in flight. However, |
| // if we did do all remaining delayed work, then lets kill the WM_TIMER. |
| if (more_work_is_plausible && delayed_work_time_.is_null()) |
| - KillTimer(message_hwnd_, reinterpret_cast<UINT_PTR>(this)); |
| + g_kill_timer(message_hwnd_, reinterpret_cast<UINT_PTR>(this)); |
| if (state_->should_quit) |
| break; |
| @@ -215,11 +341,11 @@ void MessagePumpForUI::InitMessageWnd() { |
| wc.lpfnWndProc = base::win::WrappedWindowProc<WndProcThunk>; |
| wc.hInstance = instance; |
| wc.lpszClassName = class_name.c_str(); |
| - atom_ = RegisterClassEx(&wc); |
| + atom_ = g_register_class(&wc); |
| DCHECK(atom_); |
| - message_hwnd_ = CreateWindow(MAKEINTATOM(atom_), 0, 0, 0, 0, 0, 0, |
| - HWND_MESSAGE, 0, instance, 0); |
| + message_hwnd_ = g_create_window_ex(0, MAKEINTATOM(atom_), 0, 0, 0, 0, 0, 0, |
| + HWND_MESSAGE, 0, instance, 0); |
| DCHECK(message_hwnd_); |
| } |
| @@ -233,8 +359,8 @@ void MessagePumpForUI::WaitForWork() { |
| if (delay < 0) // Negative value means no timers waiting. |
| delay = INFINITE; |
| - DWORD result = |
| - MsgWaitForMultipleObjectsEx(0, NULL, delay, QS_ALLINPUT, wait_flags); |
| + DWORD result = g_msg_wait_for_multiple_objects_ex(0, NULL, delay, |
| + QS_ALLINPUT, wait_flags); |
| if (WAIT_OBJECT_0 == result) { |
| // A WM_* message is available. |
| @@ -252,9 +378,9 @@ void MessagePumpForUI::WaitForWork() { |
| // current thread. |
| MSG msg = {0}; |
| bool has_pending_sent_message = |
| - (HIWORD(GetQueueStatus(QS_SENDMESSAGE)) & QS_SENDMESSAGE) != 0; |
| + (HIWORD(g_get_queue_status(QS_SENDMESSAGE)) & QS_SENDMESSAGE) != 0; |
| if (has_pending_sent_message || |
| - PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { |
| + g_peek_message(&msg, NULL, 0, 0, PM_NOREMOVE)) { |
| return; |
| } |
| @@ -292,7 +418,7 @@ void MessagePumpForUI::HandleWorkMessage() { |
| } |
| void MessagePumpForUI::HandleTimerMessage() { |
| - KillTimer(message_hwnd_, reinterpret_cast<UINT_PTR>(this)); |
| + g_kill_timer(message_hwnd_, reinterpret_cast<UINT_PTR>(this)); |
| // If we are being called outside of the context of Run, then don't do |
| // anything. This could correspond to a MessageBox call or something of |
| @@ -337,8 +463,8 @@ void MessagePumpForUI::RescheduleTimer() { |
| // Create a WM_TIMER event that will wake us up to check for any pending |
| // timers (in case we are running within a nested, external sub-pump). |
| - BOOL ret = SetTimer(message_hwnd_, reinterpret_cast<UINT_PTR>(this), |
| - delay_msec, NULL); |
| + BOOL ret = g_set_timer(message_hwnd_, reinterpret_cast<UINT_PTR>(this), |
| + delay_msec, NULL); |
| if (ret) |
| return; |
| // If we can't set timers, we are in big trouble... but cross our fingers |
| @@ -355,12 +481,12 @@ bool MessagePumpForUI::ProcessNextWindowsMessage() { |
| // case to ensure that the message loop peeks again instead of calling |
| // MsgWaitForMultipleObjectsEx again. |
| bool sent_messages_in_queue = false; |
| - DWORD queue_status = GetQueueStatus(QS_SENDMESSAGE); |
| + DWORD queue_status = g_get_queue_status(QS_SENDMESSAGE); |
| if (HIWORD(queue_status) & QS_SENDMESSAGE) |
| sent_messages_in_queue = true; |
| MSG msg; |
| - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != FALSE) |
| + if (g_peek_message(&msg, NULL, 0, 0, PM_REMOVE) != FALSE) |
| return ProcessMessageHelper(msg); |
| return sent_messages_in_queue; |
| @@ -373,7 +499,7 @@ bool MessagePumpForUI::ProcessMessageHelper(const MSG& msg) { |
| // Repost the QUIT message so that it will be retrieved by the primary |
| // GetMessage() loop. |
| state_->should_quit = true; |
| - PostQuitMessage(static_cast<int>(msg.wParam)); |
| + g_post_quit(static_cast<int>(msg.wParam)); |
| return false; |
| } |
| @@ -381,11 +507,11 @@ bool MessagePumpForUI::ProcessMessageHelper(const MSG& msg) { |
| if (msg.message == kMsgHaveWork && msg.hwnd == message_hwnd_) |
| return ProcessPumpReplacementMessage(); |
| - if (CallMsgFilter(const_cast<MSG*>(&msg), kMessageFilterCode)) |
| + if (g_call_msg_filter(const_cast<MSG*>(&msg), kMessageFilterCode)) |
| return true; |
| - TranslateMessage(&msg); |
| - DispatchMessage(&msg); |
| + g_translate_message(&msg); |
| + g_dispatch_message(&msg); |
| return true; |
| } |
| @@ -401,7 +527,8 @@ bool MessagePumpForUI::ProcessPumpReplacementMessage() { |
| // asynchronous to this thread!! |
| MSG msg; |
| - const bool have_message = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != FALSE; |
| + const bool have_message = |
| + g_peek_message(&msg, NULL, 0, 0, PM_REMOVE) != FALSE; |
| // Expect no message or a message different than kMsgHaveWork. |
| DCHECK(!have_message || kMsgHaveWork != msg.message || |
| @@ -531,7 +658,7 @@ void MessagePumpForGpu::WaitForWork() { |
| debug::Alias(&delay); |
| DWORD result = |
| - MsgWaitForMultipleObjectsEx(1, &event_, delay, QS_ALLINPUT, 0); |
| + g_msg_wait_for_multiple_objects_ex(1, &event_, delay, QS_ALLINPUT, 0); |
| DCHECK_NE(WAIT_FAILED, result) << GetLastError(); |
| if (result != WAIT_TIMEOUT) { |
| // Either work or message available. |
| @@ -542,20 +669,20 @@ void MessagePumpForGpu::WaitForWork() { |
| bool MessagePumpForGpu::ProcessNextMessage() { |
| MSG msg; |
| - if (!PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) |
| + if (!g_peek_message(&msg, nullptr, 0, 0, PM_REMOVE)) |
| return false; |
| if (msg.message == WM_QUIT) { |
| // Repost the QUIT message so that it will be retrieved by the primary |
| // GetMessage() loop. |
| state_->should_quit = true; |
| - PostQuitMessage(static_cast<int>(msg.wParam)); |
| + g_post_quit(static_cast<int>(msg.wParam)); |
| return false; |
| } |
| - if (!CallMsgFilter(const_cast<MSG*>(&msg), kMessageFilterCode)) { |
| - TranslateMessage(&msg); |
| - DispatchMessage(&msg); |
| + if (!g_call_msg_filter(const_cast<MSG*>(&msg), kMessageFilterCode)) { |
| + g_translate_message(&msg); |
| + g_dispatch_message(&msg); |
| } |
| return true; |