OLD | NEW |
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/base/event.h" | 13 #include "ui/base/event.h" |
14 #include "ui/base/keycodes/keyboard_code_conversion_win.h" | 14 #include "ui/base/keycodes/keyboard_code_conversion_win.h" |
15 #include "ui/base/native_theme/native_theme_win.h" | 15 #include "ui/base/native_theme/native_theme_win.h" |
16 #include "ui/base/win/hwnd_util.h" | 16 #include "ui/base/win/hwnd_util.h" |
17 #include "ui/base/win/mouse_wheel_util.h" | 17 #include "ui/base/win/mouse_wheel_util.h" |
18 #include "ui/base/win/shell.h" | 18 #include "ui/base/win/shell.h" |
19 #include "ui/gfx/canvas.h" | 19 #include "ui/gfx/canvas.h" |
20 #include "ui/gfx/canvas_paint.h" | 20 #include "ui/gfx/canvas_paint.h" |
21 #include "ui/gfx/canvas_skia_paint.h" | 21 #include "ui/gfx/canvas_skia_paint.h" |
| 22 #include "ui/gfx/icon_util.h" |
22 #include "ui/gfx/insets.h" | 23 #include "ui/gfx/insets.h" |
23 #include "ui/gfx/path.h" | 24 #include "ui/gfx/path.h" |
24 #include "ui/gfx/screen.h" | 25 #include "ui/gfx/screen.h" |
25 #include "ui/views/accessibility/native_view_accessibility_win.h" | 26 #include "ui/views/accessibility/native_view_accessibility_win.h" |
26 #include "ui/views/ime/input_method_win.h" | 27 #include "ui/views/ime/input_method_win.h" |
| 28 #include "ui/views/views_delegate.h" |
| 29 #include "ui/views/widget/child_window_message_processor.h" |
27 #include "ui/views/widget/monitor_win.h" | 30 #include "ui/views/widget/monitor_win.h" |
28 #include "ui/views/widget/native_widget_win.h" | 31 #include "ui/views/widget/native_widget_win.h" |
29 #include "ui/views/widget/widget_hwnd_utils.h" | 32 #include "ui/views/widget/widget_hwnd_utils.h" |
30 #include "ui/views/win/fullscreen_handler.h" | 33 #include "ui/views/win/fullscreen_handler.h" |
31 #include "ui/views/win/hwnd_message_handler_delegate.h" | 34 #include "ui/views/win/hwnd_message_handler_delegate.h" |
32 #include "ui/views/win/scoped_fullscreen_visibility.h" | 35 #include "ui/views/win/scoped_fullscreen_visibility.h" |
33 | 36 |
34 #if !defined(USE_AURA) | 37 #if !defined(USE_AURA) |
35 #include "base/command_line.h" | 38 #include "base/command_line.h" |
36 #include "ui/base/ui_base_switches.h" | 39 #include "ui/base/ui_base_switches.h" |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 GetWindowRect(window, &bounds); | 232 GetWindowRect(window, &bounds); |
230 ExcludeClipRect(clip_state->dc, | 233 ExcludeClipRect(clip_state->dc, |
231 bounds.left - clip_state->x, | 234 bounds.left - clip_state->x, |
232 bounds.top - clip_state->y, | 235 bounds.top - clip_state->y, |
233 bounds.right - clip_state->x, | 236 bounds.right - clip_state->x, |
234 bounds.bottom - clip_state->y); | 237 bounds.bottom - clip_state->y); |
235 } | 238 } |
236 return TRUE; | 239 return TRUE; |
237 } | 240 } |
238 | 241 |
| 242 // Get the source HWND of the specified message. Depending on the message, the |
| 243 // source HWND is encoded in either the WPARAM or the LPARAM value. |
| 244 HWND GetControlHWNDForMessage(UINT message, WPARAM w_param, LPARAM l_param) { |
| 245 // Each of the following messages can be sent by a child HWND and must be |
| 246 // forwarded to its associated NativeControlWin for handling. |
| 247 switch (message) { |
| 248 case WM_NOTIFY: |
| 249 return reinterpret_cast<NMHDR*>(l_param)->hwndFrom; |
| 250 case WM_COMMAND: |
| 251 return reinterpret_cast<HWND>(l_param); |
| 252 case WM_CONTEXTMENU: |
| 253 return reinterpret_cast<HWND>(w_param); |
| 254 case WM_CTLCOLORBTN: |
| 255 case WM_CTLCOLORSTATIC: |
| 256 return reinterpret_cast<HWND>(l_param); |
| 257 } |
| 258 return NULL; |
| 259 } |
| 260 |
| 261 // Some messages may be sent to us by a child HWND. If this is the case, this |
| 262 // function will forward those messages on to the object associated with the |
| 263 // source HWND and return true, in which case the window procedure must not do |
| 264 // any further processing of the message. If there is no associated |
| 265 // ChildWindowMessageProcessor, the return value will be false and the WndProc |
| 266 // can continue processing the message normally. |l_result| contains the result |
| 267 // of the message processing by the control and must be returned by the WndProc |
| 268 // if the return value is true. |
| 269 bool ProcessChildWindowMessage(UINT message, |
| 270 WPARAM w_param, |
| 271 LPARAM l_param, |
| 272 LRESULT* l_result) { |
| 273 *l_result = 0; |
| 274 |
| 275 HWND control_hwnd = GetControlHWNDForMessage(message, w_param, l_param); |
| 276 if (IsWindow(control_hwnd)) { |
| 277 ChildWindowMessageProcessor* processor = |
| 278 ChildWindowMessageProcessor::Get(control_hwnd); |
| 279 if (processor) |
| 280 return processor->ProcessMessage(message, w_param, l_param, l_result); |
| 281 } |
| 282 |
| 283 return false; |
| 284 } |
| 285 |
239 // A custom MSAA object id used to determine if a screen reader is actively | 286 // A custom MSAA object id used to determine if a screen reader is actively |
240 // listening for MSAA events. | 287 // listening for MSAA events. |
241 const int kCustomObjectID = 1; | 288 const int kCustomObjectID = 1; |
242 | 289 |
243 // The thickness of an auto-hide taskbar in pixels. | 290 // The thickness of an auto-hide taskbar in pixels. |
244 const int kAutoHideTaskbarThicknessPx = 2; | 291 const int kAutoHideTaskbarThicknessPx = 2; |
245 | 292 |
246 } // namespace | 293 } // namespace |
247 | 294 |
248 // A scoping class that prevents a window from being able to redraw in response | 295 // A scoping class that prevents a window from being able to redraw in response |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock); | 356 DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock); |
310 }; | 357 }; |
311 | 358 |
312 //////////////////////////////////////////////////////////////////////////////// | 359 //////////////////////////////////////////////////////////////////////////////// |
313 // HWNDMessageHandler, public: | 360 // HWNDMessageHandler, public: |
314 | 361 |
315 HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate) | 362 HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate) |
316 : delegate_(delegate), | 363 : delegate_(delegate), |
317 ALLOW_THIS_IN_INITIALIZER_LIST(fullscreen_handler_(new FullscreenHandler( | 364 ALLOW_THIS_IN_INITIALIZER_LIST(fullscreen_handler_(new FullscreenHandler( |
318 delegate->AsNativeWidgetWin()->GetWidget()))), | 365 delegate->AsNativeWidgetWin()->GetWidget()))), |
| 366 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), |
319 remove_standard_frame_(false), | 367 remove_standard_frame_(false), |
| 368 restore_focus_when_enabled_(false), |
| 369 restored_enabled_(false), |
320 previous_cursor_(NULL), | 370 previous_cursor_(NULL), |
321 active_mouse_tracking_flags_(0), | 371 active_mouse_tracking_flags_(0), |
322 is_right_mouse_pressed_on_caption_(false), | 372 is_right_mouse_pressed_on_caption_(false), |
323 lock_updates_count_(0), | 373 lock_updates_count_(0), |
324 destroyed_(NULL), | 374 destroyed_(NULL), |
325 ignore_window_pos_changes_(false), | 375 ignore_window_pos_changes_(false), |
326 ALLOW_THIS_IN_INITIALIZER_LIST(ignore_pos_changes_factory_(this)), | 376 ALLOW_THIS_IN_INITIALIZER_LIST(ignore_pos_changes_factory_(this)), |
327 last_monitor_(NULL), | 377 last_monitor_(NULL), |
328 use_layered_buffer_(false), | 378 use_layered_buffer_(false), |
329 layered_alpha_(255), | 379 layered_alpha_(255), |
(...skipping 17 matching lines...) Expand all Loading... |
347 // We implement modality by crawling up the hierarchy of windows starting | 397 // We implement modality by crawling up the hierarchy of windows starting |
348 // at the owner, disabling all of them so that they don't receive input | 398 // at the owner, disabling all of them so that they don't receive input |
349 // messages. | 399 // messages. |
350 HWND start = ::GetWindow(hwnd(), GW_OWNER); | 400 HWND start = ::GetWindow(hwnd(), GW_OWNER); |
351 while (start) { | 401 while (start) { |
352 ::EnableWindow(start, FALSE); | 402 ::EnableWindow(start, FALSE); |
353 start = ::GetParent(start); | 403 start = ::GetParent(start); |
354 } | 404 } |
355 } | 405 } |
356 | 406 |
| 407 void HWNDMessageHandler::Close() { |
| 408 if (!IsWindow(hwnd())) |
| 409 return; // No need to do anything. |
| 410 |
| 411 // Let's hide ourselves right away. |
| 412 Hide(); |
| 413 |
| 414 // Modal dialog windows disable their owner windows; re-enable them now so |
| 415 // they can activate as foreground windows upon this window's destruction. |
| 416 RestoreEnabledIfNecessary(); |
| 417 |
| 418 if (!close_widget_factory_.HasWeakPtrs()) { |
| 419 // And we delay the close so that if we are called from an ATL callback, |
| 420 // we don't destroy the window before the callback returned (as the caller |
| 421 // may delete ourselves on destroy and the ATL callback would still |
| 422 // dereference us when the callback returns). |
| 423 MessageLoop::current()->PostTask( |
| 424 FROM_HERE, |
| 425 base::Bind(&HWNDMessageHandler::CloseNow, |
| 426 close_widget_factory_.GetWeakPtr())); |
| 427 } |
| 428 } |
| 429 |
357 void HWNDMessageHandler::CloseNow() { | 430 void HWNDMessageHandler::CloseNow() { |
358 // We may already have been destroyed if the selection resulted in a tab | 431 // We may already have been destroyed if the selection resulted in a tab |
359 // switch which will have reactivated the browser window and closed us, so | 432 // switch which will have reactivated the browser window and closed us, so |
360 // we need to check to see if we're still a window before trying to destroy | 433 // we need to check to see if we're still a window before trying to destroy |
361 // ourself. | 434 // ourself. |
362 if (IsWindow(hwnd())) | 435 if (IsWindow(hwnd())) |
363 DestroyWindow(hwnd()); | 436 DestroyWindow(hwnd()); |
364 } | 437 } |
365 | 438 |
366 gfx::Rect HWNDMessageHandler::GetWindowBoundsInScreen() const { | 439 gfx::Rect HWNDMessageHandler::GetWindowBoundsInScreen() const { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 void HWNDMessageHandler::StackAbove(HWND other_hwnd) { | 523 void HWNDMessageHandler::StackAbove(HWND other_hwnd) { |
451 SetWindowPos(hwnd(), other_hwnd, 0, 0, 0, 0, | 524 SetWindowPos(hwnd(), other_hwnd, 0, 0, 0, 0, |
452 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); | 525 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); |
453 } | 526 } |
454 | 527 |
455 void HWNDMessageHandler::StackAtTop() { | 528 void HWNDMessageHandler::StackAtTop() { |
456 SetWindowPos(hwnd(), HWND_TOP, 0, 0, 0, 0, | 529 SetWindowPos(hwnd(), HWND_TOP, 0, 0, 0, 0, |
457 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); | 530 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); |
458 } | 531 } |
459 | 532 |
| 533 void HWNDMessageHandler::Show() { |
| 534 // TODO(beng): Seems like this could just be rewritten as |
| 535 // ShowWindowWithState(SW_SHOWNOACTIVATE). |
| 536 if (!IsWindow(hwnd())) |
| 537 return; |
| 538 |
| 539 ShowWindow(hwnd(), SW_SHOWNOACTIVATE); |
| 540 SetInitialFocus(); |
| 541 } |
| 542 |
| 543 void HWNDMessageHandler::ShowWindowWithState(ui::WindowShowState show_state) { |
| 544 DWORD native_show_state; |
| 545 switch (show_state) { |
| 546 case ui::SHOW_STATE_INACTIVE: |
| 547 native_show_state = SW_SHOWNOACTIVATE; |
| 548 break; |
| 549 case ui::SHOW_STATE_MAXIMIZED: |
| 550 native_show_state = SW_SHOWMAXIMIZED; |
| 551 break; |
| 552 case ui::SHOW_STATE_MINIMIZED: |
| 553 native_show_state = SW_SHOWMINIMIZED; |
| 554 break; |
| 555 default: |
| 556 native_show_state = delegate_->GetInitialShowState(); |
| 557 break; |
| 558 } |
| 559 Show(native_show_state); |
| 560 } |
| 561 |
| 562 void HWNDMessageHandler::Show(int show_state) { |
| 563 ShowWindow(hwnd(), show_state); |
| 564 // When launched from certain programs like bash and Windows Live Messenger, |
| 565 // show_state is set to SW_HIDE, so we need to correct that condition. We |
| 566 // don't just change show_state to SW_SHOWNORMAL because MSDN says we must |
| 567 // always first call ShowWindow with the specified value from STARTUPINFO, |
| 568 // otherwise all future ShowWindow calls will be ignored (!!#@@#!). Instead, |
| 569 // we call ShowWindow again in this case. |
| 570 if (show_state == SW_HIDE) { |
| 571 show_state = SW_SHOWNORMAL; |
| 572 ShowWindow(hwnd(), show_state); |
| 573 } |
| 574 |
| 575 // We need to explicitly activate the window if we've been shown with a state |
| 576 // that should activate, because if we're opened from a desktop shortcut while |
| 577 // an existing window is already running it doesn't seem to be enough to use |
| 578 // one of these flags to activate the window. |
| 579 if (show_state == SW_SHOWNORMAL || show_state == SW_SHOWMAXIMIZED) |
| 580 Activate(); |
| 581 |
| 582 if (!delegate_->HandleInitialFocus()) |
| 583 SetInitialFocus(); |
| 584 } |
| 585 |
460 void HWNDMessageHandler::ShowMaximizedWithBounds(const gfx::Rect& bounds) { | 586 void HWNDMessageHandler::ShowMaximizedWithBounds(const gfx::Rect& bounds) { |
461 WINDOWPLACEMENT placement = { 0 }; | 587 WINDOWPLACEMENT placement = { 0 }; |
462 placement.length = sizeof(WINDOWPLACEMENT); | 588 placement.length = sizeof(WINDOWPLACEMENT); |
463 placement.showCmd = SW_SHOWMAXIMIZED; | 589 placement.showCmd = SW_SHOWMAXIMIZED; |
464 placement.rcNormalPosition = bounds.ToRECT(); | 590 placement.rcNormalPosition = bounds.ToRECT(); |
465 SetWindowPlacement(hwnd(), &placement); | 591 SetWindowPlacement(hwnd(), &placement); |
466 } | 592 } |
467 | 593 |
468 void HWNDMessageHandler::Hide() { | 594 void HWNDMessageHandler::Hide() { |
469 if (IsWindow(hwnd())) { | 595 if (IsWindow(hwnd())) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 bool HWNDMessageHandler::RunMoveLoop(const gfx::Point& drag_offset) { | 656 bool HWNDMessageHandler::RunMoveLoop(const gfx::Point& drag_offset) { |
531 ReleaseCapture(); | 657 ReleaseCapture(); |
532 MoveLoopMouseWatcher watcher(this); | 658 MoveLoopMouseWatcher watcher(this); |
533 SendMessage(hwnd(), WM_SYSCOMMAND, SC_MOVE | 0x0002, GetMessagePos()); | 659 SendMessage(hwnd(), WM_SYSCOMMAND, SC_MOVE | 0x0002, GetMessagePos()); |
534 // Windows doesn't appear to offer a way to determine whether the user | 660 // 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 | 661 // canceled the move or not. We assume if the user released the mouse it was |
536 // successful. | 662 // successful. |
537 return watcher.got_mouse_up(); | 663 return watcher.got_mouse_up(); |
538 } | 664 } |
539 | 665 |
| 666 void HWNDMessageHandler::EndMoveLoop() { |
| 667 SendMessage(hwnd(), WM_CANCELMODE, 0, 0); |
| 668 } |
| 669 |
540 void HWNDMessageHandler::SendFrameChanged() { | 670 void HWNDMessageHandler::SendFrameChanged() { |
541 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, | 671 SetWindowPos(hwnd(), NULL, 0, 0, 0, 0, |
542 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | | 672 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | |
543 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | | 673 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | |
544 SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); | 674 SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); |
545 } | 675 } |
546 | 676 |
547 void HWNDMessageHandler::FlashFrame(bool flash) { | 677 void HWNDMessageHandler::FlashFrame(bool flash) { |
548 FLASHWINFO fwi; | 678 FLASHWINFO fwi; |
549 fwi.cbSize = sizeof(fwi); | 679 fwi.cbSize = sizeof(fwi); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 | 721 |
592 InputMethod* HWNDMessageHandler::CreateInputMethod() { | 722 InputMethod* HWNDMessageHandler::CreateInputMethod() { |
593 #if !defined(USE_AURA) | 723 #if !defined(USE_AURA) |
594 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 724 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
595 if (!command_line->HasSwitch(switches::kEnableViewsTextfield)) | 725 if (!command_line->HasSwitch(switches::kEnableViewsTextfield)) |
596 return NULL; | 726 return NULL; |
597 #endif | 727 #endif |
598 return new InputMethodWin(this); | 728 return new InputMethodWin(this); |
599 } | 729 } |
600 | 730 |
| 731 void HWNDMessageHandler::SetTitle(const string16& title) { |
| 732 SetWindowText(hwnd(), title.c_str()); |
| 733 SetAccessibleName(title); |
| 734 } |
| 735 |
| 736 void HWNDMessageHandler::SetAccessibleName(const string16& name) { |
| 737 base::win::ScopedComPtr<IAccPropServices> pAccPropServices; |
| 738 HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, |
| 739 IID_IAccPropServices, reinterpret_cast<void**>(&pAccPropServices)); |
| 740 if (SUCCEEDED(hr)) |
| 741 hr = pAccPropServices->SetHwndPropStr(hwnd(), OBJID_CLIENT, CHILDID_SELF, |
| 742 PROPID_ACC_NAME, name.c_str()); |
| 743 } |
| 744 |
| 745 void HWNDMessageHandler::SetAccessibleRole(ui::AccessibilityTypes::Role role) { |
| 746 base::win::ScopedComPtr<IAccPropServices> pAccPropServices; |
| 747 HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, |
| 748 IID_IAccPropServices, reinterpret_cast<void**>(&pAccPropServices)); |
| 749 if (SUCCEEDED(hr)) { |
| 750 VARIANT var; |
| 751 if (role) { |
| 752 var.vt = VT_I4; |
| 753 var.lVal = NativeViewAccessibilityWin::MSAARole(role); |
| 754 hr = pAccPropServices->SetHwndProp(hwnd(), OBJID_CLIENT, CHILDID_SELF, |
| 755 PROPID_ACC_ROLE, var); |
| 756 } |
| 757 } |
| 758 } |
| 759 |
| 760 void HWNDMessageHandler::SetAccessibleState( |
| 761 ui::AccessibilityTypes::State state) { |
| 762 base::win::ScopedComPtr<IAccPropServices> pAccPropServices; |
| 763 HRESULT hr = CoCreateInstance(CLSID_AccPropServices, NULL, CLSCTX_SERVER, |
| 764 IID_IAccPropServices, reinterpret_cast<void**>(&pAccPropServices)); |
| 765 if (SUCCEEDED(hr)) { |
| 766 VARIANT var; |
| 767 if (state) { |
| 768 var.vt = VT_I4; |
| 769 var.lVal = NativeViewAccessibilityWin::MSAAState(state); |
| 770 hr = pAccPropServices->SetHwndProp(hwnd(), OBJID_CLIENT, CHILDID_SELF, |
| 771 PROPID_ACC_STATE, var); |
| 772 } |
| 773 } |
| 774 } |
| 775 |
601 void HWNDMessageHandler::SendNativeAccessibilityEvent( | 776 void HWNDMessageHandler::SendNativeAccessibilityEvent( |
602 int id, | 777 int id, |
603 ui::AccessibilityTypes::Event event_type) { | 778 ui::AccessibilityTypes::Event event_type) { |
604 // Now call the Windows-specific method to notify MSAA clients of this | 779 // 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 | 780 // event. The widget gives us a temporary unique child ID to associate |
606 // with this view so that clients can call get_accChild in | 781 // with this view so that clients can call get_accChild in |
607 // NativeViewAccessibilityWin to retrieve the IAccessible associated | 782 // NativeViewAccessibilityWin to retrieve the IAccessible associated |
608 // with this view. | 783 // with this view. |
609 ::NotifyWinEvent(NativeViewAccessibilityWin::MSAAEvent(event_type), hwnd(), | 784 ::NotifyWinEvent(NativeViewAccessibilityWin::MSAAEvent(event_type), hwnd(), |
610 OBJID_CLIENT, id); | 785 OBJID_CLIENT, id); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 // InvalidateRect() expects client coordinates. | 844 // InvalidateRect() expects client coordinates. |
670 RECT r = rect.ToRECT(); | 845 RECT r = rect.ToRECT(); |
671 InvalidateRect(hwnd(), &r, FALSE); | 846 InvalidateRect(hwnd(), &r, FALSE); |
672 } | 847 } |
673 } | 848 } |
674 | 849 |
675 void HWNDMessageHandler::SetOpacity(BYTE opacity) { | 850 void HWNDMessageHandler::SetOpacity(BYTE opacity) { |
676 layered_alpha_ = opacity; | 851 layered_alpha_ = opacity; |
677 } | 852 } |
678 | 853 |
| 854 void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon, |
| 855 const gfx::ImageSkia& app_icon) { |
| 856 if (!window_icon.isNull()) { |
| 857 HICON windows_icon = IconUtil::CreateHICONFromSkBitmap(window_icon); |
| 858 // We need to make sure to destroy the previous icon, otherwise we'll leak |
| 859 // these GDI objects until we crash! |
| 860 HICON old_icon = reinterpret_cast<HICON>( |
| 861 SendMessage(hwnd(), WM_SETICON, ICON_SMALL, |
| 862 reinterpret_cast<LPARAM>(windows_icon))); |
| 863 if (old_icon) |
| 864 DestroyIcon(old_icon); |
| 865 } |
| 866 if (!app_icon.isNull()) { |
| 867 HICON windows_icon = IconUtil::CreateHICONFromSkBitmap(app_icon); |
| 868 HICON old_icon = reinterpret_cast<HICON>( |
| 869 SendMessage(hwnd(), WM_SETICON, ICON_BIG, |
| 870 reinterpret_cast<LPARAM>(windows_icon))); |
| 871 if (old_icon) |
| 872 DestroyIcon(old_icon); |
| 873 } |
| 874 } |
| 875 |
679 void HWNDMessageHandler::OnActivate(UINT action, BOOL minimized, HWND window) { | 876 void HWNDMessageHandler::OnActivate(UINT action, BOOL minimized, HWND window) { |
680 SetMsgHandled(FALSE); | 877 SetMsgHandled(FALSE); |
681 } | 878 } |
682 | 879 |
683 void HWNDMessageHandler::OnActivateApp(BOOL active, DWORD thread_id) { | 880 void HWNDMessageHandler::OnActivateApp(BOOL active, DWORD thread_id) { |
684 if (delegate_->IsWidgetWindow() && !active && | 881 if (delegate_->IsWidgetWindow() && !active && |
685 thread_id != GetCurrentThreadId()) { | 882 thread_id != GetCurrentThreadId()) { |
686 delegate_->HandleAppDeactivated(); | 883 delegate_->HandleAppDeactivated(); |
687 // Also update the native frame if it is rendering the non-client area. | 884 // Also update the native frame if it is rendering the non-client area. |
688 if (!remove_standard_frame_ && !delegate_->IsUsingCustomFrame()) | 885 if (!remove_standard_frame_ && !delegate_->IsUsingCustomFrame()) |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 // creation time. | 955 // creation time. |
759 ClientAreaSizeChanged(); | 956 ClientAreaSizeChanged(); |
760 | 957 |
761 delegate_->HandleCreate(); | 958 delegate_->HandleCreate(); |
762 | 959 |
763 // TODO(beng): move more of NWW::OnCreate here. | 960 // TODO(beng): move more of NWW::OnCreate here. |
764 return 0; | 961 return 0; |
765 } | 962 } |
766 | 963 |
767 void HWNDMessageHandler::OnDestroy() { | 964 void HWNDMessageHandler::OnDestroy() { |
768 delegate_->HandleDestroy(); | 965 delegate_->HandleDestroying(); |
769 } | 966 } |
770 | 967 |
771 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, | 968 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, |
772 const CSize& screen_size) { | 969 const CSize& screen_size) { |
773 delegate_->HandleDisplayChange(); | 970 delegate_->HandleDisplayChange(); |
774 } | 971 } |
775 | 972 |
776 LRESULT HWNDMessageHandler::OnDwmCompositionChanged(UINT msg, | 973 LRESULT HWNDMessageHandler::OnDwmCompositionChanged(UINT msg, |
777 WPARAM w_param, | 974 WPARAM w_param, |
778 LPARAM l_param) { | 975 LPARAM l_param) { |
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1635 } | 1832 } |
1636 | 1833 |
1637 //////////////////////////////////////////////////////////////////////////////// | 1834 //////////////////////////////////////////////////////////////////////////////// |
1638 // HWNDMessageHandler, InputMethodDelegate implementation: | 1835 // HWNDMessageHandler, InputMethodDelegate implementation: |
1639 | 1836 |
1640 void HWNDMessageHandler::DispatchKeyEventPostIME(const ui::KeyEvent& key) { | 1837 void HWNDMessageHandler::DispatchKeyEventPostIME(const ui::KeyEvent& key) { |
1641 SetMsgHandled(delegate_->HandleKeyEvent(key)); | 1838 SetMsgHandled(delegate_->HandleKeyEvent(key)); |
1642 } | 1839 } |
1643 | 1840 |
1644 //////////////////////////////////////////////////////////////////////////////// | 1841 //////////////////////////////////////////////////////////////////////////////// |
| 1842 // HWNDMessageHandler, ui::WindowImpl overrides: |
| 1843 |
| 1844 HICON HWNDMessageHandler::GetDefaultWindowIcon() const { |
| 1845 return ViewsDelegate::views_delegate ? |
| 1846 ViewsDelegate::views_delegate->GetDefaultWindowIcon() : NULL; |
| 1847 } |
| 1848 |
| 1849 LRESULT HWNDMessageHandler::OnWndProc(UINT message, |
| 1850 WPARAM w_param, |
| 1851 LPARAM l_param) { |
| 1852 HWND window = hwnd(); |
| 1853 LRESULT result = 0; |
| 1854 |
| 1855 // First allow messages sent by child controls to be processed directly by |
| 1856 // their associated views. If such a view is present, it will handle the |
| 1857 // message *instead of* this NativeWidgetWin. |
| 1858 if (ProcessChildWindowMessage(message, w_param, l_param, &result)) |
| 1859 return result; |
| 1860 |
| 1861 // Otherwise we handle everything else. |
| 1862 if (!delegate_->AsNativeWidgetWin()->ProcessWindowMessage( |
| 1863 window, message, w_param, l_param, result)) { |
| 1864 result = DefWindowProc(window, message, w_param, l_param); |
| 1865 } |
| 1866 if (message == WM_NCDESTROY) |
| 1867 delegate_->HandleDestroyed(); |
| 1868 |
| 1869 // Only top level widget should store/restore focus. |
| 1870 if (message == WM_ACTIVATE && delegate_->CanSaveFocus()) |
| 1871 PostProcessActivateMessage(LOWORD(w_param)); |
| 1872 if (message == WM_ENABLE && restore_focus_when_enabled_) { |
| 1873 // This path should be executed only for top level as |
| 1874 // restore_focus_when_enabled_ is set in PostProcessActivateMessage. |
| 1875 DCHECK(delegate_->CanSaveFocus()); |
| 1876 restore_focus_when_enabled_ = false; |
| 1877 delegate_->RestoreFocusOnEnable(); |
| 1878 } |
| 1879 return result; |
| 1880 } |
| 1881 |
| 1882 |
| 1883 //////////////////////////////////////////////////////////////////////////////// |
1645 // HWNDMessageHandler, private: | 1884 // HWNDMessageHandler, private: |
1646 | 1885 |
| 1886 void HWNDMessageHandler::SetInitialFocus() { |
| 1887 if (!(GetWindowLong(hwnd(), GWL_EXSTYLE) & WS_EX_TRANSPARENT) && |
| 1888 !(GetWindowLong(hwnd(), GWL_EXSTYLE) & WS_EX_NOACTIVATE)) { |
| 1889 // The window does not get keyboard messages unless we focus it. |
| 1890 SetFocus(hwnd()); |
| 1891 } |
| 1892 } |
| 1893 |
| 1894 void HWNDMessageHandler::PostProcessActivateMessage(int activation_state) { |
| 1895 DCHECK(delegate_->CanSaveFocus()); |
| 1896 if (WA_INACTIVE == activation_state) { |
| 1897 // We might get activated/inactivated without being enabled, so we need to |
| 1898 // clear restore_focus_when_enabled_. |
| 1899 restore_focus_when_enabled_ = false; |
| 1900 delegate_->SaveFocusOnDeactivate(); |
| 1901 } else { |
| 1902 // We must restore the focus after the message has been DefProc'ed as it |
| 1903 // does set the focus to the last focused HWND. |
| 1904 // Note that if the window is not enabled, we cannot restore the focus as |
| 1905 // calling ::SetFocus on a child of the non-enabled top-window would fail. |
| 1906 // This is the case when showing a modal dialog (such as 'open file', |
| 1907 // 'print'...) from a different thread. |
| 1908 // In that case we delay the focus restoration to when the window is enabled |
| 1909 // again. |
| 1910 if (!IsWindowEnabled(hwnd())) { |
| 1911 DCHECK(!restore_focus_when_enabled_); |
| 1912 restore_focus_when_enabled_ = true; |
| 1913 return; |
| 1914 } |
| 1915 delegate_->RestoreFocusOnActivate(); |
| 1916 } |
| 1917 } |
| 1918 |
| 1919 void HWNDMessageHandler::RestoreEnabledIfNecessary() { |
| 1920 if (delegate_->IsModal() && !restored_enabled_) { |
| 1921 restored_enabled_ = true; |
| 1922 // If we were run modally, we need to undo the disabled-ness we inflicted on |
| 1923 // the owner's parent hierarchy. |
| 1924 HWND start = ::GetWindow(hwnd(), GW_OWNER); |
| 1925 while (start) { |
| 1926 ::EnableWindow(start, TRUE); |
| 1927 start = ::GetParent(start); |
| 1928 } |
| 1929 } |
| 1930 } |
| 1931 |
1647 void HWNDMessageHandler::ExecuteSystemMenuCommand(int command) { | 1932 void HWNDMessageHandler::ExecuteSystemMenuCommand(int command) { |
1648 if (command) | 1933 if (command) |
1649 SendMessage(hwnd(), WM_SYSCOMMAND, command, 0); | 1934 SendMessage(hwnd(), WM_SYSCOMMAND, command, 0); |
1650 } | 1935 } |
1651 | 1936 |
1652 void HWNDMessageHandler::TrackMouseEvents(DWORD mouse_tracking_flags) { | 1937 void HWNDMessageHandler::TrackMouseEvents(DWORD mouse_tracking_flags) { |
1653 // Begin tracking mouse events for this HWND so that we get WM_MOUSELEAVE | 1938 // Begin tracking mouse events for this HWND so that we get WM_MOUSELEAVE |
1654 // when the user moves the mouse outside this HWND's bounds. | 1939 // when the user moves the mouse outside this HWND's bounds. |
1655 if (active_mouse_tracking_flags_ == 0 || mouse_tracking_flags & TME_CANCEL) { | 1940 if (active_mouse_tracking_flags_ == 0 || mouse_tracking_flags & TME_CANCEL) { |
1656 if (mouse_tracking_flags & TME_CANCEL) { | 1941 if (mouse_tracking_flags & TME_CANCEL) { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1808 RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA); | 2093 RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA); |
1809 invalid_rect_.SetRect(0, 0, 0, 0); | 2094 invalid_rect_.SetRect(0, 0, 0, 0); |
1810 skia::EndPlatformPaint(layered_window_contents_->sk_canvas()); | 2095 skia::EndPlatformPaint(layered_window_contents_->sk_canvas()); |
1811 } | 2096 } |
1812 | 2097 |
1813 void HWNDMessageHandler::SetMsgHandled(BOOL handled) { | 2098 void HWNDMessageHandler::SetMsgHandled(BOOL handled) { |
1814 delegate_->AsNativeWidgetWin()->SetMsgHandled(handled); | 2099 delegate_->AsNativeWidgetWin()->SetMsgHandled(handled); |
1815 } | 2100 } |
1816 | 2101 |
1817 } // namespace views | 2102 } // namespace views |
OLD | NEW |