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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/views/frame/minimize_button_metrics_win.h" 6 7 #include "base/logging.h" 8 #include "base/i18n/rtl.h" 9 #include "ui/base/win/dpi.h" 10 11 namespace { 12 13 int GetMinimizeButtonOffsetForWindow(HWND hwnd) { 14 // The WM_GETTITLEBARINFOEX message can fail if we are not active/visible. 15 TITLEBARINFOEX titlebar_info = {0}; 16 titlebar_info.cbSize = sizeof(TITLEBARINFOEX); 17 SendMessage(hwnd, WM_GETTITLEBARINFOEX, 0, 18 reinterpret_cast<WPARAM>(&titlebar_info)); 19 20 // NOTE: TITLEBARINFOEX coordinates are not scaled (they are physical). As 21 // Chrome is not DPIAware we need to properly scale the coordinates as 22 // MapWindowPoints() expects scaled coordinates. 23 POINT minimize_button_corner = { titlebar_info.rgrect[2].left / 24 ui::win::GetUndocumentedDPIScale(), 25 0 }; 26 MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1); 27 return minimize_button_corner.x / ui::win::GetDeviceScaleFactor(); 28 } 29 30 } // namespace 31 32 MinimizeButtonMetrics::MinimizeButtonMetrics() 33 : hwnd_(NULL), 34 cached_minimize_button_x_delta_(0) { 35 } 36 37 MinimizeButtonMetrics::~MinimizeButtonMetrics() { 38 } 39 40 void MinimizeButtonMetrics::Init(HWND hwnd) { 41 DCHECK(!hwnd_); 42 hwnd_ = hwnd; 43 } 44 45 void MinimizeButtonMetrics::OnHWNDActivated() { 46 int minimize_offset = GetMinimizeButtonOffsetForWindow(hwnd_); 47 48 RECT rect = {0}; 49 GetClientRect(hwnd_, &rect); 50 // Calculate and cache the value of the minimize button delta, i.e. the 51 // offset to be applied to the left or right edge of the client rect 52 // depending on whether the language is RTL or not. 53 // This cached value is only used if the WM_GETTITLEBARINFOEX message fails 54 // to get the offset of the minimize button. 55 if (base::i18n::IsRTL()) 56 cached_minimize_button_x_delta_ = minimize_offset; 57 else 58 cached_minimize_button_x_delta_ = rect.right - minimize_offset; 59 } 60 61 int MinimizeButtonMetrics::GetMinimizeButtonOffsetX() const { 62 int minimize_button_offset = GetMinimizeButtonOffsetForWindow(hwnd_); 63 if (minimize_button_offset > 0) 64 return minimize_button_offset; 65 66 // If we fail to get the minimize button offset via the WM_GETTITLEBARINFOEX 67 // message then calculate and return this via the 68 // cached_minimize_button_x_delta_ member value. Please see 69 // CacheMinimizeButtonDelta() for more details. 70 DCHECK(cached_minimize_button_x_delta_); 71 72 RECT client_rect = {0}; 73 GetClientRect(hwnd_, &client_rect); 74 75 if (base::i18n::IsRTL()) 76 return cached_minimize_button_x_delta_; 77 return client_rect.right - cached_minimize_button_x_delta_; 78 } 79 80