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, &center_bounds);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (::IsRectEmpty(&center_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