Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: ui/base/win/hwnd_util.cc

Issue 23769011: Move a bunch of windows stuff from ui/base/win to ui/gfx/win (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moar bustage. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/base/win/hwnd_util.h ('k') | ui/base/win/mouse_wheel_util.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "ui/base/win/hwnd_util.h"
6
7 #include "base/i18n/rtl.h"
8 #include "base/strings/string_util.h"
9 #include "base/win/metro.h"
10 #include "base/win/win_util.h"
11 #include "ui/gfx/point.h"
12 #include "ui/gfx/rect.h"
13 #include "ui/gfx/size.h"
14
15 namespace ui {
16
17 namespace {
18
19 // Adjust the window to fit.
20 void AdjustWindowToFit(HWND hwnd, const RECT& bounds, bool fit_to_monitor) {
21 if (fit_to_monitor) {
22 // Get the monitor.
23 HMONITOR hmon = MonitorFromRect(&bounds, MONITOR_DEFAULTTONEAREST);
24 if (hmon) {
25 MONITORINFO mi;
26 mi.cbSize = sizeof(mi);
27 base::win::GetMonitorInfoWrapper(hmon, &mi);
28 gfx::Rect window_rect(bounds);
29 gfx::Rect monitor_rect(mi.rcWork);
30 gfx::Rect new_window_rect = window_rect;
31 new_window_rect.AdjustToFit(monitor_rect);
32 if (new_window_rect != window_rect) {
33 // Window doesn't fit on monitor, move and possibly resize.
34 SetWindowPos(hwnd, 0, new_window_rect.x(), new_window_rect.y(),
35 new_window_rect.width(), new_window_rect.height(),
36 SWP_NOACTIVATE | SWP_NOZORDER);
37 return;
38 }
39 // Else fall through.
40 } else {
41 NOTREACHED() << "Unable to find default monitor";
42 // Fall through.
43 }
44 } // Else fall through.
45
46 // The window is not being fit to monitor, or the window fits on the monitor
47 // as is, or we have no monitor info; reset the bounds.
48 ::SetWindowPos(hwnd, 0, bounds.left, bounds.top,
49 bounds.right - bounds.left, bounds.bottom - bounds.top,
50 SWP_NOACTIVATE | SWP_NOZORDER);
51 }
52
53 } // namespace
54
55 string16 GetClassName(HWND window) {
56 // GetClassNameW will return a truncated result (properly null terminated) if
57 // the given buffer is not large enough. So, it is not possible to determine
58 // that we got the entire class name if the result is exactly equal to the
59 // size of the buffer minus one.
60 DWORD buffer_size = MAX_PATH;
61 while (true) {
62 std::wstring output;
63 DWORD size_ret =
64 GetClassNameW(window, WriteInto(&output, buffer_size), buffer_size);
65 if (size_ret == 0)
66 break;
67 if (size_ret < (buffer_size - 1)) {
68 output.resize(size_ret);
69 return output;
70 }
71 buffer_size *= 2;
72 }
73 return std::wstring(); // error
74 }
75
76 #pragma warning(push)
77 #pragma warning(disable:4312 4244)
78
79 WNDPROC SetWindowProc(HWND hwnd, WNDPROC proc) {
80 // The reason we don't return the SetwindowLongPtr() value is that it returns
81 // the orignal window procedure and not the current one. I don't know if it is
82 // a bug or an intended feature.
83 WNDPROC oldwindow_proc =
84 reinterpret_cast<WNDPROC>(GetWindowLongPtr(hwnd, GWLP_WNDPROC));
85 SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(proc));
86 return oldwindow_proc;
87 }
88
89 void* SetWindowUserData(HWND hwnd, void* user_data) {
90 return
91 reinterpret_cast<void*>(SetWindowLongPtr(hwnd, GWLP_USERDATA,
92 reinterpret_cast<LONG_PTR>(user_data)));
93 }
94
95 void* GetWindowUserData(HWND hwnd) {
96 DWORD process_id = 0;
97 DWORD thread_id = GetWindowThreadProcessId(hwnd, &process_id);
98 // A window outside the current process needs to be ignored.
99 if (process_id != ::GetCurrentProcessId())
100 return NULL;
101 return reinterpret_cast<void*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
102 }
103
104 #pragma warning(pop)
105
106 bool DoesWindowBelongToActiveWindow(HWND window) {
107 DCHECK(window);
108 HWND top_window = ::GetAncestor(window, GA_ROOT);
109 if (!top_window)
110 return false;
111
112 HWND active_top_window = ::GetAncestor(::GetForegroundWindow(), GA_ROOT);
113 return (top_window == active_top_window);
114 }
115
116 void CenterAndSizeWindow(HWND parent,
117 HWND window,
118 const gfx::Size& pref) {
119 DCHECK(window && pref.width() > 0 && pref.height() > 0);
120
121 // Calculate the ideal bounds.
122 RECT window_bounds;
123 RECT center_bounds = {0};
124 if (parent) {
125 // If there is a parent, center over the parents bounds.
126 ::GetWindowRect(parent, &center_bounds);
127 }
128
129 if (::IsRectEmpty(&center_bounds)) {
130 // No parent or no parent rect. Center over the monitor the window is on.
131 HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST);
132 if (monitor) {
133 MONITORINFO mi = {0};
134 mi.cbSize = sizeof(mi);
135 base::win::GetMonitorInfoWrapper(monitor, &mi);
136 center_bounds = mi.rcWork;
137 } else {
138 NOTREACHED() << "Unable to get default monitor";
139 }
140 }
141
142 window_bounds.left = center_bounds.left;
143 if (pref.width() < (center_bounds.right - center_bounds.left)) {
144 window_bounds.left +=
145 (center_bounds.right - center_bounds.left - pref.width()) / 2;
146 }
147 window_bounds.right = window_bounds.left + pref.width();
148
149 window_bounds.top = center_bounds.top;
150 if (pref.height() < (center_bounds.bottom - center_bounds.top)) {
151 window_bounds.top +=
152 (center_bounds.bottom - center_bounds.top - pref.height()) / 2;
153 }
154 window_bounds.bottom = window_bounds.top + pref.height();
155
156 // If we're centering a child window, we are positioning in client
157 // coordinates, and as such we need to offset the target rectangle by the
158 // position of the parent window.
159 if (::GetWindowLong(window, GWL_STYLE) & WS_CHILD) {
160 DCHECK(parent && ::GetParent(window) == parent);
161 POINT topleft = { window_bounds.left, window_bounds.top };
162 ::MapWindowPoints(HWND_DESKTOP, parent, &topleft, 1);
163 window_bounds.left = topleft.x;
164 window_bounds.top = topleft.y;
165 window_bounds.right = window_bounds.left + pref.width();
166 window_bounds.bottom = window_bounds.top + pref.height();
167 }
168
169 AdjustWindowToFit(window, window_bounds, !parent);
170 }
171
172 void CheckWindowCreated(HWND hwnd) {
173 if (!hwnd)
174 LOG_GETLASTERROR(FATAL);
175 }
176
177 void ShowSystemMenu(HWND window) {
178 RECT rect;
179 GetWindowRect(window, &rect);
180 gfx::Point point = gfx::Point(rect.left, rect.top);
181 static const int kSystemMenuOffset = 10;
182 point.Offset(kSystemMenuOffset, kSystemMenuOffset);
183 ShowSystemMenuAtPoint(window, point);
184 }
185
186 void ShowSystemMenuAtPoint(HWND window, const gfx::Point& point) {
187 // In the Metro process, we never want to show the system menu.
188 if (base::win::IsMetroProcess())
189 return;
190 UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD;
191 if (base::i18n::IsRTL())
192 flags |= TPM_RIGHTALIGN;
193 HMENU menu = GetSystemMenu(window, FALSE);
194 const int command =
195 TrackPopupMenu(menu, flags, point.x(), point.y(), 0, window, NULL);
196 if (command)
197 SendMessage(window, WM_SYSCOMMAND, command, 0);
198 }
199
200 extern "C" {
201 typedef HWND (*RootWindow)();
202 }
203
204 HWND GetWindowToParentTo(bool get_real_hwnd) {
205 HMODULE metro = base::win::GetMetroModule();
206 if (!metro)
207 return get_real_hwnd ? ::GetDesktopWindow() : HWND_DESKTOP;
208 // In windows 8 metro-mode the root window is not the desktop.
209 RootWindow root_window =
210 reinterpret_cast<RootWindow>(::GetProcAddress(metro, "GetRootWindow"));
211 return root_window();
212 }
213
214 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/win/hwnd_util.h ('k') | ui/base/win/mouse_wheel_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698