minimize_button_metrics_win.cc revision 58537e28ecd584eab876aee8be7156509866d23a
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/gfx/dpi_win.h"
10
11namespace {
12
13int 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                                   gfx::win::GetUndocumentedDPIScale(),
25                                   0 };
26  MapWindowPoints(HWND_DESKTOP, hwnd, &minimize_button_corner, 1);
27  return minimize_button_corner.x / gfx::win::GetDeviceScaleFactor();
28}
29
30}  // namespace
31
32MinimizeButtonMetrics::MinimizeButtonMetrics()
33    : hwnd_(NULL),
34      cached_minimize_button_x_delta_(0) {
35}
36
37MinimizeButtonMetrics::~MinimizeButtonMetrics() {
38}
39
40void MinimizeButtonMetrics::Init(HWND hwnd) {
41  DCHECK(!hwnd_);
42  hwnd_ = hwnd;
43}
44
45void 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
61int 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