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