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 <oleacc.h> | 8 #include <oleacc.h> |
9 #include <shellapi.h> | 9 #include <shellapi.h> |
10 #include <tchar.h> | 10 #include <tchar.h> |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 } | 551 } |
552 | 552 |
553 void HWNDMessageHandler::CenterWindow(const gfx::Size& size) { | 553 void HWNDMessageHandler::CenterWindow(const gfx::Size& size) { |
554 HWND parent = GetParent(hwnd()); | 554 HWND parent = GetParent(hwnd()); |
555 if (!IsWindow(hwnd())) | 555 if (!IsWindow(hwnd())) |
556 parent = ::GetWindow(hwnd(), GW_OWNER); | 556 parent = ::GetWindow(hwnd(), GW_OWNER); |
557 gfx::CenterAndSizeWindow(parent, hwnd(), size); | 557 gfx::CenterAndSizeWindow(parent, hwnd(), size); |
558 } | 558 } |
559 | 559 |
560 void HWNDMessageHandler::SetRegion(HRGN region) { | 560 void HWNDMessageHandler::SetRegion(HRGN region) { |
561 custom_window_region_.Set(region); | 561 custom_window_region_.reset(region); |
562 ResetWindowRegion(true, true); | 562 ResetWindowRegion(true, true); |
563 } | 563 } |
564 | 564 |
565 void HWNDMessageHandler::StackAbove(HWND other_hwnd) { | 565 void HWNDMessageHandler::StackAbove(HWND other_hwnd) { |
566 // Windows API allows to stack behind another windows only. | 566 // Windows API allows to stack behind another windows only. |
567 DCHECK(other_hwnd); | 567 DCHECK(other_hwnd); |
568 HWND next_window = GetNextWindow(other_hwnd, GW_HWNDPREV); | 568 HWND next_window = GetNextWindow(other_hwnd, GW_HWNDPREV); |
569 SetWindowPos(hwnd(), next_window ? next_window : HWND_TOP, 0, 0, 0, 0, | 569 SetWindowPos(hwnd(), next_window ? next_window : HWND_TOP, 0, 0, 0, 0, |
570 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); | 570 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); |
571 } | 571 } |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | | 743 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS | |
744 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | | 744 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION | |
745 SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); | 745 SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER); |
746 } | 746 } |
747 | 747 |
748 void HWNDMessageHandler::FlashFrame(bool flash) { | 748 void HWNDMessageHandler::FlashFrame(bool flash) { |
749 FLASHWINFO fwi; | 749 FLASHWINFO fwi; |
750 fwi.cbSize = sizeof(fwi); | 750 fwi.cbSize = sizeof(fwi); |
751 fwi.hwnd = hwnd(); | 751 fwi.hwnd = hwnd(); |
752 if (flash) { | 752 if (flash) { |
753 fwi.dwFlags = custom_window_region_ ? FLASHW_TRAY : FLASHW_ALL; | 753 fwi.dwFlags = custom_window_region_.is_valid() ? FLASHW_TRAY : FLASHW_ALL; |
754 fwi.uCount = 4; | 754 fwi.uCount = 4; |
755 fwi.dwTimeout = 0; | 755 fwi.dwTimeout = 0; |
756 } else { | 756 } else { |
757 fwi.dwFlags = FLASHW_STOP; | 757 fwi.dwFlags = FLASHW_STOP; |
758 } | 758 } |
759 FlashWindowEx(&fwi); | 759 FlashWindowEx(&fwi); |
760 } | 760 } |
761 | 761 |
762 void HWNDMessageHandler::ClearNativeFocus() { | 762 void HWNDMessageHandler::ClearNativeFocus() { |
763 ::SetFocus(hwnd()); | 763 ::SetFocus(hwnd()); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 } | 811 } |
812 | 812 |
813 void HWNDMessageHandler::FrameTypeChanged() { | 813 void HWNDMessageHandler::FrameTypeChanged() { |
814 if (base::win::GetVersion() < base::win::VERSION_VISTA) { | 814 if (base::win::GetVersion() < base::win::VERSION_VISTA) { |
815 // Don't redraw the window here, because we invalidate the window later. | 815 // Don't redraw the window here, because we invalidate the window later. |
816 ResetWindowRegion(true, false); | 816 ResetWindowRegion(true, false); |
817 // The non-client view needs to update too. | 817 // The non-client view needs to update too. |
818 delegate_->HandleFrameChanged(); | 818 delegate_->HandleFrameChanged(); |
819 InvalidateRect(hwnd(), NULL, FALSE); | 819 InvalidateRect(hwnd(), NULL, FALSE); |
820 } else { | 820 } else { |
821 if (!custom_window_region_ && !delegate_->IsUsingCustomFrame()) | 821 if (!custom_window_region_.is_valid() && !delegate_->IsUsingCustomFrame()) |
822 dwm_transition_desired_ = true; | 822 dwm_transition_desired_ = true; |
823 if (!dwm_transition_desired_ || !fullscreen_handler_->fullscreen()) | 823 if (!dwm_transition_desired_ || !fullscreen_handler_->fullscreen()) |
824 PerformDwmTransition(); | 824 PerformDwmTransition(); |
825 } | 825 } |
826 } | 826 } |
827 | 827 |
828 void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon, | 828 void HWNDMessageHandler::SetWindowIcons(const gfx::ImageSkia& window_icon, |
829 const gfx::ImageSkia& app_icon) { | 829 const gfx::ImageSkia& app_icon) { |
830 if (!window_icon.isNull()) { | 830 if (!window_icon.isNull()) { |
831 HICON windows_icon = IconUtil::CreateHICONFromSkBitmap( | 831 base::win::ScopedHICON previous_icon = window_icon_.Pass(); |
832 *window_icon.bitmap()); | 832 window_icon_ = |
833 // We need to make sure to destroy the previous icon, otherwise we'll leak | 833 IconUtil::CreateHICONFromSkBitmap(*window_icon.bitmap()).Pass(); |
834 // these GDI objects until we crash! | 834 SendMessage(hwnd(), WM_SETICON, ICON_SMALL, |
835 HICON old_icon = reinterpret_cast<HICON>( | 835 reinterpret_cast<LPARAM>(window_icon_.get())); |
836 SendMessage(hwnd(), WM_SETICON, ICON_SMALL, | |
837 reinterpret_cast<LPARAM>(windows_icon))); | |
838 if (old_icon) | |
839 DestroyIcon(old_icon); | |
840 } | 836 } |
841 if (!app_icon.isNull()) { | 837 if (!app_icon.isNull()) { |
842 HICON windows_icon = IconUtil::CreateHICONFromSkBitmap(*app_icon.bitmap()); | 838 base::win::ScopedHICON previous_icon = app_icon_.Pass(); |
843 HICON old_icon = reinterpret_cast<HICON>( | 839 app_icon_ = IconUtil::CreateHICONFromSkBitmap(*app_icon.bitmap()).Pass(); |
844 SendMessage(hwnd(), WM_SETICON, ICON_BIG, | 840 SendMessage(hwnd(), WM_SETICON, ICON_BIG, |
845 reinterpret_cast<LPARAM>(windows_icon))); | 841 reinterpret_cast<LPARAM>(app_icon_.get())); |
846 if (old_icon) | |
847 DestroyIcon(old_icon); | |
848 } | 842 } |
849 } | 843 } |
850 | 844 |
851 void HWNDMessageHandler::SetFullscreen(bool fullscreen) { | 845 void HWNDMessageHandler::SetFullscreen(bool fullscreen) { |
852 fullscreen_handler()->SetFullscreen(fullscreen); | 846 fullscreen_handler()->SetFullscreen(fullscreen); |
853 // If we are out of fullscreen and there was a pending DWM transition for the | 847 // If we are out of fullscreen and there was a pending DWM transition for the |
854 // window, then go ahead and do it now. | 848 // window, then go ahead and do it now. |
855 if (!fullscreen && dwm_transition_desired_) | 849 if (!fullscreen && dwm_transition_desired_) |
856 PerformDwmTransition(); | 850 PerformDwmTransition(); |
857 } | 851 } |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1114 return true; | 1108 return true; |
1115 } | 1109 } |
1116 | 1110 |
1117 void HWNDMessageHandler::ResetWindowRegion(bool force, bool redraw) { | 1111 void HWNDMessageHandler::ResetWindowRegion(bool force, bool redraw) { |
1118 // A native frame uses the native window region, and we don't want to mess | 1112 // A native frame uses the native window region, and we don't want to mess |
1119 // with it. | 1113 // with it. |
1120 // WS_EX_COMPOSITED is used instead of WS_EX_LAYERED under aura. WS_EX_LAYERED | 1114 // WS_EX_COMPOSITED is used instead of WS_EX_LAYERED under aura. WS_EX_LAYERED |
1121 // automatically makes clicks on transparent pixels fall through, that isn't | 1115 // automatically makes clicks on transparent pixels fall through, that isn't |
1122 // the case with WS_EX_COMPOSITED. So, we route WS_EX_COMPOSITED through to | 1116 // the case with WS_EX_COMPOSITED. So, we route WS_EX_COMPOSITED through to |
1123 // the delegate to allow for a custom hit mask. | 1117 // the delegate to allow for a custom hit mask. |
1124 if ((window_ex_style() & WS_EX_COMPOSITED) == 0 && !custom_window_region_ && | 1118 if ((window_ex_style() & WS_EX_COMPOSITED) == 0 && |
| 1119 !custom_window_region_.is_valid() && |
1125 (!delegate_->IsUsingCustomFrame() || !delegate_->IsWidgetWindow())) { | 1120 (!delegate_->IsUsingCustomFrame() || !delegate_->IsWidgetWindow())) { |
1126 if (force) | 1121 if (force) |
1127 SetWindowRgn(hwnd(), NULL, redraw); | 1122 SetWindowRgn(hwnd(), NULL, redraw); |
1128 return; | 1123 return; |
1129 } | 1124 } |
1130 | 1125 |
1131 // Changing the window region is going to force a paint. Only change the | 1126 // Changing the window region is going to force a paint. Only change the |
1132 // window region if the region really differs. | 1127 // window region if the region really differs. |
1133 base::win::ScopedRegion current_rgn(CreateRectRgn(0, 0, 0, 0)); | 1128 base::win::ScopedRegion current_rgn(CreateRectRgn(0, 0, 0, 0)); |
1134 GetWindowRgn(hwnd(), current_rgn); | 1129 GetWindowRgn(hwnd(), current_rgn.get()); |
1135 | 1130 |
1136 RECT window_rect; | 1131 RECT window_rect; |
1137 GetWindowRect(hwnd(), &window_rect); | 1132 GetWindowRect(hwnd(), &window_rect); |
1138 base::win::ScopedRegion new_region; | 1133 base::win::ScopedRegion new_region; |
1139 if (custom_window_region_) { | 1134 if (custom_window_region_.is_valid()) { |
1140 new_region.Set(::CreateRectRgn(0, 0, 0, 0)); | 1135 new_region.reset(CreateRectRgn(0, 0, 0, 0)); |
1141 ::CombineRgn(new_region, custom_window_region_.Get(), NULL, RGN_COPY); | 1136 CombineRgn(new_region.get(), custom_window_region_.get(), NULL, RGN_COPY); |
1142 } else if (IsMaximized()) { | 1137 } else if (IsMaximized()) { |
1143 HMONITOR monitor = MonitorFromWindow(hwnd(), MONITOR_DEFAULTTONEAREST); | 1138 HMONITOR monitor = MonitorFromWindow(hwnd(), MONITOR_DEFAULTTONEAREST); |
1144 MONITORINFO mi; | 1139 MONITORINFO mi; |
1145 mi.cbSize = sizeof mi; | 1140 mi.cbSize = sizeof mi; |
1146 GetMonitorInfo(monitor, &mi); | 1141 GetMonitorInfo(monitor, &mi); |
1147 RECT work_rect = mi.rcWork; | 1142 RECT work_rect = mi.rcWork; |
1148 OffsetRect(&work_rect, -window_rect.left, -window_rect.top); | 1143 OffsetRect(&work_rect, -window_rect.left, -window_rect.top); |
1149 new_region.Set(CreateRectRgnIndirect(&work_rect)); | 1144 new_region.reset(CreateRectRgnIndirect(&work_rect)); |
1150 } else { | 1145 } else { |
1151 gfx::Path window_mask; | 1146 gfx::Path window_mask; |
1152 delegate_->GetWindowMask(gfx::Size(window_rect.right - window_rect.left, | 1147 delegate_->GetWindowMask(gfx::Size(window_rect.right - window_rect.left, |
1153 window_rect.bottom - window_rect.top), | 1148 window_rect.bottom - window_rect.top), |
1154 &window_mask); | 1149 &window_mask); |
1155 if (!window_mask.isEmpty()) | 1150 if (!window_mask.isEmpty()) |
1156 new_region.Set(gfx::CreateHRGNFromSkPath(window_mask)); | 1151 new_region.reset(gfx::CreateHRGNFromSkPath(window_mask)); |
1157 } | 1152 } |
1158 | 1153 |
1159 const bool has_current_region = current_rgn != 0; | 1154 const bool has_current_region = current_rgn != 0; |
1160 const bool has_new_region = new_region != 0; | 1155 const bool has_new_region = new_region != 0; |
1161 if (has_current_region != has_new_region || | 1156 if (has_current_region != has_new_region || |
1162 (has_current_region && !EqualRgn(current_rgn, new_region))) { | 1157 (has_current_region && !EqualRgn(current_rgn.get(), new_region.get()))) { |
1163 // SetWindowRgn takes ownership of the HRGN. | 1158 // SetWindowRgn takes ownership of the HRGN. |
1164 SetWindowRgn(hwnd(), new_region.release(), redraw); | 1159 SetWindowRgn(hwnd(), new_region.release(), redraw); |
1165 } | 1160 } |
1166 } | 1161 } |
1167 | 1162 |
1168 void HWNDMessageHandler::UpdateDwmNcRenderingPolicy() { | 1163 void HWNDMessageHandler::UpdateDwmNcRenderingPolicy() { |
1169 if (base::win::GetVersion() < base::win::VERSION_VISTA) | 1164 if (base::win::GetVersion() < base::win::VERSION_VISTA) |
1170 return; | 1165 return; |
1171 | 1166 |
1172 if (fullscreen_handler_->fullscreen()) | 1167 if (fullscreen_handler_->fullscreen()) |
1173 return; | 1168 return; |
1174 | 1169 |
1175 DWMNCRENDERINGPOLICY policy = | 1170 DWMNCRENDERINGPOLICY policy = |
1176 custom_window_region_ || delegate_->IsUsingCustomFrame() ? | 1171 custom_window_region_.is_valid() || delegate_->IsUsingCustomFrame() |
1177 DWMNCRP_DISABLED : DWMNCRP_ENABLED; | 1172 ? DWMNCRP_DISABLED |
| 1173 : DWMNCRP_ENABLED; |
1178 | 1174 |
1179 DwmSetWindowAttribute(hwnd(), DWMWA_NCRENDERING_POLICY, | 1175 DwmSetWindowAttribute(hwnd(), DWMWA_NCRENDERING_POLICY, |
1180 &policy, sizeof(DWMNCRENDERINGPOLICY)); | 1176 &policy, sizeof(DWMNCRENDERINGPOLICY)); |
1181 } | 1177 } |
1182 | 1178 |
1183 LRESULT HWNDMessageHandler::DefWindowProcWithRedrawLock(UINT message, | 1179 LRESULT HWNDMessageHandler::DefWindowProcWithRedrawLock(UINT message, |
1184 WPARAM w_param, | 1180 WPARAM w_param, |
1185 LPARAM l_param) { | 1181 LPARAM l_param) { |
1186 ScopedRedrawLock lock(this); | 1182 ScopedRedrawLock lock(this); |
1187 // The Widget and HWND can be destroyed in the call to DefWindowProc, so use | 1183 // The Widget and HWND can be destroyed in the call to DefWindowProc, so use |
(...skipping 1382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2570 | 2566 |
2571 default: | 2567 default: |
2572 left_button_down_on_caption_ = false; | 2568 left_button_down_on_caption_ = false; |
2573 break; | 2569 break; |
2574 } | 2570 } |
2575 return handled; | 2571 return handled; |
2576 } | 2572 } |
2577 | 2573 |
2578 | 2574 |
2579 } // namespace views | 2575 } // namespace views |
OLD | NEW |