OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/window/window_win.h" | 5 #include "views/window/window_win.h" |
6 | 6 |
7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
8 #include <shellapi.h> | 8 #include <shellapi.h> |
9 | 9 |
10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 InitClass(); | 644 InitClass(); |
645 DCHECK(window_delegate_); | 645 DCHECK(window_delegate_); |
646 DCHECK(!window_delegate_->window_); | 646 DCHECK(!window_delegate_->window_); |
647 window_delegate_->window_ = this; | 647 window_delegate_->window_ = this; |
648 // Initialize these values to 0 so that subclasses can override the default | 648 // Initialize these values to 0 so that subclasses can override the default |
649 // behavior before calling Init. | 649 // behavior before calling Init. |
650 set_window_style(0); | 650 set_window_style(0); |
651 set_window_ex_style(0); | 651 set_window_ex_style(0); |
652 } | 652 } |
653 | 653 |
654 void WindowWin::Init(HWND parent, const gfx::Rect& bounds) { | 654 void WindowWin::Init(gfx::NativeView parent, const gfx::Rect& bounds) { |
655 // We need to save the parent window, since later calls to GetParent() will | 655 // We need to save the parent window, since later calls to GetParent() will |
656 // return NULL. | 656 // return NULL. |
657 owning_hwnd_ = parent; | 657 owning_hwnd_ = parent; |
658 // We call this after initializing our members since our implementations of | 658 // We call this after initializing our members since our implementations of |
659 // assorted WidgetWin functions may be called during initialization. | 659 // assorted WidgetWin functions may be called during initialization. |
660 is_modal_ = window_delegate_->IsModal(); | 660 is_modal_ = window_delegate_->IsModal(); |
661 if (is_modal_) | 661 if (is_modal_) |
662 BecomeModal(); | 662 BecomeModal(); |
663 | 663 |
664 if (window_style() == 0) | 664 if (window_style() == 0) |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 ScopedRedrawLock lock(this); | 810 ScopedRedrawLock lock(this); |
811 EnableMenuItem(menu, SC_RESTORE, is_minimized || is_maximized); | 811 EnableMenuItem(menu, SC_RESTORE, is_minimized || is_maximized); |
812 EnableMenuItem(menu, SC_MOVE, is_restored); | 812 EnableMenuItem(menu, SC_MOVE, is_restored); |
813 EnableMenuItem(menu, SC_SIZE, window_delegate_->CanResize() && is_restored); | 813 EnableMenuItem(menu, SC_SIZE, window_delegate_->CanResize() && is_restored); |
814 EnableMenuItem(menu, SC_MAXIMIZE, | 814 EnableMenuItem(menu, SC_MAXIMIZE, |
815 window_delegate_->CanMaximize() && !is_fullscreen && !is_maximized); | 815 window_delegate_->CanMaximize() && !is_fullscreen && !is_maximized); |
816 EnableMenuItem(menu, SC_MINIMIZE, | 816 EnableMenuItem(menu, SC_MINIMIZE, |
817 window_delegate_->CanMaximize() && !is_minimized); | 817 window_delegate_->CanMaximize() && !is_minimized); |
818 } | 818 } |
819 | 819 |
820 void WindowWin::OnMouseLeave() { | 820 LRESULT WindowWin::OnMouseLeave(UINT message, WPARAM w_param, LPARAM l_param) { |
821 // We only need to manually track WM_MOUSELEAVE messages between the client | 821 // We only need to manually track WM_MOUSELEAVE messages between the client |
822 // and non-client area when we're not using the native frame. | 822 // and non-client area when we're not using the native frame. |
823 if (non_client_view_->UseNativeFrame()) { | 823 if (non_client_view_->UseNativeFrame()) { |
824 SetMsgHandled(FALSE); | 824 SetMsgHandled(FALSE); |
825 return; | 825 return 0; |
826 } | 826 } |
827 | 827 |
828 bool process_mouse_exited = true; | 828 bool process_mouse_exited = true; |
829 POINT pt; | 829 POINT pt; |
830 if (GetCursorPos(&pt)) { | 830 if (GetCursorPos(&pt)) { |
831 LRESULT ht_component = | 831 LRESULT ht_component = |
832 ::SendMessage(GetNativeView(), WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y)); | 832 ::SendMessage(GetNativeView(), WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y)); |
833 if (ht_component != HTNOWHERE) { | 833 if (ht_component != HTNOWHERE) { |
834 // If the mouse moved into a part of the window's non-client area, then | 834 // If the mouse moved into a part of the window's non-client area, then |
835 // don't send a mouse exited event since the mouse is still within the | 835 // don't send a mouse exited event since the mouse is still within the |
836 // bounds of the ChromeView that's rendering the frame. Note that we do | 836 // bounds of the ChromeView that's rendering the frame. Note that we do |
837 // _NOT_ do this for windows with native frames, since in that case the | 837 // _NOT_ do this for windows with native frames, since in that case the |
838 // mouse really will have left the bounds of the RootView. | 838 // mouse really will have left the bounds of the RootView. |
839 process_mouse_exited = false; | 839 process_mouse_exited = false; |
840 } | 840 } |
841 } | 841 } |
842 | 842 |
843 if (process_mouse_exited) | 843 if (process_mouse_exited) |
844 ProcessMouseExited(); | 844 ProcessMouseExited(); |
| 845 return 0; |
845 } | 846 } |
846 | 847 |
| 848 LRESULT WindowWin::OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) { |
| 849 if (message == WM_RBUTTONUP) { |
| 850 if (is_right_mouse_pressed_on_caption_) { |
| 851 is_right_mouse_pressed_on_caption_ = false; |
| 852 ReleaseCapture(); |
| 853 // |point| is in window coordinates, but WM_NCHITTEST and TrackPopupMenu() |
| 854 // expect screen coordinates. |
| 855 CPoint screen_point(l_param); |
| 856 MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_point, 1); |
| 857 w_param = SendMessage(GetNativeView(), WM_NCHITTEST, 0, |
| 858 MAKELPARAM(screen_point.x, screen_point.y)); |
| 859 if (w_param == HTCAPTION || w_param == HTSYSMENU) { |
| 860 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; |
| 861 if (base::i18n::IsRTL()) |
| 862 flags |= TPM_RIGHTALIGN; |
| 863 HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE); |
| 864 int id = TrackPopupMenu(system_menu, flags, screen_point.x, |
| 865 screen_point.y, 0, GetNativeView(), NULL); |
| 866 ExecuteSystemMenuCommand(id); |
| 867 return 0; |
| 868 } |
| 869 } |
| 870 } |
| 871 |
| 872 WidgetWin::OnMouseRange(message, w_param, l_param); |
| 873 return 0; |
| 874 } |
| 875 |
| 876 |
847 LRESULT WindowWin::OnNCActivate(BOOL active) { | 877 LRESULT WindowWin::OnNCActivate(BOOL active) { |
848 is_active_ = !!active; | 878 is_active_ = !!active; |
849 | 879 |
850 // The frame may need to redraw as a result of the activation change. | 880 // The frame may need to redraw as a result of the activation change. |
851 // We can get WM_NCACTIVATE before we're actually visible. If we're not | 881 // We can get WM_NCACTIVATE before we're actually visible. If we're not |
852 // visible, no need to paint. | 882 // visible, no need to paint. |
853 if (IsVisible()) | 883 if (IsVisible()) |
854 non_client_view_->SchedulePaint(); | 884 non_client_view_->SchedulePaint(); |
855 | 885 |
856 // If we're active again, we should be allowed to render as inactive, so | 886 // If we're active again, we should be allowed to render as inactive, so |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
955 MapWindowPoints(HWND_DESKTOP, GetNativeView(), &temp, 1); | 985 MapWindowPoints(HWND_DESKTOP, GetNativeView(), &temp, 1); |
956 int component = non_client_view_->NonClientHitTest(gfx::Point(temp)); | 986 int component = non_client_view_->NonClientHitTest(gfx::Point(temp)); |
957 if (component != HTNOWHERE) | 987 if (component != HTNOWHERE) |
958 return component; | 988 return component; |
959 | 989 |
960 // Otherwise, we let Windows do all the native frame non-client handling for | 990 // Otherwise, we let Windows do all the native frame non-client handling for |
961 // us. | 991 // us. |
962 return WidgetWin::OnNCHitTest(point); | 992 return WidgetWin::OnNCHitTest(point); |
963 } | 993 } |
964 | 994 |
965 void WindowWin::OnNCPaint(HRGN rgn) { | 995 LRESULT WindowWin::OnNCMouseRange(UINT message, |
966 // When using a custom frame, we want to avoid calling DefWindowProc() since | 996 WPARAM w_param, |
967 // that may render artifacts. | 997 LPARAM l_param) { |
968 SetMsgHandled(!non_client_view_->UseNativeFrame()); | |
969 } | |
970 | |
971 void WindowWin::OnNCLButtonDown(UINT ht_component, const CPoint& point) { | |
972 // When we're using a native frame, window controls work without us | 998 // When we're using a native frame, window controls work without us |
973 // interfering. | 999 // interfering. |
974 if (!non_client_view_->UseNativeFrame()) { | 1000 if (message == WM_NCLBUTTONDOWN && !non_client_view_->UseNativeFrame()) { |
975 switch (ht_component) { | 1001 switch (w_param) { |
976 case HTCLOSE: | 1002 case HTCLOSE: |
977 case HTMINBUTTON: | 1003 case HTMINBUTTON: |
978 case HTMAXBUTTON: { | 1004 case HTMAXBUTTON: { |
979 // When the mouse is pressed down in these specific non-client areas, | 1005 // When the mouse is pressed down in these specific non-client areas, |
980 // we need to tell the RootView to send the mouse pressed event (which | 1006 // we need to tell the RootView to send the mouse pressed event (which |
981 // sets capture, allowing subsequent WM_LBUTTONUP (note, _not_ | 1007 // sets capture, allowing subsequent WM_LBUTTONUP (note, _not_ |
982 // WM_NCLBUTTONUP) to fire so that the appropriate WM_SYSCOMMAND can be | 1008 // WM_NCLBUTTONUP) to fire so that the appropriate WM_SYSCOMMAND can be |
983 // sent by the applicable button's ButtonListener. We _have_ to do this | 1009 // sent by the applicable button's ButtonListener. We _have_ to do this |
984 // way rather than letting Windows just send the syscommand itself (as | 1010 // way rather than letting Windows just send the syscommand itself (as |
985 // would happen if we never did this dance) because for some insane | 1011 // would happen if we never did this dance) because for some insane |
986 // reason DefWindowProc for WM_NCLBUTTONDOWN also renders the pressed | 1012 // reason DefWindowProc for WM_NCLBUTTONDOWN also renders the pressed |
987 // window control button appearance, in the Windows classic style, over | 1013 // window control button appearance, in the Windows classic style, over |
988 // our view! Ick! By handling this message we prevent Windows from | 1014 // our view! Ick! By handling this message we prevent Windows from |
989 // doing this undesirable thing, but that means we need to roll the | 1015 // doing this undesirable thing, but that means we need to roll the |
990 // sys-command handling ourselves. | 1016 // sys-command handling ourselves. |
991 ProcessNCMousePress(point, MK_LBUTTON); | 1017 // Combine |w_param| with common key state message flags. |
992 return; | 1018 w_param |= ((GetKeyState(VK_CONTROL) & 0x80) == 0x80)? MK_CONTROL : 0; |
| 1019 w_param |= ((GetKeyState(VK_SHIFT) & 0x80) == 0x80)? MK_SHIFT : 0; |
| 1020 ProcessMousePressed(message, w_param, l_param); |
| 1021 return 0; |
993 } | 1022 } |
994 } | 1023 } |
995 } | 1024 } else if (message == WM_NCRBUTTONDOWN && |
996 | 1025 (w_param == HTCAPTION || w_param == HTSYSMENU)) { |
997 WidgetWin::OnNCLButtonDown(ht_component, point); | |
998 | |
999 /* TODO(beng): Fix the standard non-client over-painting bug. This code | |
1000 doesn't work but identifies the problem. | |
1001 if (!IsMsgHandled()) { | |
1002 // WindowWin::OnNCLButtonDown set the message as unhandled. This normally | |
1003 // means WidgetWin::ProcessWindowMessage will pass it to | |
1004 // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird | |
1005 // non-client painting, so we need to call it directly here inside a | |
1006 // scoped update lock. | |
1007 ScopedRedrawLock lock(this); | |
1008 DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, ht_component, | |
1009 MAKELPARAM(point.x, point.y)); | |
1010 SetMsgHandled(TRUE); | |
1011 } | |
1012 */ | |
1013 } | |
1014 | |
1015 void WindowWin::OnNCRButtonDown(UINT ht_component, const CPoint& point) { | |
1016 if (ht_component == HTCAPTION || ht_component == HTSYSMENU) { | |
1017 is_right_mouse_pressed_on_caption_ = true; | 1026 is_right_mouse_pressed_on_caption_ = true; |
1018 // We SetCapture() to ensure we only show the menu when the button down and | 1027 // We SetCapture() to ensure we only show the menu when the button down and |
1019 // up are both on the caption. Note: this causes the button up to be | 1028 // up are both on the caption. Note: this causes the button up to be |
1020 // WM_RBUTTONUP instead of WM_NCRBUTTONUP. | 1029 // WM_RBUTTONUP instead of WM_NCRBUTTONUP. |
1021 SetCapture(); | 1030 SetCapture(); |
1022 } | 1031 } |
1023 | 1032 |
1024 WidgetWin::OnNCRButtonDown(ht_component, point); | 1033 WidgetWin::OnNCMouseRange(message, w_param, l_param); |
| 1034 |
| 1035 /* TODO(beng): Fix the standard non-client over-painting bug. This code |
| 1036 doesn't work but identifies the problem. |
| 1037 if (message == WM_NCLBUTTONDOWN && !IsMsgHandled()) { |
| 1038 // WindowWin::OnNCLButtonDown set the message as unhandled. This normally |
| 1039 // means WidgetWin::ProcessWindowMessage will pass it to |
| 1040 // DefWindowProc. Sadly, DefWindowProc for WM_NCLBUTTONDOWN does weird |
| 1041 // non-client painting, so we need to call it directly here inside a |
| 1042 // scoped update lock. |
| 1043 ScopedRedrawLock lock(this); |
| 1044 DefWindowProc(GetNativeView(), WM_NCLBUTTONDOWN, w_param, l_param); |
| 1045 SetMsgHandled(TRUE); |
| 1046 } |
| 1047 */ |
| 1048 |
| 1049 return 0; |
1025 } | 1050 } |
1026 | 1051 |
1027 void WindowWin::OnRButtonUp(UINT ht_component, const CPoint& point) { | 1052 void WindowWin::OnNCPaint(HRGN rgn) { |
1028 if (is_right_mouse_pressed_on_caption_) { | 1053 // When using a custom frame, we want to avoid calling DefWindowProc() since |
1029 is_right_mouse_pressed_on_caption_ = false; | 1054 // that may render artifacts. |
1030 ReleaseCapture(); | 1055 SetMsgHandled(!non_client_view_->UseNativeFrame()); |
1031 // |point| is in window coordinates, but WM_NCHITTEST and TrackPopupMenu() | |
1032 // expect screen coordinates. | |
1033 CPoint screen_point(point); | |
1034 MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_point, 1); | |
1035 ht_component = SendMessage(GetNativeView(), WM_NCHITTEST, 0, | |
1036 MAKELPARAM(screen_point.x, screen_point.y)); | |
1037 if (ht_component == HTCAPTION || ht_component == HTSYSMENU) { | |
1038 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; | |
1039 if (base::i18n::IsRTL()) | |
1040 flags |= TPM_RIGHTALIGN; | |
1041 HMENU system_menu = GetSystemMenu(GetNativeView(), FALSE); | |
1042 int id = TrackPopupMenu(system_menu, flags, screen_point.x, | |
1043 screen_point.y, 0, GetNativeView(), NULL); | |
1044 ExecuteSystemMenuCommand(id); | |
1045 return; | |
1046 } | |
1047 } | |
1048 | |
1049 WidgetWin::OnRButtonUp(ht_component, point); | |
1050 } | 1056 } |
1051 | 1057 |
1052 LRESULT WindowWin::OnNCUAHDrawCaption(UINT msg, WPARAM w_param, | 1058 LRESULT WindowWin::OnNCUAHDrawCaption(UINT msg, WPARAM w_param, |
1053 LPARAM l_param) { | 1059 LPARAM l_param) { |
1054 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for | 1060 // See comment in widget_win.h at the definition of WM_NCUAHDRAWCAPTION for |
1055 // an explanation about why we need to handle this message. | 1061 // an explanation about why we need to handle this message. |
1056 SetMsgHandled(!non_client_view_->UseNativeFrame()); | 1062 SetMsgHandled(!non_client_view_->UseNativeFrame()); |
1057 return 0; | 1063 return 0; |
1058 } | 1064 } |
1059 | 1065 |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1446 VARIANT var; | 1452 VARIANT var; |
1447 AccessibilityTypes::State state = window_delegate_->accessible_state(); | 1453 AccessibilityTypes::State state = window_delegate_->accessible_state(); |
1448 if (state) { | 1454 if (state) { |
1449 var.lVal = ViewAccessibility::MSAAState(state); | 1455 var.lVal = ViewAccessibility::MSAAState(state); |
1450 hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, | 1456 hr = pAccPropServices->SetHwndProp(GetNativeView(), OBJID_CLIENT, |
1451 CHILDID_SELF, PROPID_ACC_STATE, var); | 1457 CHILDID_SELF, PROPID_ACC_STATE, var); |
1452 } | 1458 } |
1453 } | 1459 } |
1454 } | 1460 } |
1455 | 1461 |
1456 void WindowWin::ProcessNCMousePress(const CPoint& point, int flags) { | |
1457 CPoint temp = point; | |
1458 MapWindowPoints(HWND_DESKTOP, GetNativeView(), &temp, 1); | |
1459 UINT message_flags = 0; | |
1460 if ((GetKeyState(VK_CONTROL) & 0x80) == 0x80) | |
1461 message_flags |= MK_CONTROL; | |
1462 if ((GetKeyState(VK_SHIFT) & 0x80) == 0x80) | |
1463 message_flags |= MK_SHIFT; | |
1464 message_flags |= flags; | |
1465 ProcessMousePressed(temp, message_flags, false, false); | |
1466 } | |
1467 | |
1468 LRESULT WindowWin::CallDefaultNCActivateHandler(BOOL active) { | 1462 LRESULT WindowWin::CallDefaultNCActivateHandler(BOOL active) { |
1469 // The DefWindowProc handling for WM_NCACTIVATE renders the classic-look | 1463 // The DefWindowProc handling for WM_NCACTIVATE renders the classic-look |
1470 // window title bar directly, so we need to use a redraw lock here to prevent | 1464 // window title bar directly, so we need to use a redraw lock here to prevent |
1471 // it from doing so. | 1465 // it from doing so. |
1472 ScopedRedrawLock lock(this); | 1466 ScopedRedrawLock lock(this); |
1473 return DefWindowProc(GetNativeView(), WM_NCACTIVATE, active, 0); | 1467 return DefWindowProc(GetNativeView(), WM_NCACTIVATE, active, 0); |
1474 } | 1468 } |
1475 | 1469 |
1476 void WindowWin::GetWindowBoundsAndMaximizedState(gfx::Rect* bounds, | 1470 void WindowWin::GetWindowBoundsAndMaximizedState(gfx::Rect* bounds, |
1477 bool* maximized) const { | 1471 bool* maximized) const { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1516 Window::CloseSecondaryWidget(native_widget->GetWidget()); | 1510 Window::CloseSecondaryWidget(native_widget->GetWidget()); |
1517 return TRUE; | 1511 return TRUE; |
1518 } | 1512 } |
1519 } // namespace | 1513 } // namespace |
1520 | 1514 |
1521 void Window::CloseAllSecondaryWindows() { | 1515 void Window::CloseAllSecondaryWindows() { |
1522 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); | 1516 EnumThreadWindows(GetCurrentThreadId(), WindowCallbackProc, 0); |
1523 } | 1517 } |
1524 | 1518 |
1525 } // namespace views | 1519 } // namespace views |
OLD | NEW |