Chromium Code Reviews| Index: remoting/host/clipboard_win.cc |
| diff --git a/remoting/host/clipboard_win.cc b/remoting/host/clipboard_win.cc |
| index 3b766c5be30cc25c37f42eef7d6421ea6e0c219a..4976a5585cd11facdece619ee6575f3b9abadfde 100644 |
| --- a/remoting/host/clipboard_win.cc |
| +++ b/remoting/host/clipboard_win.cc |
| @@ -18,14 +18,12 @@ |
| #include "base/win/wrapped_window_proc.h" |
| #include "remoting/base/constants.h" |
| #include "remoting/base/util.h" |
| +#include "remoting/host/win/message_window.h" |
| #include "remoting/proto/event.pb.h" |
| #include "remoting/protocol/clipboard_stub.h" |
| namespace { |
| -const WCHAR kWindowClassName[] = L"clipboardWindowClass"; |
| -const WCHAR kWindowName[] = L"clipboardWindow"; |
| - |
| // A scoper class that opens and closes the clipboard. |
| // This class was adapted from the ScopedClipboard class in |
| // ui/base/clipboard/clipboard_win.cc. |
| @@ -102,7 +100,8 @@ typedef BOOL (WINAPI RemoveClipboardFormatListenerFn)(HWND); |
| namespace remoting { |
| -class ClipboardWin : public Clipboard { |
| +class ClipboardWin : public Clipboard, |
| + public win::MessageWindow::Delegate { |
| public: |
| ClipboardWin(); |
| @@ -114,69 +113,61 @@ class ClipboardWin : public Clipboard { |
| private: |
| void OnClipboardUpdate(); |
| - bool HaveClipboardListenerApi(); |
| - static bool RegisterWindowClass(); |
| - static LRESULT CALLBACK WndProc(HWND hwmd, UINT msg, WPARAM wParam, |
| - LPARAM lParam); |
| + // win::MessageWindow::Delegate interface. |
| + virtual bool HandleMessage(UINT message, WPARAM wparam, LPARAM lparam, |
| + LRESULT* result) OVERRIDE; |
| scoped_ptr<protocol::ClipboardStub> client_clipboard_; |
| - HWND hwnd_; |
| AddClipboardFormatListenerFn* add_clipboard_format_listener_; |
| RemoveClipboardFormatListenerFn* remove_clipboard_format_listener_; |
| - bool load_functions_tried_; |
| + |
| + // Used to subsribe to WM_CLIPBOARDUPDATE messages. |
|
dcaiafa
2013/03/28 23:25:35
nit: subscribe
alexeypa (please no reviews)
2013/03/29 16:57:01
Done.
|
| + scoped_ptr<win::MessageWindow> window_; |
| DISALLOW_COPY_AND_ASSIGN(ClipboardWin); |
| }; |
| ClipboardWin::ClipboardWin() |
| - : hwnd_(NULL), |
| - add_clipboard_format_listener_(NULL), |
| - remove_clipboard_format_listener_(NULL), |
| - load_functions_tried_(false) { |
| + : add_clipboard_format_listener_(NULL), |
| + remove_clipboard_format_listener_(NULL) { |
| } |
| void ClipboardWin::Start( |
| scoped_ptr<protocol::ClipboardStub> client_clipboard) { |
| + DCHECK(!add_clipboard_format_listener_); |
| + DCHECK(!remove_clipboard_format_listener_); |
| + DCHECK(!window_); |
| + |
| client_clipboard_.swap(client_clipboard); |
| - if (!load_functions_tried_) { |
| - load_functions_tried_ = true; |
| - HMODULE user32_module = ::GetModuleHandle(L"user32.dll"); |
| - if (!user32_module) { |
| - LOG(WARNING) << "Couldn't find user32.dll."; |
| - } else { |
| - add_clipboard_format_listener_ = |
| - reinterpret_cast<AddClipboardFormatListenerFn*>( |
| - ::GetProcAddress(user32_module, "AddClipboardFormatListener")); |
| - remove_clipboard_format_listener_ = |
| - reinterpret_cast<RemoveClipboardFormatListenerFn*>( |
| - ::GetProcAddress(user32_module, "RemoveClipboardFormatListener")); |
| - if (!HaveClipboardListenerApi()) { |
| - LOG(WARNING) << "Couldn't load AddClipboardFormatListener or " |
| - << "RemoveClipboardFormatListener."; |
| - } |
| - } |
| + // user32.dll is statically linked. |
| + HMODULE user32 = GetModuleHandle(L"user32.dll"); |
| + CHECK(user32); |
| + |
| + add_clipboard_format_listener_ = |
| + reinterpret_cast<AddClipboardFormatListenerFn*>( |
| + GetProcAddress(user32, "AddClipboardFormatListener")); |
| + if (add_clipboard_format_listener_) { |
| + remove_clipboard_format_listener_ = |
| + reinterpret_cast<RemoveClipboardFormatListenerFn*>( |
| + GetProcAddress(user32, "RemoveClipboardFormatListener")); |
| + // If AddClipboardFormatListener() present, RemoveClipboardFormatListener() |
| + // should be available too. |
| + CHECK(remove_clipboard_format_listener_); |
| + } else { |
| + LOG(WARNING) << "AddClipboardFormatListener() is not available."; |
| } |
| - if (!RegisterWindowClass()) { |
| - LOG(ERROR) << "Couldn't register clipboard window class."; |
| - return; |
| - } |
| - hwnd_ = ::CreateWindow(kWindowClassName, |
| - kWindowName, |
| - 0, 0, 0, 0, 0, |
| - HWND_MESSAGE, |
| - NULL, |
| - base::GetModuleFromAddress(&WndProc), |
| - this); |
| - if (!hwnd_) { |
| + window_.reset(new win::MessageWindow()); |
| + if (!window_->Create(this)) { |
| LOG(ERROR) << "Couldn't create clipboard window."; |
| + window_.reset(); |
| return; |
| } |
| - if (HaveClipboardListenerApi()) { |
| - if (!(*add_clipboard_format_listener_)(hwnd_)) { |
| + if (add_clipboard_format_listener_) { |
| + if (!(*add_clipboard_format_listener_)(window_->hwnd())) { |
| LOG(WARNING) << "AddClipboardFormatListener() failed: " << GetLastError(); |
| } |
| } |
| @@ -185,18 +176,15 @@ void ClipboardWin::Start( |
| void ClipboardWin::Stop() { |
| client_clipboard_.reset(); |
| - if (hwnd_) { |
| - if (HaveClipboardListenerApi()) { |
| - (*remove_clipboard_format_listener_)(hwnd_); |
| - } |
| - ::DestroyWindow(hwnd_); |
| - hwnd_ = NULL; |
| - } |
| + if (window_ && remove_clipboard_format_listener_) |
| + (*remove_clipboard_format_listener_)(window_->hwnd()); |
| + |
| + window_.reset(); |
| } |
| void ClipboardWin::InjectClipboardEvent( |
| const protocol::ClipboardEvent& event) { |
| - if (!hwnd_) |
| + if (!window_) |
| return; |
| // Currently we only handle UTF-8 text. |
| @@ -210,7 +198,7 @@ void ClipboardWin::InjectClipboardEvent( |
| string16 text = UTF8ToUTF16(ReplaceLfByCrLf(event.data())); |
| ScopedClipboard clipboard; |
| - if (!clipboard.Init(hwnd_)) { |
| + if (!clipboard.Init(window_->hwnd())) { |
| LOG(WARNING) << "Couldn't open the clipboard."; |
| return; |
| } |
| @@ -234,7 +222,7 @@ void ClipboardWin::InjectClipboardEvent( |
| } |
| void ClipboardWin::OnClipboardUpdate() { |
| - DCHECK(hwnd_); |
| + DCHECK(window_); |
| if (::IsClipboardFormatAvailable(CF_UNICODETEXT)) { |
| string16 text; |
| @@ -242,7 +230,7 @@ void ClipboardWin::OnClipboardUpdate() { |
| // possible. |
| { |
| ScopedClipboard clipboard; |
| - if (!clipboard.Init(hwnd_)) { |
| + if (!clipboard.Init(window_->hwnd())) { |
| LOG(WARNING) << "Couldn't open the clipboard." << GetLastError(); |
| return; |
| } |
| @@ -272,49 +260,15 @@ void ClipboardWin::OnClipboardUpdate() { |
| } |
| } |
| -bool ClipboardWin::HaveClipboardListenerApi() { |
| - return add_clipboard_format_listener_ && remove_clipboard_format_listener_; |
| -} |
| - |
| -bool ClipboardWin::RegisterWindowClass() { |
| - // This method is only called on the UI thread, so it doesn't matter |
| - // that the following test is not thread-safe. |
| - static bool registered = false; |
| - if (registered) { |
| +bool ClipboardWin::HandleMessage( |
| + UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result) { |
| + if (message == WM_CLIPBOARDUPDATE) { |
| + OnClipboardUpdate(); |
| + *result = 0; |
| return true; |
| } |
| - WNDCLASSEX window_class; |
| - base::win::InitializeWindowClass( |
| - kWindowClassName, |
| - base::win::WrappedWindowProc<WndProc>, |
| - 0, 0, 0, NULL, NULL, NULL, NULL, NULL, |
| - &window_class); |
| - if (!::RegisterClassEx(&window_class)) { |
| - return false; |
| - } |
| - |
| - registered = true; |
| - return true; |
| -} |
| - |
| -LRESULT CALLBACK ClipboardWin::WndProc(HWND hwnd, UINT msg, WPARAM wparam, |
| - LPARAM lparam) { |
| - if (msg == WM_CREATE) { |
| - CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lparam); |
| - ::SetWindowLongPtr(hwnd, |
| - GWLP_USERDATA, |
| - reinterpret_cast<LONG_PTR>(cs->lpCreateParams)); |
| - return 0; |
| - } |
| - ClipboardWin* clipboard = |
| - reinterpret_cast<ClipboardWin*>(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); |
| - switch (msg) { |
| - case WM_CLIPBOARDUPDATE: |
| - clipboard->OnClipboardUpdate(); |
| - return 0; |
| - } |
| - return ::DefWindowProc(hwnd, msg, wparam, lparam); |
| + return false; |
| } |
| scoped_ptr<Clipboard> Clipboard::Create() { |