Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Side by Side Diff: ui/base/clipboard/clipboard_win.cc

Issue 17285002: ui::Clipboard now uses base::win::MessageWindow to create a message-only window on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/base/clipboard/clipboard.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Many of these functions are based on those found in 5 // Many of these functions are based on those found in
6 // webkit/port/platform/PasteboardWin.cpp 6 // webkit/port/platform/PasteboardWin.cpp
7 7
8 #include "ui/base/clipboard/clipboard.h" 8 #include "ui/base/clipboard/clipboard.h"
9 9
10 #include <shlobj.h> 10 #include <shlobj.h>
11 #include <shellapi.h> 11 #include <shellapi.h>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/memory/shared_memory.h" 16 #include "base/memory/shared_memory.h"
17 #include "base/message_loop.h" 17 #include "base/message_loop.h"
18 #include "base/safe_numerics.h" 18 #include "base/safe_numerics.h"
19 #include "base/stl_util.h" 19 #include "base/stl_util.h"
20 #include "base/strings/string_number_conversions.h" 20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
22 #include "base/strings/utf_offset_string_conversions.h" 22 #include "base/strings/utf_offset_string_conversions.h"
23 #include "base/strings/utf_string_conversions.h" 23 #include "base/strings/utf_string_conversions.h"
24 #include "base/win/message_window.h"
24 #include "base/win/scoped_gdi_object.h" 25 #include "base/win/scoped_gdi_object.h"
25 #include "base/win/scoped_hdc.h" 26 #include "base/win/scoped_hdc.h"
26 #include "base/win/wrapped_window_proc.h" 27 #include "base/win/wrapped_window_proc.h"
27 #include "third_party/skia/include/core/SkBitmap.h" 28 #include "third_party/skia/include/core/SkBitmap.h"
28 #include "ui/base/clipboard/clipboard_util_win.h" 29 #include "ui/base/clipboard/clipboard_util_win.h"
29 #include "ui/base/clipboard/custom_data_helper.h" 30 #include "ui/base/clipboard/custom_data_helper.h"
30 #include "ui/gfx/canvas.h" 31 #include "ui/gfx/canvas.h"
31 #include "ui/gfx/size.h" 32 #include "ui/gfx/size.h"
32 33
33 namespace ui { 34 namespace ui {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 opened_ = false; 88 opened_ = false;
88 } else { 89 } else {
89 NOTREACHED(); 90 NOTREACHED();
90 } 91 }
91 } 92 }
92 93
93 private: 94 private:
94 bool opened_; 95 bool opened_;
95 }; 96 };
96 97
97 LRESULT CALLBACK ClipboardOwnerWndProc(HWND hwnd,
98 UINT message,
99 WPARAM wparam,
100 LPARAM lparam) {
101 LRESULT lresult = 0;
102
103 switch (message) {
104 case WM_RENDERFORMAT:
105 // This message comes when SetClipboardData was sent a null data handle
106 // and now it's come time to put the data on the clipboard.
107 // We always set data, so there isn't a need to actually do anything here.
108 break;
109 case WM_RENDERALLFORMATS:
110 // This message comes when SetClipboardData was sent a null data handle
111 // and now this application is about to quit, so it must put data on
112 // the clipboard before it exits.
113 // We always set data, so there isn't a need to actually do anything here.
114 break;
115 case WM_DRAWCLIPBOARD:
116 break;
117 case WM_DESTROY:
118 break;
119 case WM_CHANGECBCHAIN:
120 break;
121 default:
122 lresult = DefWindowProc(hwnd, message, wparam, lparam);
123 break;
124 }
125 return lresult;
126 }
127
128 template <typename charT> 98 template <typename charT>
129 HGLOBAL CreateGlobalData(const std::basic_string<charT>& str) { 99 HGLOBAL CreateGlobalData(const std::basic_string<charT>& str) {
130 HGLOBAL data = 100 HGLOBAL data =
131 ::GlobalAlloc(GMEM_MOVEABLE, ((str.size() + 1) * sizeof(charT))); 101 ::GlobalAlloc(GMEM_MOVEABLE, ((str.size() + 1) * sizeof(charT)));
132 if (data) { 102 if (data) {
133 charT* raw_data = static_cast<charT*>(::GlobalLock(data)); 103 charT* raw_data = static_cast<charT*>(::GlobalLock(data));
134 memcpy(raw_data, str.data(), str.size() * sizeof(charT)); 104 memcpy(raw_data, str.data(), str.size() * sizeof(charT));
135 raw_data[str.size()] = '\0'; 105 raw_data[str.size()] = '\0';
136 ::GlobalUnlock(data); 106 ::GlobalUnlock(data);
137 } 107 }
(...skipping 16 matching lines...) Expand all
154 void MakeBitmapOpaque(const SkBitmap& bitmap) { 124 void MakeBitmapOpaque(const SkBitmap& bitmap) {
155 for (int x = 0; x < bitmap.width(); ++x) { 125 for (int x = 0; x < bitmap.width(); ++x) {
156 for (int y = 0; y < bitmap.height(); ++y) { 126 for (int y = 0; y < bitmap.height(); ++y) {
157 *bitmap.getAddr32(x, y) = SkColorSetA(*bitmap.getAddr32(x, y), 0xFF); 127 *bitmap.getAddr32(x, y) = SkColorSetA(*bitmap.getAddr32(x, y), 0xFF);
158 } 128 }
159 } 129 }
160 } 130 }
161 131
162 } // namespace 132 } // namespace
163 133
134 // Used to create a message-only window handling clipboard-related window
135 // messages. It is intended to be passed to OpenClipboard() API.
136 class Clipboard::ClipboardWindow
137 : public base::win::MessageWindow::Delegate {
138 public:
139 ClipboardWindow();
140 virtual ~ClipboardWindow();
141
142 // Creates the window if it is not created yat and returns its handle. Returns
143 // NULL if an error occurs.
144 HWND GetHandle();
145
146 // Returns |true| if the window is created.
147 bool IsValid() const;
148
149 private:
150 // base::win::MessageWindow::Delegate interface.
151 virtual bool HandleMessage(HWND hwnd,
152 UINT message,
153 WPARAM wparam,
154 LPARAM lparam,
155 LRESULT* result) OVERRIDE;
156
157 scoped_ptr<base::win::MessageWindow> window_;
cpu_(ooo_6.6-7.5) 2013/06/19 00:11:36 why scoped_ptr?
alexeypa (please no reviews) 2013/06/19 17:57:18 Yes, indeed. It does not need to be.
158
159 DISALLOW_COPY_AND_ASSIGN(ClipboardWindow);
160 };
161
162
163 Clipboard::ClipboardWindow::ClipboardWindow()
164 : window_(new base::win::MessageWindow()) {
165 }
166
167 Clipboard::ClipboardWindow::~ClipboardWindow() {
168 }
169
170 HWND Clipboard::ClipboardWindow::GetHandle() {
171 if (!IsValid())
172 window_->Create(this);
173
174 return window_->hwnd();
175 }
176
177 bool Clipboard::ClipboardWindow::IsValid() const {
178 return window_->hwnd() != NULL;
179 }
180
181 bool Clipboard::ClipboardWindow::HandleMessage(HWND hwnd,
182 UINT message,
183 WPARAM wparam,
184 LPARAM lparam,
185 LRESULT* result) {
186 switch (message) {
187 case WM_RENDERFORMAT:
188 // This message comes when SetClipboardData was sent a null data handle
189 // and now it's come time to put the data on the clipboard.
190 // We always set data, so there isn't a need to actually do anything here.
191 break;
192 case WM_RENDERALLFORMATS:
193 // This message comes when SetClipboardData was sent a null data handle
194 // and now this application is about to quit, so it must put data on
195 // the clipboard before it exits.
196 // We always set data, so there isn't a need to actually do anything here.
197 break;
198 case WM_DRAWCLIPBOARD:
199 break;
200 case WM_DESTROY:
201 break;
202 case WM_CHANGECBCHAIN:
203 break;
204 default:
205 return false;
206 }
207
208 *result = 0;
209 return true;
210 }
211
164 Clipboard::FormatType::FormatType() : data_() {} 212 Clipboard::FormatType::FormatType() : data_() {}
165 213
166 Clipboard::FormatType::FormatType(UINT native_format) : data_() { 214 Clipboard::FormatType::FormatType(UINT native_format) : data_() {
167 // There's no good way to actually initialize this in the constructor in 215 // There's no good way to actually initialize this in the constructor in
168 // C++03. 216 // C++03.
169 data_.cfFormat = native_format; 217 data_.cfFormat = native_format;
170 data_.dwAspect = DVASPECT_CONTENT; 218 data_.dwAspect = DVASPECT_CONTENT;
171 data_.lindex = -1; 219 data_.lindex = -1;
172 data_.tymed = TYMED_HGLOBAL; 220 data_.tymed = TYMED_HGLOBAL;
173 } 221 }
(...skipping 22 matching lines...) Expand all
196 NOTREACHED(); 244 NOTREACHED();
197 return FormatType(); 245 return FormatType();
198 } 246 }
199 return FormatType(clipboard_format); 247 return FormatType(clipboard_format);
200 } 248 }
201 249
202 bool Clipboard::FormatType::operator<(const FormatType& other) const { 250 bool Clipboard::FormatType::operator<(const FormatType& other) const {
203 return ToUINT() < other.ToUINT(); 251 return ToUINT() < other.ToUINT();
204 } 252 }
205 253
206 Clipboard::Clipboard() : create_window_(false) { 254 Clipboard::Clipboard() {
207 if (base::MessageLoop::current()->type() == base::MessageLoop::TYPE_UI) { 255 if (base::MessageLoop::current()->type() == base::MessageLoop::TYPE_UI)
208 // Make a dummy HWND to be the clipboard's owner. 256 clipboard_owner_.reset(new ClipboardWindow());
209 WNDCLASSEX window_class;
210 base::win::InitializeWindowClass(
211 L"ClipboardOwnerWindowClass",
212 &base::win::WrappedWindowProc<ClipboardOwnerWndProc>,
213 0, 0, 0, NULL, NULL, NULL, NULL, NULL,
214 &window_class);
215 ::RegisterClassEx(&window_class);
216 create_window_ = true;
217 }
218
219 clipboard_owner_ = NULL;
220 } 257 }
221 258
222 Clipboard::~Clipboard() { 259 Clipboard::~Clipboard() {
223 if (clipboard_owner_)
224 ::DestroyWindow(clipboard_owner_);
225 clipboard_owner_ = NULL;
226 } 260 }
227 261
228 void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) { 262 void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) {
229 DCHECK_EQ(buffer, BUFFER_STANDARD); 263 DCHECK_EQ(buffer, BUFFER_STANDARD);
230 264
231 ScopedClipboard clipboard; 265 ScopedClipboard clipboard;
232 if (!clipboard.Acquire(GetClipboardWindow())) 266 if (!clipboard.Acquire(GetClipboardWindow()))
233 return; 267 return;
234 268
235 ::EmptyClipboard(); 269 ::EmptyClipboard();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 bookmark.append(1, L'\n'); 310 bookmark.append(1, L'\n');
277 bookmark.append(url_data, url_len); 311 bookmark.append(url_data, url_len);
278 312
279 string16 wide_bookmark = UTF8ToWide(bookmark); 313 string16 wide_bookmark = UTF8ToWide(bookmark);
280 HGLOBAL glob = CreateGlobalData(wide_bookmark); 314 HGLOBAL glob = CreateGlobalData(wide_bookmark);
281 315
282 WriteToClipboard(GetUrlWFormatType().ToUINT(), glob); 316 WriteToClipboard(GetUrlWFormatType().ToUINT(), glob);
283 } 317 }
284 318
285 void Clipboard::WriteWebSmartPaste() { 319 void Clipboard::WriteWebSmartPaste() {
286 DCHECK(clipboard_owner_); 320 DCHECK(clipboard_owner_->IsValid());
287 ::SetClipboardData(GetWebKitSmartPasteFormatType().ToUINT(), NULL); 321 ::SetClipboardData(GetWebKitSmartPasteFormatType().ToUINT(), NULL);
288 } 322 }
289 323
290 void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { 324 void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) {
291 const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data); 325 const gfx::Size* size = reinterpret_cast<const gfx::Size*>(size_data);
292 HDC dc = ::GetDC(NULL); 326 HDC dc = ::GetDC(NULL);
293 327
294 // This doesn't actually cost us a memcpy when the bitmap comes from the 328 // This doesn't actually cost us a memcpy when the bitmap comes from the
295 // renderer as we load it into the bitmap using setPixels which just sets a 329 // renderer as we load it into the bitmap using setPixels which just sets a
296 // pointer. Someone has to memcpy it into GDI, it might as well be us here. 330 // pointer. Someone has to memcpy it into GDI, it might as well be us here.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 if (!hdata) 405 if (!hdata)
372 return; 406 return;
373 407
374 char* data = static_cast<char*>(::GlobalLock(hdata)); 408 char* data = static_cast<char*>(::GlobalLock(hdata));
375 memcpy(data, data_data, data_len); 409 memcpy(data, data_data, data_len);
376 ::GlobalUnlock(data); 410 ::GlobalUnlock(data);
377 WriteToClipboard(format.ToUINT(), hdata); 411 WriteToClipboard(format.ToUINT(), hdata);
378 } 412 }
379 413
380 void Clipboard::WriteToClipboard(unsigned int format, HANDLE handle) { 414 void Clipboard::WriteToClipboard(unsigned int format, HANDLE handle) {
381 DCHECK(clipboard_owner_); 415 DCHECK(clipboard_owner_->IsValid());
382 if (handle && !::SetClipboardData(format, handle)) { 416 if (handle && !::SetClipboardData(format, handle)) {
383 DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError()); 417 DCHECK(ERROR_CLIPBOARD_NOT_OPEN != GetLastError());
384 FreeData(format, handle); 418 FreeData(format, handle);
385 } 419 }
386 } 420 }
387 421
388 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { 422 uint64 Clipboard::GetSequenceNumber(Buffer buffer) {
389 DCHECK_EQ(buffer, BUFFER_STANDARD); 423 DCHECK_EQ(buffer, BUFFER_STANDARD);
390 return ::GetClipboardSequenceNumber(); 424 return ::GetClipboardSequenceNumber();
391 } 425 }
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 852
819 // static 853 // static
820 void Clipboard::FreeData(unsigned int format, HANDLE data) { 854 void Clipboard::FreeData(unsigned int format, HANDLE data) {
821 if (format == CF_BITMAP) 855 if (format == CF_BITMAP)
822 ::DeleteObject(static_cast<HBITMAP>(data)); 856 ::DeleteObject(static_cast<HBITMAP>(data));
823 else 857 else
824 ::GlobalFree(data); 858 ::GlobalFree(data);
825 } 859 }
826 860
827 HWND Clipboard::GetClipboardWindow() const { 861 HWND Clipboard::GetClipboardWindow() const {
828 if (!clipboard_owner_ && create_window_) { 862 return clipboard_owner_ ? clipboard_owner_->GetHandle() : NULL;
829 clipboard_owner_ = ::CreateWindow(L"ClipboardOwnerWindowClass",
830 L"ClipboardOwnerWindow",
831 0, 0, 0, 0, 0,
832 HWND_MESSAGE,
833 0, 0, 0);
834 }
835 return clipboard_owner_;
836 } 863 }
837 864
838 } // namespace ui 865 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/clipboard/clipboard.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698