Chromium Code Reviews| Index: base/message_pump_win.cc |
| diff --git a/base/message_pump_win.cc b/base/message_pump_win.cc |
| index 9484b29e67c5cc00bd98e92e18a34e4f10e43c6b..72657dc51710ed605de7ece4452a9a9d763b6e27 100644 |
| --- a/base/message_pump_win.cc |
| +++ b/base/message_pump_win.cc |
| @@ -8,11 +8,20 @@ |
| #include "base/message_loop.h" |
| #include "base/metrics/histogram.h" |
| +#include "base/process_util.h" |
| +#include "base/stringprintf.h" |
| #include "base/win/wrapped_window_proc.h" |
| +namespace { |
| + |
| +// The ID of the timer used by the UI message pump. |
| +const int kMessagePumpTimerId = 0; |
| + |
| +} // namespace |
| + |
| namespace base { |
| -static const wchar_t kWndClass[] = L"Chrome_MessagePumpWindow"; |
| +static const wchar_t kWndClassFormat[] = L"Chrome_MessagePumpWindow%p"; |
| // Message sent to get an additional time slice for pumping (processing) another |
| // task (a series of such messages creates a continuous task pump). |
| @@ -82,13 +91,19 @@ int MessagePumpWin::GetCurrentDelay() const { |
| //----------------------------------------------------------------------------- |
| // MessagePumpForUI public: |
| -MessagePumpForUI::MessagePumpForUI() { |
| +MessagePumpForUI::MessagePumpForUI() |
| + : atom_(0), |
| + instance_(NULL), |
| + message_hwnd_(NULL) { |
| InitMessageWnd(); |
| } |
| MessagePumpForUI::~MessagePumpForUI() { |
| - DestroyWindow(message_hwnd_); |
| - UnregisterClass(kWndClass, GetModuleHandle(NULL)); |
| + if (message_hwnd_ != NULL) |
| + DestroyWindow(message_hwnd_); |
| + |
| + if (atom_ != 0) |
| + UnregisterClass(reinterpret_cast<const char16*>(atom_), instance_); |
| } |
| void MessagePumpForUI::ScheduleWork() { |
| @@ -96,7 +111,7 @@ void MessagePumpForUI::ScheduleWork() { |
| return; // Someone else continued the pumping. |
| // Make sure the MessagePump does some work for us. |
| - PostMessage(message_hwnd_, kMsgHaveWork, reinterpret_cast<WPARAM>(this), 0); |
| + PostMessage(message_hwnd_, kMsgHaveWork, 0, 0); |
| } |
| void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) { |
| @@ -129,7 +144,7 @@ void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) { |
| // 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). |
| - SetTimer(message_hwnd_, reinterpret_cast<UINT_PTR>(this), delay_msec, NULL); |
| + SetTimer(message_hwnd_, kMessagePumpTimerId, delay_msec, NULL); |
| } |
| void MessagePumpForUI::PumpOutPendingPaintMessages() { |
| @@ -162,13 +177,19 @@ void MessagePumpForUI::PumpOutPendingPaintMessages() { |
| // static |
| LRESULT CALLBACK MessagePumpForUI::WndProcThunk( |
| HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { |
| - switch (message) { |
| - case kMsgHaveWork: |
| - reinterpret_cast<MessagePumpForUI*>(wparam)->HandleWorkMessage(); |
| - break; |
| - case WM_TIMER: |
| - reinterpret_cast<MessagePumpForUI*>(wparam)->HandleTimerMessage(); |
| - break; |
| + // Retrieve |this| from the user data, associated with the window. |
| + MessagePumpForUI* self = reinterpret_cast<MessagePumpForUI*>( |
| + GetWindowLongPtr(hwnd, GWLP_USERDATA)); |
| + if (self != NULL) { |
|
jar (doing other things)
2012/05/15 21:39:42
Perchance we should not check the value of |self|,
alexeypa (please no reviews)
2012/05/15 22:10:27
|self| should never be NULL except for WM_CREATE m
|
| + switch (message) { |
| + case kMsgHaveWork: |
| + self->HandleWorkMessage(); |
| + break; |
| + case WM_TIMER: |
| + DCHECK(wparam == kMessagePumpTimerId); |
| + self->HandleTimerMessage(); |
| + break; |
| + } |
| } |
| return DefWindowProc(hwnd, message, wparam, lparam); |
| } |
| @@ -211,7 +232,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)); |
| + KillTimer(message_hwnd_, kMessagePumpTimerId); |
| if (state_->should_quit) |
| break; |
| @@ -230,18 +251,38 @@ void MessagePumpForUI::DoRunLoop() { |
| } |
| void MessagePumpForUI::InitMessageWnd() { |
| - HINSTANCE hinst = GetModuleHandle(NULL); |
| + // Register a unique window class for each instance of UI pump. |
| + string16 class_name = base::StringPrintf(kWndClassFormat, this); |
| + WNDPROC window_procedure = &base::win::WrappedWindowProc<WndProcThunk>; |
| - WNDCLASSEX wc = {0}; |
| + // RegisterClassEx uses a handle of the module containing the window procedure |
| + // to distinguish identically named classes registered in different modules. |
| + instance_ = GetModuleFromAddress(window_procedure); |
| + |
| + WNDCLASSEXW wc = {0}; |
| wc.cbSize = sizeof(wc); |
| - wc.lpfnWndProc = base::win::WrappedWindowProc<WndProcThunk>; |
| - wc.hInstance = hinst; |
| - wc.lpszClassName = kWndClass; |
| - RegisterClassEx(&wc); |
| + wc.lpfnWndProc = window_procedure; |
| + wc.hInstance = instance_; |
| + wc.lpszClassName = class_name.c_str(); |
| + atom_ = RegisterClassEx(&wc); |
| + if (atom_ == 0) { |
| + DCHECK(atom_); |
|
alexeypa (please no reviews)
2012/05/15 22:10:27
We should also CHECK here.
|
| + return; |
| + } |
| + |
| + // Create the message-only window. |
| + message_hwnd_ = CreateWindow( |
| + reinterpret_cast<const char16*>(atom_), 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, |
| + instance_, 0); |
| + if (message_hwnd_ == NULL) { |
| + DCHECK(message_hwnd_); |
| + return; |
|
jar (doing other things)
2012/05/15 21:39:42
These return on error condition appear to mask a s
alexeypa (please no reviews)
2012/05/15 22:10:27
Those DCHECKs migrated from the previous version o
|
| + } |
| - message_hwnd_ = |
| - CreateWindow(kWndClass, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, 0); |
| - DCHECK(message_hwnd_); |
| + // Store |this| so that the window procedure could retrieve it later. |
| + SetWindowLongPtr(message_hwnd_, |
|
alexeypa (please no reviews)
2012/05/15 22:10:27
The return value of SetWindowLongPtr should be che
|
| + GWLP_USERDATA, |
| + reinterpret_cast<LONG_PTR>(this)); |
| } |
| void MessagePumpForUI::WaitForWork() { |
| @@ -300,7 +341,7 @@ void MessagePumpForUI::HandleWorkMessage() { |
| } |
| void MessagePumpForUI::HandleTimerMessage() { |
| - KillTimer(message_hwnd_, reinterpret_cast<UINT_PTR>(this)); |
| + KillTimer(message_hwnd_, kMessagePumpTimerId); |
| // 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 |