| 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 |