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

Side by Side Diff: ui/views/win/hwnd_message_handler.cc

Issue 10871077: Move more code from NWW to HWNDMessageHandler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 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/views/win/hwnd_message_handler.h ('k') | ui/views/win/hwnd_message_handler_delegate.h » ('j') | 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 #include "ui/views/win/hwnd_message_handler.h" 5 #include "ui/views/win/hwnd_message_handler.h"
6 6
7 #include <dwmapi.h> 7 #include <dwmapi.h>
8 #include <shellapi.h> 8 #include <shellapi.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/system_monitor/system_monitor.h" 11 #include "base/system_monitor/system_monitor.h"
12 #include "base/win/windows_version.h" 12 #include "base/win/windows_version.h"
13 #include "ui/gfx/insets.h"
14 #include "ui/gfx/path.h"
15 #include "ui/base/event.h" 13 #include "ui/base/event.h"
16 #include "ui/base/keycodes/keyboard_code_conversion_win.h" 14 #include "ui/base/keycodes/keyboard_code_conversion_win.h"
17 #include "ui/base/native_theme/native_theme_win.h" 15 #include "ui/base/native_theme/native_theme_win.h"
18 #include "ui/base/win/hwnd_util.h" 16 #include "ui/base/win/hwnd_util.h"
19 #include "ui/base/win/mouse_wheel_util.h" 17 #include "ui/base/win/mouse_wheel_util.h"
20 #include "ui/base/win/shell.h" 18 #include "ui/base/win/shell.h"
19 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/canvas_paint.h"
21 #include "ui/gfx/canvas_skia_paint.h"
22 #include "ui/gfx/insets.h"
23 #include "ui/gfx/path.h"
24 #include "ui/gfx/screen.h"
25 #include "ui/views/accessibility/native_view_accessibility_win.h"
21 #include "ui/views/ime/input_method_win.h" 26 #include "ui/views/ime/input_method_win.h"
22 #include "ui/views/widget/monitor_win.h" 27 #include "ui/views/widget/monitor_win.h"
23 #include "ui/views/widget/native_widget_win.h" 28 #include "ui/views/widget/native_widget_win.h"
24 #include "ui/views/widget/widget_hwnd_utils.h" 29 #include "ui/views/widget/widget_hwnd_utils.h"
25 #include "ui/views/win/fullscreen_handler.h" 30 #include "ui/views/win/fullscreen_handler.h"
26 #include "ui/views/win/hwnd_message_handler_delegate.h" 31 #include "ui/views/win/hwnd_message_handler_delegate.h"
27 #include "ui/views/win/scoped_fullscreen_visibility.h" 32 #include "ui/views/win/scoped_fullscreen_visibility.h"
28 33
29 #if !defined(USE_AURA) 34 #if !defined(USE_AURA)
30 #include "base/command_line.h" 35 #include "base/command_line.h"
31 #include "ui/base/ui_base_switches.h" 36 #include "ui/base/ui_base_switches.h"
32 #endif 37 #endif
33 38
34 namespace views { 39 namespace views {
35 namespace { 40 namespace {
36 41
42 // MoveLoopMouseWatcher is used to determine if the user canceled or completed a
43 // move. win32 doesn't appear to offer a way to determine the result of a move,
44 // so we install hooks to determine if we got a mouse up and assume the move
45 // completed.
46 class MoveLoopMouseWatcher {
47 public:
48 explicit MoveLoopMouseWatcher(HWNDMessageHandler* host);
49 ~MoveLoopMouseWatcher();
50
51 // Returns true if the mouse is up, or if we couldn't install the hook.
52 bool got_mouse_up() const { return got_mouse_up_; }
53
54 private:
55 // Instance that owns the hook. We only allow one instance to hook the mouse
56 // at a time.
57 static MoveLoopMouseWatcher* instance_;
58
59 // Key and mouse callbacks from the hook.
60 static LRESULT CALLBACK MouseHook(int n_code, WPARAM w_param, LPARAM l_param);
61 static LRESULT CALLBACK KeyHook(int n_code, WPARAM w_param, LPARAM l_param);
62
63 void Unhook();
64
65 // HWNDMessageHandler that created us.
66 HWNDMessageHandler* host_;
67
68 // Did we get a mouse up?
69 bool got_mouse_up_;
70
71 // Hook identifiers.
72 HHOOK mouse_hook_;
73 HHOOK key_hook_;
74
75 DISALLOW_COPY_AND_ASSIGN(MoveLoopMouseWatcher);
76 };
77
78 // static
79 MoveLoopMouseWatcher* MoveLoopMouseWatcher::instance_ = NULL;
80
81 MoveLoopMouseWatcher::MoveLoopMouseWatcher(HWNDMessageHandler* host)
82 : host_(host),
83 got_mouse_up_(false),
84 mouse_hook_(NULL),
85 key_hook_(NULL) {
86 // Only one instance can be active at a time.
87 if (instance_)
88 instance_->Unhook();
89
90 mouse_hook_ = SetWindowsHookEx(
91 WH_MOUSE, &MouseHook, NULL, GetCurrentThreadId());
92 if (mouse_hook_) {
93 instance_ = this;
94 // We don't care if setting the key hook succeeded.
95 key_hook_ = SetWindowsHookEx(
96 WH_KEYBOARD, &KeyHook, NULL, GetCurrentThreadId());
97 }
98 if (instance_ != this) {
99 // Failed installation. Assume we got a mouse up in this case, otherwise
100 // we'll think all drags were canceled.
101 got_mouse_up_ = true;
102 }
103 }
104
105 MoveLoopMouseWatcher::~MoveLoopMouseWatcher() {
106 Unhook();
107 }
108
109 void MoveLoopMouseWatcher::Unhook() {
110 if (instance_ != this)
111 return;
112
113 DCHECK(mouse_hook_);
114 UnhookWindowsHookEx(mouse_hook_);
115 if (key_hook_)
116 UnhookWindowsHookEx(key_hook_);
117 key_hook_ = NULL;
118 mouse_hook_ = NULL;
119 instance_ = NULL;
120 }
121
122 // static
123 LRESULT CALLBACK MoveLoopMouseWatcher::MouseHook(int n_code,
124 WPARAM w_param,
125 LPARAM l_param) {
126 DCHECK(instance_);
127 if (n_code == HC_ACTION && w_param == WM_LBUTTONUP)
128 instance_->got_mouse_up_ = true;
129 return CallNextHookEx(instance_->mouse_hook_, n_code, w_param, l_param);
130 }
131
132 // static
133 LRESULT CALLBACK MoveLoopMouseWatcher::KeyHook(int n_code,
134 WPARAM w_param,
135 LPARAM l_param) {
136 if (n_code == HC_ACTION && w_param == VK_ESCAPE) {
137 if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
138 int value = TRUE;
139 HRESULT result = DwmSetWindowAttribute(
140 instance_->host_->hwnd(),
141 DWMWA_TRANSITIONS_FORCEDISABLED,
142 &value,
143 sizeof(value));
144 }
145 // Hide the window on escape, otherwise the window is visibly going to snap
146 // back to the original location before we close it.
147 // This behavior is specific to tab dragging, in that we generally wouldn't
148 // want this functionality if we have other consumers using this API.
149 instance_->host_->Hide();
150 }
151 return CallNextHookEx(instance_->key_hook_, n_code, w_param, l_param);
152 }
153
37 // Called from OnNCActivate. 154 // Called from OnNCActivate.
38 BOOL CALLBACK EnumChildWindowsForRedraw(HWND hwnd, LPARAM lparam) { 155 BOOL CALLBACK EnumChildWindowsForRedraw(HWND hwnd, LPARAM lparam) {
39 DWORD process_id; 156 DWORD process_id;
40 GetWindowThreadProcessId(hwnd, &process_id); 157 GetWindowThreadProcessId(hwnd, &process_id);
41 int flags = RDW_INVALIDATE | RDW_NOCHILDREN | RDW_FRAME; 158 int flags = RDW_INVALIDATE | RDW_NOCHILDREN | RDW_FRAME;
42 if (process_id == GetCurrentProcessId()) 159 if (process_id == GetCurrentProcessId())
43 flags |= RDW_UPDATENOW; 160 flags |= RDW_UPDATENOW;
44 RedrawWindow(hwnd, NULL, NULL, flags); 161 RedrawWindow(hwnd, NULL, NULL, flags);
45 return TRUE; 162 return TRUE;
46 } 163 }
(...skipping 30 matching lines...) Expand all
77 } 194 }
78 return TRUE; 195 return TRUE;
79 } 196 }
80 197
81 // Enables or disables the menu item for the specified command and menu. 198 // Enables or disables the menu item for the specified command and menu.
82 void EnableMenuItemByCommand(HMENU menu, UINT command, bool enabled) { 199 void EnableMenuItemByCommand(HMENU menu, UINT command, bool enabled) {
83 UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED); 200 UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED);
84 EnableMenuItem(menu, command, flags); 201 EnableMenuItem(menu, command, flags);
85 } 202 }
86 203
204 // Callback used to notify child windows that the top level window received a
205 // DWMCompositionChanged message.
206 BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) {
207 SendMessage(window, WM_DWMCOMPOSITIONCHANGED, 0, 0);
208 return TRUE;
209 }
210
211 // See comments in OnNCPaint() for details of this struct.
212 struct ClipState {
213 // The window being painted.
214 HWND parent;
215
216 // DC painting to.
217 HDC dc;
218
219 // Origin of the window in terms of the screen.
220 int x;
221 int y;
222 };
223
224 // See comments in OnNCPaint() for details of this function.
225 static BOOL CALLBACK ClipDCToChild(HWND window, LPARAM param) {
226 ClipState* clip_state = reinterpret_cast<ClipState*>(param);
227 if (GetParent(window) == clip_state->parent && IsWindowVisible(window)) {
228 RECT bounds;
229 GetWindowRect(window, &bounds);
230 ExcludeClipRect(clip_state->dc,
231 bounds.left - clip_state->x,
232 bounds.top - clip_state->y,
233 bounds.right - clip_state->x,
234 bounds.bottom - clip_state->y);
235 }
236 return TRUE;
237 }
238
87 // A custom MSAA object id used to determine if a screen reader is actively 239 // A custom MSAA object id used to determine if a screen reader is actively
88 // listening for MSAA events. 240 // listening for MSAA events.
89 const int kCustomObjectID = 1; 241 const int kCustomObjectID = 1;
90 242
91 // The thickness of an auto-hide taskbar in pixels. 243 // The thickness of an auto-hide taskbar in pixels.
92 const int kAutoHideTaskbarThicknessPx = 2; 244 const int kAutoHideTaskbarThicknessPx = 2;
93 245
94 } // namespace 246 } // namespace
95 247
96 // A scoping class that prevents a window from being able to redraw in response 248 // A scoping class that prevents a window from being able to redraw in response
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 }; 310 };
159 311
160 //////////////////////////////////////////////////////////////////////////////// 312 ////////////////////////////////////////////////////////////////////////////////
161 // HWNDMessageHandler, public: 313 // HWNDMessageHandler, public:
162 314
163 HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate) 315 HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate)
164 : delegate_(delegate), 316 : delegate_(delegate),
165 ALLOW_THIS_IN_INITIALIZER_LIST(fullscreen_handler_(new FullscreenHandler( 317 ALLOW_THIS_IN_INITIALIZER_LIST(fullscreen_handler_(new FullscreenHandler(
166 delegate->AsNativeWidgetWin()->GetWidget()))), 318 delegate->AsNativeWidgetWin()->GetWidget()))),
167 remove_standard_frame_(false), 319 remove_standard_frame_(false),
320 previous_cursor_(NULL),
168 active_mouse_tracking_flags_(0), 321 active_mouse_tracking_flags_(0),
169 is_right_mouse_pressed_on_caption_(false), 322 is_right_mouse_pressed_on_caption_(false),
170 lock_updates_count_(0), 323 lock_updates_count_(0),
171 destroyed_(NULL), 324 destroyed_(NULL),
172 ignore_window_pos_changes_(false), 325 ignore_window_pos_changes_(false),
173 ALLOW_THIS_IN_INITIALIZER_LIST(ignore_pos_changes_factory_(this)), 326 ALLOW_THIS_IN_INITIALIZER_LIST(ignore_pos_changes_factory_(this)),
174 last_monitor_(NULL) { 327 last_monitor_(NULL),
328 use_layered_buffer_(false),
329 layered_alpha_(255),
330 ALLOW_THIS_IN_INITIALIZER_LIST(paint_layered_window_factory_(this)),
331 can_update_layered_window_(true) {
175 } 332 }
176 333
177 HWNDMessageHandler::~HWNDMessageHandler() { 334 HWNDMessageHandler::~HWNDMessageHandler() {
178 if (destroyed_ != NULL) 335 if (destroyed_ != NULL)
179 *destroyed_ = true; 336 *destroyed_ = true;
180 } 337 }
181 338
182 void HWNDMessageHandler::Init(const gfx::Rect& bounds) { 339 void HWNDMessageHandler::Init(const gfx::Rect& bounds) {
183 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, 340 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_,
184 &last_work_area_); 341 &last_work_area_);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 if (show_state) { 412 if (show_state) {
256 if (wp.showCmd == SW_SHOWMAXIMIZED) 413 if (wp.showCmd == SW_SHOWMAXIMIZED)
257 *show_state = ui::SHOW_STATE_MAXIMIZED; 414 *show_state = ui::SHOW_STATE_MAXIMIZED;
258 else if (wp.showCmd == SW_SHOWMINIMIZED) 415 else if (wp.showCmd == SW_SHOWMINIMIZED)
259 *show_state = ui::SHOW_STATE_MINIMIZED; 416 *show_state = ui::SHOW_STATE_MINIMIZED;
260 else 417 else
261 *show_state = ui::SHOW_STATE_NORMAL; 418 *show_state = ui::SHOW_STATE_NORMAL;
262 } 419 }
263 } 420 }
264 421
422 gfx::Rect HWNDMessageHandler::GetWorkAreaBoundsInScreen() const {
423 return gfx::Screen::GetDisplayNearestWindow(hwnd()).work_area();
424 }
425
265 void HWNDMessageHandler::SetBounds(const gfx::Rect& bounds) { 426 void HWNDMessageHandler::SetBounds(const gfx::Rect& bounds) {
266 LONG style = GetWindowLong(hwnd(), GWL_STYLE); 427 LONG style = GetWindowLong(hwnd(), GWL_STYLE);
267 if (style & WS_MAXIMIZE) 428 if (style & WS_MAXIMIZE)
268 SetWindowLong(hwnd(), GWL_STYLE, style & ~WS_MAXIMIZE); 429 SetWindowLong(hwnd(), GWL_STYLE, style & ~WS_MAXIMIZE);
269 SetWindowPos(hwnd(), NULL, bounds.x(), bounds.y(), bounds.width(), 430 SetWindowPos(hwnd(), NULL, bounds.x(), bounds.y(), bounds.width(),
270 bounds.height(), SWP_NOACTIVATE | SWP_NOZORDER); 431 bounds.height(), SWP_NOACTIVATE | SWP_NOZORDER);
271 } 432 }
272 433
273 void HWNDMessageHandler::SetSize(const gfx::Size& size) { 434 void HWNDMessageHandler::SetSize(const gfx::Size& size) {
274 SetWindowPos(hwnd(), NULL, 0, 0, size.width(), size.height(), 435 SetWindowPos(hwnd(), NULL, 0, 0, size.width(), size.height(),
275 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); 436 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE);
276 } 437 }
277 438
439 void HWNDMessageHandler::CenterWindow(const gfx::Size& size) {
440 HWND parent = GetParent(hwnd());
441 if (!IsWindow(hwnd()))
442 parent = ::GetWindow(hwnd(), GW_OWNER);
443 ui::CenterAndSizeWindow(parent, hwnd(), size);
444 }
445
278 void HWNDMessageHandler::SetRegion(HRGN region) { 446 void HWNDMessageHandler::SetRegion(HRGN region) {
279 SetWindowRgn(hwnd(), region, TRUE); 447 SetWindowRgn(hwnd(), region, TRUE);
280 } 448 }
281 449
282 void HWNDMessageHandler::StackAbove(HWND other_hwnd) { 450 void HWNDMessageHandler::StackAbove(HWND other_hwnd) {
283 SetWindowPos(hwnd(), other_hwnd, 0, 0, 0, 0, 451 SetWindowPos(hwnd(), other_hwnd, 0, 0, 0, 0,
284 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); 452 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
285 } 453 }
286 454
287 void HWNDMessageHandler::StackAtTop() { 455 void HWNDMessageHandler::StackAtTop() {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 } 520 }
353 521
354 bool HWNDMessageHandler::IsMinimized() const { 522 bool HWNDMessageHandler::IsMinimized() const {
355 return !!::IsIconic(hwnd()); 523 return !!::IsIconic(hwnd());
356 } 524 }
357 525
358 bool HWNDMessageHandler::IsMaximized() const { 526 bool HWNDMessageHandler::IsMaximized() const {
359 return !!::IsZoomed(hwnd()); 527 return !!::IsZoomed(hwnd());
360 } 528 }
361 529
530 bool HWNDMessageHandler::RunMoveLoop(const gfx::Point& drag_offset) {
531 ReleaseCapture();
532 MoveLoopMouseWatcher watcher(this);
533 SendMessage(hwnd(), WM_SYSCOMMAND, SC_MOVE | 0x0002, GetMessagePos());
534 // Windows doesn't appear to offer a way to determine whether the user
535 // canceled the move or not. We assume if the user released the mouse it was
536 // successful.
537 return watcher.got_mouse_up();
538 }
539
362 void HWNDMessageHandler::SendFrameChanged() { 540 void HWNDMessageHandler::SendFrameChanged() {
363 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, 541 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0,
364 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | 542 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS |
365 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | 543 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION |
366 SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); 544 SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER);
367 } 545 }
368 546
369 void HWNDMessageHandler::FlashFrame(bool flash) { 547 void HWNDMessageHandler::FlashFrame(bool flash) {
370 FLASHWINFO fwi; 548 FLASHWINFO fwi;
371 fwi.cbSize = sizeof(fwi); 549 fwi.cbSize = sizeof(fwi);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 591
414 InputMethod* HWNDMessageHandler::CreateInputMethod() { 592 InputMethod* HWNDMessageHandler::CreateInputMethod() {
415 #if !defined(USE_AURA) 593 #if !defined(USE_AURA)
416 CommandLine* command_line = CommandLine::ForCurrentProcess(); 594 CommandLine* command_line = CommandLine::ForCurrentProcess();
417 if (!command_line->HasSwitch(switches::kEnableViewsTextfield)) 595 if (!command_line->HasSwitch(switches::kEnableViewsTextfield))
418 return NULL; 596 return NULL;
419 #endif 597 #endif
420 return new InputMethodWin(this); 598 return new InputMethodWin(this);
421 } 599 }
422 600
601 void HWNDMessageHandler::SendNativeAccessibilityEvent(
602 int id,
603 ui::AccessibilityTypes::Event event_type) {
604 // Now call the Windows-specific method to notify MSAA clients of this
605 // event. The widget gives us a temporary unique child ID to associate
606 // with this view so that clients can call get_accChild in
607 // NativeViewAccessibilityWin to retrieve the IAccessible associated
608 // with this view.
609 ::NotifyWinEvent(NativeViewAccessibilityWin::MSAAEvent(event_type), hwnd(),
610 OBJID_CLIENT, id);
611 }
612
613 void HWNDMessageHandler::SetCursor(HCURSOR cursor) {
614 if (cursor) {
615 previous_cursor_ = ::SetCursor(cursor);
616 } else if (previous_cursor_) {
617 ::SetCursor(previous_cursor_);
618 previous_cursor_ = NULL;
619 }
620 }
621
622 void HWNDMessageHandler::FrameTypeChanged() {
623 // Called when the frame type could possibly be changing (theme change or
624 // DWM composition change).
625 if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
626 // We need to toggle the rendering policy of the DWM/glass frame as we
627 // change from opaque to glass. "Non client rendering enabled" means that
628 // the DWM's glass non-client rendering is enabled, which is why
629 // DWMNCRP_ENABLED is used for the native frame case. _DISABLED means the
630 // DWM doesn't render glass, and so is used in the custom frame case.
631 DWMNCRENDERINGPOLICY policy = !delegate_->IsUsingCustomFrame() ?
632 DWMNCRP_ENABLED : DWMNCRP_DISABLED;
633 DwmSetWindowAttribute(hwnd(), DWMWA_NCRENDERING_POLICY,
634 &policy, sizeof(DWMNCRENDERINGPOLICY));
635 }
636
637 // Send a frame change notification, since the non-client metrics have
638 // changed.
639 SendFrameChanged();
640
641 // Update the non-client view with the correct frame view for the active frame
642 // type.
643 delegate_->UpdateFrame();
644
645 // WM_DWMCOMPOSITIONCHANGED is only sent to top level windows, however we want
646 // to notify our children too, since we can have MDI child windows who need to
647 // update their appearance.
648 EnumChildWindows(hwnd(), &SendDwmCompositionChanged, NULL);
649 }
650
651 void HWNDMessageHandler::SchedulePaintInRect(const gfx::Rect& rect) {
652 if (use_layered_buffer_) {
653 // We must update the back-buffer immediately, since Windows' handling of
654 // invalid rects is somewhat mysterious.
655 invalid_rect_ = invalid_rect_.Union(rect);
656
657 // In some situations, such as drag and drop, when Windows itself runs a
658 // nested message loop our message loop appears to be starved and we don't
659 // receive calls to DidProcessMessage(). This only seems to affect layered
660 // windows, so we schedule a redraw manually using a task, since those never
661 // seem to be starved. Also, wtf.
662 if (!paint_layered_window_factory_.HasWeakPtrs()) {
663 MessageLoop::current()->PostTask(
664 FROM_HERE,
665 base::Bind(&HWNDMessageHandler::RedrawLayeredWindowContents,
666 paint_layered_window_factory_.GetWeakPtr()));
667 }
668 } else {
669 // InvalidateRect() expects client coordinates.
670 RECT r = rect.ToRECT();
671 InvalidateRect(hwnd(), &r, FALSE);
672 }
673 }
674
675 void HWNDMessageHandler::SetOpacity(BYTE opacity) {
676 layered_alpha_ = opacity;
677 }
678
423 void HWNDMessageHandler::OnActivate(UINT action, BOOL minimized, HWND window) { 679 void HWNDMessageHandler::OnActivate(UINT action, BOOL minimized, HWND window) {
424 SetMsgHandled(FALSE); 680 SetMsgHandled(FALSE);
425 } 681 }
426 682
427 void HWNDMessageHandler::OnActivateApp(BOOL active, DWORD thread_id) { 683 void HWNDMessageHandler::OnActivateApp(BOOL active, DWORD thread_id) {
428 if (delegate_->IsWidgetWindow() && !active && 684 if (delegate_->IsWidgetWindow() && !active &&
429 thread_id != GetCurrentThreadId()) { 685 thread_id != GetCurrentThreadId()) {
430 delegate_->HandleAppDeactivated(); 686 delegate_->HandleAppDeactivated();
431 // Also update the native frame if it is rendering the non-client area. 687 // Also update the native frame if it is rendering the non-client area.
432 if (!remove_standard_frame_ && !delegate_->IsUsingCustomFrame()) 688 if (!remove_standard_frame_ && !delegate_->IsUsingCustomFrame())
(...skipping 28 matching lines...) Expand all
461 void HWNDMessageHandler::OnCommand(UINT notification_code, 717 void HWNDMessageHandler::OnCommand(UINT notification_code,
462 int command, 718 int command,
463 HWND window) { 719 HWND window) {
464 // If the notification code is > 1 it means it is control specific and we 720 // If the notification code is > 1 it means it is control specific and we
465 // should ignore it. 721 // should ignore it.
466 if (notification_code > 1 || delegate_->HandleAppCommand(command)) 722 if (notification_code > 1 || delegate_->HandleAppCommand(command))
467 SetMsgHandled(FALSE); 723 SetMsgHandled(FALSE);
468 } 724 }
469 725
470 LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) { 726 LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) {
727 use_layered_buffer_ = !!(delegate_->AsNativeWidgetWin()->
728 window_ex_style() & WS_EX_LAYERED);
729
471 // Attempt to detect screen readers by sending an event with our custom id. 730 // Attempt to detect screen readers by sending an event with our custom id.
472 NotifyWinEvent(EVENT_SYSTEM_ALERT, hwnd(), kCustomObjectID, CHILDID_SELF); 731 NotifyWinEvent(EVENT_SYSTEM_ALERT, hwnd(), kCustomObjectID, CHILDID_SELF);
473 732
474 // This message initializes the window so that focus border are shown for 733 // This message initializes the window so that focus border are shown for
475 // windows. 734 // windows.
476 SendMessage(hwnd(), 735 SendMessage(hwnd(),
477 WM_CHANGEUISTATE, 736 WM_CHANGEUISTATE,
478 MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 737 MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS),
479 0); 738 0);
480 739
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 } 880 }
622 881
623 InputMethodWin* ime_win = static_cast<InputMethodWin*>(input_method); 882 InputMethodWin* ime_win = static_cast<InputMethodWin*>(input_method);
624 BOOL handled = FALSE; 883 BOOL handled = FALSE;
625 LRESULT result = ime_win->OnImeMessages(message, w_param, l_param, &handled); 884 LRESULT result = ime_win->OnImeMessages(message, w_param, l_param, &handled);
626 SetMsgHandled(handled); 885 SetMsgHandled(handled);
627 return result; 886 return result;
628 } 887 }
629 888
630 void HWNDMessageHandler::OnInitMenu(HMENU menu) { 889 void HWNDMessageHandler::OnInitMenu(HMENU menu) {
631 bool is_fullscreen = delegate_->AsNativeWidgetWin()->IsFullscreen(); 890 bool is_fullscreen = fullscreen_handler_->fullscreen();
632 bool is_minimized = IsMinimized(); 891 bool is_minimized = IsMinimized();
633 bool is_maximized = IsMaximized(); 892 bool is_maximized = IsMaximized();
634 bool is_restored = !is_fullscreen && !is_minimized && !is_maximized; 893 bool is_restored = !is_fullscreen && !is_minimized && !is_maximized;
635 894
636 ScopedRedrawLock lock(this); 895 ScopedRedrawLock lock(this);
637 EnableMenuItemByCommand(menu, SC_RESTORE, is_minimized || is_maximized); 896 EnableMenuItemByCommand(menu, SC_RESTORE, is_minimized || is_maximized);
638 EnableMenuItemByCommand(menu, SC_MOVE, is_restored); 897 EnableMenuItemByCommand(menu, SC_MOVE, is_restored);
639 EnableMenuItemByCommand(menu, SC_SIZE, delegate_->CanResize() && is_restored); 898 EnableMenuItemByCommand(menu, SC_SIZE, delegate_->CanResize() && is_restored);
640 EnableMenuItemByCommand(menu, SC_MAXIMIZE, delegate_->CanMaximize() && 899 EnableMenuItemByCommand(menu, SC_MAXIMIZE, delegate_->CanMaximize() &&
641 !is_fullscreen && !is_maximized); 900 !is_fullscreen && !is_maximized);
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 int component = delegate_->GetNonClientComponent(gfx::Point(temp)); 1200 int component = delegate_->GetNonClientComponent(gfx::Point(temp));
942 if (component != HTNOWHERE) 1201 if (component != HTNOWHERE)
943 return component; 1202 return component;
944 1203
945 // Otherwise, we let Windows do all the native frame non-client handling for 1204 // Otherwise, we let Windows do all the native frame non-client handling for
946 // us. 1205 // us.
947 SetMsgHandled(FALSE); 1206 SetMsgHandled(FALSE);
948 return 0; 1207 return 0;
949 } 1208 }
950 1209
1210 void HWNDMessageHandler::OnNCPaint(HRGN rgn) {
1211 // We only do non-client painting if we're not using the native frame.
1212 // It's required to avoid some native painting artifacts from appearing when
1213 // the window is resized.
1214 if (!delegate_->IsWidgetWindow() || !delegate_->IsUsingCustomFrame()) {
1215 SetMsgHandled(FALSE);
1216 return;
1217 }
1218
1219 // We have an NC region and need to paint it. We expand the NC region to
1220 // include the dirty region of the root view. This is done to minimize
1221 // paints.
1222 CRect window_rect;
1223 GetWindowRect(hwnd(), &window_rect);
1224
1225 gfx::Size root_view_size = delegate_->GetRootViewSize();
1226 if (gfx::Size(window_rect.Width(), window_rect.Height()) != root_view_size) {
1227 // If the size of the window differs from the size of the root view it
1228 // means we're being asked to paint before we've gotten a WM_SIZE. This can
1229 // happen when the user is interactively resizing the window. To avoid
1230 // mass flickering we don't do anything here. Once we get the WM_SIZE we'll
1231 // reset the region of the window which triggers another WM_NCPAINT and
1232 // all is well.
1233 return;
1234 }
1235
1236 CRect dirty_region;
1237 // A value of 1 indicates paint all.
1238 if (!rgn || rgn == reinterpret_cast<HRGN>(1)) {
1239 dirty_region = CRect(0, 0, window_rect.Width(), window_rect.Height());
1240 } else {
1241 RECT rgn_bounding_box;
1242 GetRgnBox(rgn, &rgn_bounding_box);
1243 if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect))
1244 return; // Dirty region doesn't intersect window bounds, bale.
1245
1246 // rgn_bounding_box is in screen coordinates. Map it to window coordinates.
1247 OffsetRect(&dirty_region, -window_rect.left, -window_rect.top);
1248 }
1249
1250 // In theory GetDCEx should do what we want, but I couldn't get it to work.
1251 // In particular the docs mentiond DCX_CLIPCHILDREN, but as far as I can tell
1252 // it doesn't work at all. So, instead we get the DC for the window then
1253 // manually clip out the children.
1254 HDC dc = GetWindowDC(hwnd());
1255 ClipState clip_state;
1256 clip_state.x = window_rect.left;
1257 clip_state.y = window_rect.top;
1258 clip_state.parent = hwnd();
1259 clip_state.dc = dc;
1260 EnumChildWindows(hwnd(), &ClipDCToChild,
1261 reinterpret_cast<LPARAM>(&clip_state));
1262
1263 gfx::Rect old_paint_region = invalid_rect_;
1264 if (!old_paint_region.IsEmpty()) {
1265 // The root view has a region that needs to be painted. Include it in the
1266 // region we're going to paint.
1267
1268 CRect old_paint_region_crect = old_paint_region.ToRECT();
1269 CRect tmp = dirty_region;
1270 UnionRect(&dirty_region, &tmp, &old_paint_region_crect);
1271 }
1272
1273 SchedulePaintInRect(gfx::Rect(dirty_region));
1274
1275 // gfx::CanvasSkiaPaint's destructor does the actual painting. As such, wrap
1276 // the following in a block to force paint to occur so that we can release
1277 // the dc.
1278 {
1279 gfx::CanvasSkiaPaint canvas(dc, true, dirty_region.left,
1280 dirty_region.top, dirty_region.Width(),
1281 dirty_region.Height());
1282 delegate_->HandlePaint(&canvas);
1283 }
1284
1285 ReleaseDC(hwnd(), dc);
1286 // When using a custom frame, we want to avoid calling DefWindowProc() since
1287 // that may render artifacts.
1288 SetMsgHandled(delegate_->IsUsingCustomFrame());
1289 }
1290
951 LRESULT HWNDMessageHandler::OnNCUAHDrawCaption(UINT message, 1291 LRESULT HWNDMessageHandler::OnNCUAHDrawCaption(UINT message,
952 WPARAM w_param, 1292 WPARAM w_param,
953 LPARAM l_param) { 1293 LPARAM l_param) {
954 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for 1294 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for
955 // an explanation about why we need to handle this message. 1295 // an explanation about why we need to handle this message.
956 SetMsgHandled(delegate_->IsUsingCustomFrame()); 1296 SetMsgHandled(delegate_->IsUsingCustomFrame());
957 return 0; 1297 return 0;
958 } 1298 }
959 1299
960 LRESULT HWNDMessageHandler::OnNCUAHDrawFrame(UINT message, 1300 LRESULT HWNDMessageHandler::OnNCUAHDrawFrame(UINT message,
961 WPARAM w_param, 1301 WPARAM w_param,
962 LPARAM l_param) { 1302 LPARAM l_param) {
963 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for 1303 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for
964 // an explanation about why we need to handle this message. 1304 // an explanation about why we need to handle this message.
965 SetMsgHandled(delegate_->IsUsingCustomFrame()); 1305 SetMsgHandled(delegate_->IsUsingCustomFrame());
966 return 0; 1306 return 0;
967 } 1307 }
968 1308
969 LRESULT HWNDMessageHandler::OnNotify(int w_param, NMHDR* l_param) { 1309 LRESULT HWNDMessageHandler::OnNotify(int w_param, NMHDR* l_param) {
970 LRESULT l_result = 0; 1310 LRESULT l_result = 0;
971 SetMsgHandled(delegate_->HandleTooltipNotify(w_param, l_param, &l_result)); 1311 SetMsgHandled(delegate_->HandleTooltipNotify(w_param, l_param, &l_result));
972 return l_result; 1312 return l_result;
973 } 1313 }
974 1314
1315 void HWNDMessageHandler::OnPaint(HDC dc) {
1316 RECT dirty_rect;
1317 // Try to paint accelerated first.
1318 if (GetUpdateRect(hwnd(), &dirty_rect, FALSE) &&
1319 !IsRectEmpty(&dirty_rect)) {
1320 if (delegate_->HandlePaintAccelerated(gfx::Rect(dirty_rect))) {
1321 ValidateRect(hwnd(), NULL);
1322 } else {
1323 scoped_ptr<gfx::CanvasPaint> canvas(
1324 gfx::CanvasPaint::CreateCanvasPaint(hwnd()));
1325 delegate_->HandlePaint(canvas->AsCanvas());
1326 }
1327 } else {
1328 // TODO(msw): Find a better solution for this crbug.com/93530 workaround.
1329 // Some scenarios otherwise fail to validate minimized app/popup windows.
1330 ValidateRect(hwnd(), NULL);
1331 }
1332 }
1333
975 LRESULT HWNDMessageHandler::OnPowerBroadcast(DWORD power_event, DWORD data) { 1334 LRESULT HWNDMessageHandler::OnPowerBroadcast(DWORD power_event, DWORD data) {
976 base::SystemMonitor* monitor = base::SystemMonitor::Get(); 1335 base::SystemMonitor* monitor = base::SystemMonitor::Get();
977 if (monitor) 1336 if (monitor)
978 monitor->ProcessWmPowerBroadcastMessage(power_event); 1337 monitor->ProcessWmPowerBroadcastMessage(power_event);
979 SetMsgHandled(FALSE); 1338 SetMsgHandled(FALSE);
980 return 0; 1339 return 0;
981 } 1340 }
982 1341
983 LRESULT HWNDMessageHandler::OnReflectedMessage(UINT message, 1342 LRESULT HWNDMessageHandler::OnReflectedMessage(UINT message,
984 WPARAM w_param, 1343 WPARAM w_param,
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 if (current_rgn_result == ERROR || !EqualRgn(current_rgn, new_region)) { 1619 if (current_rgn_result == ERROR || !EqualRgn(current_rgn, new_region)) {
1261 // SetWindowRgn takes ownership of the HRGN created by CreateNativeRegion. 1620 // SetWindowRgn takes ownership of the HRGN created by CreateNativeRegion.
1262 SetWindowRgn(hwnd(), new_region, TRUE); 1621 SetWindowRgn(hwnd(), new_region, TRUE);
1263 } else { 1622 } else {
1264 DeleteObject(new_region); 1623 DeleteObject(new_region);
1265 } 1624 }
1266 1625
1267 DeleteObject(current_rgn); 1626 DeleteObject(current_rgn);
1268 } 1627 }
1269 1628
1629 HWND HWNDMessageHandler::hwnd() {
1630 return delegate_->AsNativeWidgetWin()->hwnd();
1631 }
1632
1633 HWND HWNDMessageHandler::hwnd() const {
1634 return delegate_->AsNativeWidgetWin()->hwnd();
1635 }
1636
1270 //////////////////////////////////////////////////////////////////////////////// 1637 ////////////////////////////////////////////////////////////////////////////////
1271 // HWNDMessageHandler, InputMethodDelegate implementation: 1638 // HWNDMessageHandler, InputMethodDelegate implementation:
1272 1639
1273 void HWNDMessageHandler::DispatchKeyEventPostIME(const ui::KeyEvent& key) { 1640 void HWNDMessageHandler::DispatchKeyEventPostIME(const ui::KeyEvent& key) {
1274 SetMsgHandled(delegate_->HandleKeyEvent(key)); 1641 SetMsgHandled(delegate_->HandleKeyEvent(key));
1275 } 1642 }
1276 1643
1277 //////////////////////////////////////////////////////////////////////////////// 1644 ////////////////////////////////////////////////////////////////////////////////
1278 // HWNDMessageHandler, private: 1645 // HWNDMessageHandler, private:
1279 1646
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 // TODO(beng): investigate whether this could be done 1679 // TODO(beng): investigate whether this could be done
1313 // from other branch of if-else. 1680 // from other branch of if-else.
1314 if (!IsMinimized()) 1681 if (!IsMinimized())
1315 GetClientRect(hwnd(), &r); 1682 GetClientRect(hwnd(), &r);
1316 } else { 1683 } else {
1317 GetWindowRect(hwnd(), &r); 1684 GetWindowRect(hwnd(), &r);
1318 } 1685 }
1319 gfx::Size s(std::max(0, static_cast<int>(r.right - r.left)), 1686 gfx::Size s(std::max(0, static_cast<int>(r.right - r.left)),
1320 std::max(0, static_cast<int>(r.bottom - r.top))); 1687 std::max(0, static_cast<int>(r.bottom - r.top)));
1321 delegate_->HandleClientSizeChanged(s); 1688 delegate_->HandleClientSizeChanged(s);
1689 if (use_layered_buffer_) {
1690 layered_window_contents_.reset(
1691 new gfx::Canvas(s, ui::SCALE_FACTOR_100P, false));
1692 }
1322 } 1693 }
1323 1694
1324 gfx::Insets HWNDMessageHandler::GetClientAreaInsets() const { 1695 gfx::Insets HWNDMessageHandler::GetClientAreaInsets() const {
1325 gfx::Insets insets; 1696 gfx::Insets insets;
1326 if (delegate_->GetClientAreaInsets(&insets)) 1697 if (delegate_->GetClientAreaInsets(&insets))
1327 return insets; 1698 return insets;
1328 DCHECK(insets.empty()); 1699 DCHECK(insets.empty());
1329 1700
1330 // Returning an empty Insets object causes the default handling in 1701 // Returning an empty Insets object causes the default handling in
1331 // NativeWidgetWin::OnNCCalcSize() to be invoked. 1702 // NativeWidgetWin::OnNCCalcSize() to be invoked.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1399 } 1770 }
1400 1771
1401 void HWNDMessageHandler::UnlockUpdates(bool force) { 1772 void HWNDMessageHandler::UnlockUpdates(bool force) {
1402 if ((force || !ui::win::IsAeroGlassEnabled()) && --lock_updates_count_ <= 0) { 1773 if ((force || !ui::win::IsAeroGlassEnabled()) && --lock_updates_count_ <= 0) {
1403 SetWindowLong(hwnd(), GWL_STYLE, 1774 SetWindowLong(hwnd(), GWL_STYLE,
1404 GetWindowLong(hwnd(), GWL_STYLE) | WS_VISIBLE); 1775 GetWindowLong(hwnd(), GWL_STYLE) | WS_VISIBLE);
1405 lock_updates_count_ = 0; 1776 lock_updates_count_ = 0;
1406 } 1777 }
1407 } 1778 }
1408 1779
1409 HWND HWNDMessageHandler::hwnd() { 1780 void HWNDMessageHandler::RedrawInvalidRect() {
1410 return delegate_->AsNativeWidgetWin()->hwnd(); 1781 if (!use_layered_buffer_) {
1782 RECT r = { 0, 0, 0, 0 };
1783 if (GetUpdateRect(hwnd(), &r, FALSE) && !IsRectEmpty(&r)) {
1784 RedrawWindow(hwnd(), &r, NULL,
1785 RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN);
1786 }
1787 }
1411 } 1788 }
1412 1789
1413 HWND HWNDMessageHandler::hwnd() const { 1790 void HWNDMessageHandler::RedrawLayeredWindowContents() {
1414 return delegate_->AsNativeWidgetWin()->hwnd(); 1791 if (invalid_rect_.IsEmpty())
1792 return;
1793
1794 // We need to clip to the dirty rect ourselves.
1795 layered_window_contents_->sk_canvas()->save(SkCanvas::kClip_SaveFlag);
1796 layered_window_contents_->ClipRect(invalid_rect_);
1797 delegate_->PaintLayeredWindow(layered_window_contents_.get());
1798 layered_window_contents_->sk_canvas()->restore();
1799
1800 RECT wr;
1801 GetWindowRect(hwnd(), &wr);
1802 SIZE size = {wr.right - wr.left, wr.bottom - wr.top};
1803 POINT position = {wr.left, wr.top};
1804 HDC dib_dc = skia::BeginPlatformPaint(layered_window_contents_->sk_canvas());
1805 POINT zero = {0, 0};
1806 BLENDFUNCTION blend = {AC_SRC_OVER, 0, layered_alpha_, AC_SRC_ALPHA};
1807 UpdateLayeredWindow(hwnd(), NULL, &position, &size, dib_dc, &zero,
1808 RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA);
1809 invalid_rect_.SetRect(0, 0, 0, 0);
1810 skia::EndPlatformPaint(layered_window_contents_->sk_canvas());
1415 } 1811 }
1416 1812
1417 void HWNDMessageHandler::SetMsgHandled(BOOL handled) { 1813 void HWNDMessageHandler::SetMsgHandled(BOOL handled) {
1418 delegate_->AsNativeWidgetWin()->SetMsgHandled(handled); 1814 delegate_->AsNativeWidgetWin()->SetMsgHandled(handled);
1419 } 1815 }
1420 1816
1421 } // namespace views 1817 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/win/hwnd_message_handler.h ('k') | ui/views/win/hwnd_message_handler_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698