hwnd_util.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/win/hwnd_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h" 87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/metro.h" 103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/win/win_util.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gfx/point.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace gfx { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adjust the window to fit. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AdjustWindowToFit(HWND hwnd, const RECT& bounds, bool fit_to_monitor) { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fit_to_monitor) { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the monitor. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMONITOR hmon = MonitorFromRect(&bounds, MONITOR_DEFAULTTONEAREST); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hmon) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MONITORINFO mi; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mi.cbSize = sizeof(mi); 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::win::GetMonitorInfoWrapper(hmon, &mi); 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Rect window_rect(bounds); 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Rect monitor_rect(mi.rcWork); 30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Rect new_window_rect = window_rect; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_window_rect.AdjustToFit(monitor_rect); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_window_rect != window_rect) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Window doesn't fit on monitor, move and possibly resize. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetWindowPos(hwnd, 0, new_window_rect.x(), new_window_rect.y(), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_window_rect.width(), new_window_rect.height(), 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SWP_NOACTIVATE | SWP_NOZORDER); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Else fall through. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unable to find default monitor"; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fall through. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } // Else fall through. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The window is not being fit to monitor, or the window fits on the monitor 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as is, or we have no monitor info; reset the bounds. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SetWindowPos(hwnd, 0, bounds.left, bounds.top, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds.right - bounds.left, bounds.bottom - bounds.top, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SWP_NOACTIVATE | SWP_NOZORDER); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 GetClassName(HWND window) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetClassNameW will return a truncated result (properly null terminated) if 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the given buffer is not large enough. So, it is not possible to determine 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that we got the entire class name if the result is exactly equal to the 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size of the buffer minus one. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD buffer_size = MAX_PATH; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring output; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD size_ret = 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetClassNameW(window, WriteInto(&output, buffer_size), buffer_size); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size_ret == 0) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size_ret < (buffer_size - 1)) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.resize(size_ret); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return output; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_size *= 2; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::wstring(); // error 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(push) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(disable:4312 4244) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WNDPROC SetWindowProc(HWND hwnd, WNDPROC proc) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The reason we don't return the SetwindowLongPtr() value is that it returns 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the orignal window procedure and not the current one. I don't know if it is 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a bug or an intended feature. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WNDPROC oldwindow_proc = 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<WNDPROC>(GetWindowLongPtr(hwnd, GWLP_WNDPROC)); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(proc)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return oldwindow_proc; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* SetWindowUserData(HWND hwnd, void* user_data) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<void*>(SetWindowLongPtr(hwnd, GWLP_USERDATA, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<LONG_PTR>(user_data))); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* GetWindowUserData(HWND hwnd) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD process_id = 0; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD thread_id = GetWindowThreadProcessId(hwnd, &process_id); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A window outside the current process needs to be ignored. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (process_id != ::GetCurrentProcessId()) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<void*>(GetWindowLongPtr(hwnd, GWLP_USERDATA)); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma warning(pop) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DoesWindowBelongToActiveWindow(HWND window) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(window); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HWND top_window = ::GetAncestor(window, GA_ROOT); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!top_window) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HWND active_top_window = ::GetAncestor(::GetForegroundWindow(), GA_ROOT); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (top_window == active_top_window); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CenterAndSizeWindow(HWND parent, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HWND window, 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const Size& pref) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(window && pref.width() > 0 && pref.height() > 0); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calculate the ideal bounds. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RECT window_bounds; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RECT center_bounds = {0}; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there is a parent, center over the parents bounds. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetWindowRect(parent, ¢er_bounds); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::IsRectEmpty(¢er_bounds)) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No parent or no parent rect. Center over the monitor the window is on. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (monitor) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MONITORINFO mi = {0}; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mi.cbSize = sizeof(mi); 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::win::GetMonitorInfoWrapper(monitor, &mi); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) center_bounds = mi.rcWork; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unable to get default monitor"; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_bounds.left = center_bounds.left; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pref.width() < (center_bounds.right - center_bounds.left)) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_bounds.left += 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (center_bounds.right - center_bounds.left - pref.width()) / 2; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_bounds.right = window_bounds.left + pref.width(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_bounds.top = center_bounds.top; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pref.height() < (center_bounds.bottom - center_bounds.top)) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_bounds.top += 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (center_bounds.bottom - center_bounds.top - pref.height()) / 2; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_bounds.bottom = window_bounds.top + pref.height(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're centering a child window, we are positioning in client 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // coordinates, and as such we need to offset the target rectangle by the 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // position of the parent window. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::GetWindowLong(window, GWL_STYLE) & WS_CHILD) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(parent && ::GetParent(window) == parent); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) POINT topleft = { window_bounds.left, window_bounds.top }; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::MapWindowPoints(HWND_DESKTOP, parent, &topleft, 1); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_bounds.left = topleft.x; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_bounds.top = topleft.y; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_bounds.right = window_bounds.left + pref.width(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_bounds.bottom = window_bounds.top + pref.height(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdjustWindowToFit(window, window_bounds, !parent); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CheckWindowCreated(HWND hwnd) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hwnd) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_GETLASTERROR(FATAL); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShowSystemMenu(HWND window) { 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RECT rect; 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetWindowRect(window, &rect); 180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Point point = Point(rect.left, rect.top); 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static const int kSystemMenuOffset = 10; 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) point.Offset(kSystemMenuOffset, kSystemMenuOffset); 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ShowSystemMenuAtPoint(window, point); 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ShowSystemMenuAtPoint(HWND window, const Point& point) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In the Metro process, we never want to show the system menu. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::win::IsMetroProcess()) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UINT flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::i18n::IsRTL()) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= TPM_RIGHTALIGN; 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HMENU menu = GetSystemMenu(window, FALSE); 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int command = 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TrackPopupMenu(menu, flags, point.x(), point.y(), 0, window, NULL); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendMessage(window, WM_SYSCOMMAND, command, 0); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef HWND (*RootWindow)(); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HWND GetWindowToParentTo(bool get_real_hwnd) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMODULE metro = base::win::GetMetroModule(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!metro) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return get_real_hwnd ? ::GetDesktopWindow() : HWND_DESKTOP; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In windows 8 metro-mode the root window is not the desktop. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RootWindow root_window = 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<RootWindow>(::GetProcAddress(metro, "GetRootWindow")); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return root_window(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} // namespace gfx 215