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/window_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/alias.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h"
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/synchronization/lock.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/wrapped_window_proc.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/win/hwnd_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace gfx {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const DWORD kWindowDefaultChildStyle =
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const DWORD kWindowDefaultStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const DWORD kWindowDefaultExStyle = 0;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WindowImpl class tracking.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Several external scripts rely explicitly on this base class name for
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// acquiring the window handle and will break if this is modified!
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t* const WindowImpl::kBaseClassName = L"Chrome_WidgetWin_";
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WindowImpl class information used for registering unique windows.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ClassInfo {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UINT style;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HICON icon;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClassInfo(int style, HICON icon)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : style(style),
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        icon(icon) {}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Compares two ClassInfos. Returns true if all members match.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Equals(const ClassInfo& other) const {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (other.style == style && other.icon == icon);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// WARNING: this class may be used on multiple threads.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClassRegistrar {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~ClassRegistrar();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static ClassRegistrar* GetInstance();
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the atom identifying the class matching |class_info|,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // creating and registering a new class if the class is not yet known.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ATOM RetrieveClassAtom(const ClassInfo& class_info);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Represents a registered window class.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct RegisteredClass {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RegisteredClass(const ClassInfo& info, ATOM atom);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Info used to create the class.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClassInfo info;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The atom identifying the window class.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ATOM atom;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ClassRegistrar();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct DefaultSingletonTraits<ClassRegistrar>;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::list<RegisteredClass> RegisteredClasses;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisteredClasses registered_classes_;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Counter of how many classes have been registered so far.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int registered_count_;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::Lock lock_;
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ClassRegistrar);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ClassRegistrar::~ClassRegistrar() {}
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ClassRegistrar* ClassRegistrar::GetInstance() {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Singleton<ClassRegistrar,
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   LeakySingletonTraits<ClassRegistrar> >::get();
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ATOM ClassRegistrar::RetrieveClassAtom(const ClassInfo& class_info) {
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::AutoLock auto_lock(lock_);
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (RegisteredClasses::const_iterator i = registered_classes_.begin();
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       i != registered_classes_.end(); ++i) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (class_info.Equals(i->info))
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return i->atom;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // No class found, need to register one.
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 name = base::string16(WindowImpl::kBaseClassName) +
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::IntToString16(registered_count_++);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WNDCLASSEX window_class;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::win::InitializeWindowClass(
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      name.c_str(),
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &base::win::WrappedWindowProc<WindowImpl::WndProc>,
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      class_info.style,
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0,
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      0,
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NULL,
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)),
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NULL,
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      class_info.icon,
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      class_info.icon,
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &window_class);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HMODULE instance = window_class.hInstance;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ATOM atom = RegisterClassEx(&window_class);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(atom) << GetLastError();
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registered_classes_.push_back(RegisteredClass(class_info, atom));
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return atom;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ClassRegistrar::RegisteredClass::RegisteredClass(const ClassInfo& info,
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 ATOM atom)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : info(info),
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      atom(atom) {}
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochClassRegistrar::ClassRegistrar() : registered_count_(0) {}
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WindowImpl, public
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WindowImpl::WindowImpl()
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : window_style_(0),
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_ex_style_(kWindowDefaultExStyle),
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      class_style_(CS_DBLCLKS),
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hwnd_(NULL),
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      got_create_(false),
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      got_valid_hwnd_(false),
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      destroyed_(NULL) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WindowImpl::~WindowImpl() {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (destroyed_)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *destroyed_ = true;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearUserData();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void WindowImpl::Init(HWND parent, const Rect& bounds) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (window_style_ == 0)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_style_ = parent ? kWindowDefaultChildStyle : kWindowDefaultStyle;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parent == HWND_DESKTOP) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only non-child windows can have HWND_DESKTOP (0) as their parent.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK((window_style_ & WS_CHILD) == 0);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parent = GetWindowToParentTo(false);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (parent == ::GetDesktopWindow()) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Any type of window can have the "Desktop Window" as their parent.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parent = GetWindowToParentTo(true);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (parent != HWND_MESSAGE) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(::IsWindow(parent));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int x, y, width, height;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bounds.IsEmpty()) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    x = y = width = height = CW_USEDEFAULT;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    x = bounds.x();
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    y = bounds.y();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    width = bounds.width();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    height = bounds.height();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ATOM atom = GetWindowClassAtom();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool destroyed = false;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  destroyed_ = &destroyed;
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HWND hwnd = CreateWindowEx(window_ex_style_,
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             reinterpret_cast<wchar_t*>(atom), NULL,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             window_style_, x, y, width, height,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             parent, NULL, NULL, this);
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // First nccalcszie (during CreateWindow) for captioned windows is
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // deliberately ignored so force a second one here to get the right
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // non-client set up.
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (hwnd && (window_style_ & WS_CAPTION)) {
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE |
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!hwnd_ && GetLastError() == 0) {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::Alias(&destroyed);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::Alias(&hwnd);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool got_create = got_create_;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::Alias(&got_create);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool got_valid_hwnd = got_valid_hwnd_;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::Alias(&got_valid_hwnd);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WNDCLASSEX class_info;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(&class_info, 0, sizeof(WNDCLASSEX));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    class_info.cbSize = sizeof(WNDCLASSEX);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    BOOL got_class = GetClassInfoEx(GetModuleHandle(NULL),
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    reinterpret_cast<wchar_t*>(atom),
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    &class_info);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::Alias(&got_class);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool procs_match = got_class && class_info.lpfnWndProc ==
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::win::WrappedWindowProc<&WindowImpl::WndProc>;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::Alias(&procs_match);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(false);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!destroyed)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    destroyed_ = NULL;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckWindowCreated(hwnd_);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The window procedure should have set the data for us.
219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  CHECK_EQ(this, GetWindowUserData(hwnd));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HICON WindowImpl::GetDefaultWindowIcon() const {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LRESULT WindowImpl::OnWndProc(UINT message, WPARAM w_param, LPARAM l_param) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LRESULT result = 0;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HWND hwnd = hwnd_;
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (message == WM_NCDESTROY)
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    hwnd_ = NULL;
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handle the message if it's in our message map; otherwise, let the system
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handle it.
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!ProcessWindowMessage(hwnd, message, w_param, l_param, result))
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result = DefWindowProc(hwnd, message, w_param, l_param);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WindowImpl::ClearUserData() {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (::IsWindow(hwnd_))
243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    gfx::SetWindowUserData(hwnd_, NULL);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LRESULT CALLBACK WindowImpl::WndProc(HWND hwnd,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     UINT message,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     WPARAM w_param,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     LPARAM l_param) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message == WM_NCCREATE) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(l_param);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WindowImpl* window = reinterpret_cast<WindowImpl*>(cs->lpCreateParams);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(window);
255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    gfx::SetWindowUserData(hwnd, window);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window->hwnd_ = hwnd;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window->got_create_ = true;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (hwnd)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window->got_valid_hwnd_ = true;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TRUE;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  WindowImpl* window = reinterpret_cast<WindowImpl*>(GetWindowUserData(hwnd));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!window)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window->OnWndProc(message, w_param, l_param);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ATOM WindowImpl::GetWindowClassAtom() {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HICON icon = GetDefaultWindowIcon();
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClassInfo class_info(initial_class_style(), icon);
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ClassRegistrar::GetInstance()->RetrieveClassAtom(class_info);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}  // namespace gfx
277