| 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 1778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1789 } | 1789 } |
| 1790 | 1790 |
| 1791 default: | 1791 default: |
| 1792 break; | 1792 break; |
| 1793 } | 1793 } |
| 1794 } | 1794 } |
| 1795 return hit_test_code; | 1795 return hit_test_code; |
| 1796 } | 1796 } |
| 1797 | 1797 |
| 1798 void HWNDMessageHandler::OnNCPaint(HRGN rgn) { | 1798 void HWNDMessageHandler::OnNCPaint(HRGN rgn) { |
| 1799 RECT window_rect; |
| 1800 GetWindowRect(hwnd(), &window_rect); |
| 1801 RECT dirty_region; |
| 1802 // A value of 1 indicates paint all. |
| 1803 if (!rgn || rgn == reinterpret_cast<HRGN>(1)) { |
| 1804 dirty_region.left = 0; |
| 1805 dirty_region.top = 0; |
| 1806 dirty_region.right = window_rect.right - window_rect.left; |
| 1807 dirty_region.bottom = window_rect.bottom - window_rect.top; |
| 1808 } else { |
| 1809 RECT rgn_bounding_box; |
| 1810 GetRgnBox(rgn, &rgn_bounding_box); |
| 1811 if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect)) { |
| 1812 SetMsgHandled(FALSE); |
| 1813 return; // Dirty region doesn't intersect window bounds, bail. |
| 1814 } |
| 1815 |
| 1816 // rgn_bounding_box is in screen coordinates. Map it to window coordinates. |
| 1817 OffsetRect(&dirty_region, -window_rect.left, -window_rect.top); |
| 1818 } |
| 1819 |
| 1799 // We only do non-client painting if we're not using the system frame. | 1820 // We only do non-client painting if we're not using the system frame. |
| 1800 // It's required to avoid some native painting artifacts from appearing when | 1821 // It's required to avoid some native painting artifacts from appearing when |
| 1801 // the window is resized. | 1822 // the window is resized. |
| 1802 if (!delegate_->HasNonClientView() || | 1823 if (!delegate_->HasNonClientView() || |
| 1803 delegate_->GetFrameMode() == FrameMode::SYSTEM_DRAWN) { | 1824 delegate_->GetFrameMode() == FrameMode::SYSTEM_DRAWN) { |
| 1825 if (ui::win::IsAeroGlassEnabled()) { |
| 1826 // The default WM_NCPAINT handler under Aero Glass doesn't clear the |
| 1827 // nonclient area, so it'll remain the default white color. That area is |
| 1828 // invisible initially (covered by the window border) but can become |
| 1829 // temporarily visible on maximizing or fullscreening, so clear it here. |
| 1830 HDC dc = GetWindowDC(hwnd()); |
| 1831 RECT client_rect; |
| 1832 ::GetClientRect(hwnd(), &client_rect); |
| 1833 ::MapWindowPoints(hwnd(), nullptr, reinterpret_cast<POINT*>(&client_rect), |
| 1834 2); |
| 1835 ::OffsetRect(&client_rect, -window_rect.left, -window_rect.top); |
| 1836 // client_rect now is in window space. |
| 1837 |
| 1838 base::win::ScopedRegion base(::CreateRectRgnIndirect(&dirty_region)); |
| 1839 base::win::ScopedRegion client(::CreateRectRgnIndirect(&client_rect)); |
| 1840 base::win::ScopedRegion nonclient(::CreateRectRgn(0, 0, 0, 0)); |
| 1841 ::CombineRgn(nonclient.get(), base.get(), client.get(), RGN_DIFF); |
| 1842 |
| 1843 ::SelectClipRgn(dc, nonclient.get()); |
| 1844 HBRUSH brush = CreateSolidBrush(0); |
| 1845 ::FillRect(dc, &dirty_region, brush); |
| 1846 ::DeleteObject(brush); |
| 1847 ::ReleaseDC(hwnd(), dc); |
| 1848 } |
| 1804 SetMsgHandled(FALSE); | 1849 SetMsgHandled(FALSE); |
| 1805 return; | 1850 return; |
| 1806 } | 1851 } |
| 1807 | 1852 |
| 1808 // We have an NC region and need to paint it. We expand the NC region to | |
| 1809 // include the dirty region of the root view. This is done to minimize | |
| 1810 // paints. | |
| 1811 RECT window_rect; | |
| 1812 GetWindowRect(hwnd(), &window_rect); | |
| 1813 | |
| 1814 gfx::Size root_view_size = delegate_->GetRootViewSize(); | 1853 gfx::Size root_view_size = delegate_->GetRootViewSize(); |
| 1815 if (gfx::Size(window_rect.right - window_rect.left, | 1854 if (gfx::Size(window_rect.right - window_rect.left, |
| 1816 window_rect.bottom - window_rect.top) != root_view_size) { | 1855 window_rect.bottom - window_rect.top) != root_view_size) { |
| 1817 // If the size of the window differs from the size of the root view it | 1856 // If the size of the window differs from the size of the root view it |
| 1818 // means we're being asked to paint before we've gotten a WM_SIZE. This can | 1857 // means we're being asked to paint before we've gotten a WM_SIZE. This can |
| 1819 // happen when the user is interactively resizing the window. To avoid | 1858 // happen when the user is interactively resizing the window. To avoid |
| 1820 // mass flickering we don't do anything here. Once we get the WM_SIZE we'll | 1859 // mass flickering we don't do anything here. Once we get the WM_SIZE we'll |
| 1821 // reset the region of the window which triggers another WM_NCPAINT and | 1860 // reset the region of the window which triggers another WM_NCPAINT and |
| 1822 // all is well. | 1861 // all is well. |
| 1823 return; | 1862 return; |
| 1824 } | 1863 } |
| 1825 | |
| 1826 RECT dirty_region; | |
| 1827 // A value of 1 indicates paint all. | |
| 1828 if (!rgn || rgn == reinterpret_cast<HRGN>(1)) { | |
| 1829 dirty_region.left = 0; | |
| 1830 dirty_region.top = 0; | |
| 1831 dirty_region.right = window_rect.right - window_rect.left; | |
| 1832 dirty_region.bottom = window_rect.bottom - window_rect.top; | |
| 1833 } else { | |
| 1834 RECT rgn_bounding_box; | |
| 1835 GetRgnBox(rgn, &rgn_bounding_box); | |
| 1836 if (!IntersectRect(&dirty_region, &rgn_bounding_box, &window_rect)) | |
| 1837 return; // Dirty region doesn't intersect window bounds, bale. | |
| 1838 | |
| 1839 // rgn_bounding_box is in screen coordinates. Map it to window coordinates. | |
| 1840 OffsetRect(&dirty_region, -window_rect.left, -window_rect.top); | |
| 1841 } | |
| 1842 | |
| 1843 delegate_->HandlePaintAccelerated(gfx::Rect(dirty_region)); | 1864 delegate_->HandlePaintAccelerated(gfx::Rect(dirty_region)); |
| 1844 | 1865 |
| 1845 // When using a custom frame, we want to avoid calling DefWindowProc() since | 1866 // When using a custom frame, we want to avoid calling DefWindowProc() since |
| 1846 // that may render artifacts. | 1867 // that may render artifacts. |
| 1847 SetMsgHandled(delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN); | 1868 SetMsgHandled(delegate_->GetFrameMode() == FrameMode::CUSTOM_DRAWN); |
| 1848 } | 1869 } |
| 1849 | 1870 |
| 1850 LRESULT HWNDMessageHandler::OnNCUAHDrawCaption(UINT message, | 1871 LRESULT HWNDMessageHandler::OnNCUAHDrawCaption(UINT message, |
| 1851 WPARAM w_param, | 1872 WPARAM w_param, |
| 1852 LPARAM l_param) { | 1873 LPARAM l_param) { |
| (...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2629 delegate_->HandleClientSizeChanged(GetClientAreaBounds().size()); | 2650 delegate_->HandleClientSizeChanged(GetClientAreaBounds().size()); |
| 2630 ResetWindowRegion(false, true); | 2651 ResetWindowRegion(false, true); |
| 2631 } | 2652 } |
| 2632 | 2653 |
| 2633 if (direct_manipulation_helper_) | 2654 if (direct_manipulation_helper_) |
| 2634 direct_manipulation_helper_->SetBounds(bounds_in_pixels); | 2655 direct_manipulation_helper_->SetBounds(bounds_in_pixels); |
| 2635 } | 2656 } |
| 2636 | 2657 |
| 2637 | 2658 |
| 2638 } // namespace views | 2659 } // namespace views |
| OLD | NEW |