OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/win/window_impl.h" | 5 #include "ui/gfx/win/window_impl.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 | 8 |
| 9 #include "base/bind.h" |
9 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
10 #include "base/memory/singleton.h" | 11 #include "base/memory/singleton.h" |
11 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
12 #include "base/synchronization/lock.h" | 13 #include "base/synchronization/lock.h" |
13 #include "base/win/wrapped_window_proc.h" | 14 #include "base/win/wrapped_window_proc.h" |
14 #include "ui/gfx/win/hwnd_util.h" | 15 #include "ui/gfx/win/hwnd_util.h" |
15 | 16 |
16 namespace gfx { | 17 namespace gfx { |
17 | 18 |
18 static const DWORD kWindowDefaultChildStyle = | 19 static const DWORD kWindowDefaultChildStyle = |
(...skipping 24 matching lines...) Expand all Loading... |
43 } | 44 } |
44 }; | 45 }; |
45 | 46 |
46 // WARNING: this class may be used on multiple threads. | 47 // WARNING: this class may be used on multiple threads. |
47 class ClassRegistrar { | 48 class ClassRegistrar { |
48 public: | 49 public: |
49 ~ClassRegistrar(); | 50 ~ClassRegistrar(); |
50 | 51 |
51 static ClassRegistrar* GetInstance(); | 52 static ClassRegistrar* GetInstance(); |
52 | 53 |
| 54 void UnregisterClasses(); |
| 55 |
53 // Returns the atom identifying the class matching |class_info|, | 56 // Returns the atom identifying the class matching |class_info|, |
54 // creating and registering a new class if the class is not yet known. | 57 // creating and registering a new class if the class is not yet known. |
55 ATOM RetrieveClassAtom(const ClassInfo& class_info); | 58 ATOM RetrieveClassAtom(const ClassInfo& class_info); |
56 | 59 |
57 private: | 60 private: |
58 // Represents a registered window class. | 61 // Represents a registered window class. |
59 struct RegisteredClass { | 62 struct RegisteredClass { |
60 RegisteredClass(const ClassInfo& info, ATOM atom); | 63 RegisteredClass(const ClassInfo& info, |
| 64 const base::string16& name, |
| 65 ATOM atom, |
| 66 HINSTANCE instance); |
61 | 67 |
62 // Info used to create the class. | 68 // Info used to create the class. |
63 ClassInfo info; | 69 ClassInfo info; |
64 | 70 |
| 71 // The name given to the window class |
| 72 base::string16 name; |
| 73 |
65 // The atom identifying the window class. | 74 // The atom identifying the window class. |
66 ATOM atom; | 75 ATOM atom; |
| 76 |
| 77 // The handle of the module containing the window proceedure. |
| 78 HMODULE instance; |
67 }; | 79 }; |
68 | 80 |
69 ClassRegistrar(); | 81 ClassRegistrar(); |
70 friend struct DefaultSingletonTraits<ClassRegistrar>; | 82 friend struct DefaultSingletonTraits<ClassRegistrar>; |
71 | 83 |
72 typedef std::list<RegisteredClass> RegisteredClasses; | 84 typedef std::list<RegisteredClass> RegisteredClasses; |
73 RegisteredClasses registered_classes_; | 85 RegisteredClasses registered_classes_; |
74 | 86 |
75 // Counter of how many classes have been registered so far. | 87 // Counter of how many classes have been registered so far. |
76 int registered_count_; | 88 int registered_count_; |
77 | 89 |
78 base::Lock lock_; | 90 base::Lock lock_; |
79 | 91 |
80 DISALLOW_COPY_AND_ASSIGN(ClassRegistrar); | 92 DISALLOW_COPY_AND_ASSIGN(ClassRegistrar); |
81 }; | 93 }; |
82 | 94 |
83 ClassRegistrar::~ClassRegistrar() {} | 95 ClassRegistrar::~ClassRegistrar() {} |
84 | 96 |
85 // static | 97 // static |
86 ClassRegistrar* ClassRegistrar::GetInstance() { | 98 ClassRegistrar* ClassRegistrar::GetInstance() { |
87 return Singleton<ClassRegistrar, | 99 return Singleton<ClassRegistrar, |
88 LeakySingletonTraits<ClassRegistrar> >::get(); | 100 LeakySingletonTraits<ClassRegistrar> >::get(); |
| 101 } |
| 102 |
| 103 void ClassRegistrar::UnregisterClasses() { |
| 104 for (RegisteredClasses::iterator i = registered_classes_.begin(); |
| 105 i != registered_classes_.end(); ++i) { |
| 106 if (UnregisterClass(MAKEINTATOM(i->atom), i->instance)) { |
| 107 registered_classes_.erase(i); |
| 108 } else { |
| 109 LOG(ERROR) << "Failed to unregister class " << i->name |
| 110 << ". Error = " << GetLastError(); |
| 111 } |
| 112 } |
89 } | 113 } |
90 | 114 |
91 ATOM ClassRegistrar::RetrieveClassAtom(const ClassInfo& class_info) { | 115 ATOM ClassRegistrar::RetrieveClassAtom(const ClassInfo& class_info) { |
92 base::AutoLock auto_lock(lock_); | 116 base::AutoLock auto_lock(lock_); |
93 for (RegisteredClasses::const_iterator i = registered_classes_.begin(); | 117 for (RegisteredClasses::const_iterator i = registered_classes_.begin(); |
94 i != registered_classes_.end(); ++i) { | 118 i != registered_classes_.end(); ++i) { |
95 if (class_info.Equals(i->info)) | 119 if (class_info.Equals(i->info)) |
96 return i->atom; | 120 return i->atom; |
97 } | 121 } |
98 | 122 |
(...skipping 11 matching lines...) Expand all Loading... |
110 NULL, | 134 NULL, |
111 reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)), | 135 reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)), |
112 NULL, | 136 NULL, |
113 class_info.icon, | 137 class_info.icon, |
114 class_info.icon, | 138 class_info.icon, |
115 &window_class); | 139 &window_class); |
116 HMODULE instance = window_class.hInstance; | 140 HMODULE instance = window_class.hInstance; |
117 ATOM atom = RegisterClassEx(&window_class); | 141 ATOM atom = RegisterClassEx(&window_class); |
118 CHECK(atom) << GetLastError(); | 142 CHECK(atom) << GetLastError(); |
119 | 143 |
120 registered_classes_.push_back(RegisteredClass(class_info, atom)); | 144 registered_classes_.push_back(RegisteredClass( |
| 145 class_info, name, atom, instance)); |
121 | 146 |
122 return atom; | 147 return atom; |
123 } | 148 } |
124 | 149 |
125 ClassRegistrar::RegisteredClass::RegisteredClass(const ClassInfo& info, | 150 ClassRegistrar::RegisteredClass::RegisteredClass(const ClassInfo& info, |
126 ATOM atom) | 151 const base::string16& name, |
| 152 ATOM atom, |
| 153 HMODULE instance) |
127 : info(info), | 154 : info(info), |
128 atom(atom) {} | 155 name(name), |
| 156 atom(atom), |
| 157 instance(instance) {} |
129 | 158 |
130 ClassRegistrar::ClassRegistrar() : registered_count_(0) {} | 159 ClassRegistrar::ClassRegistrar() : registered_count_(0) {} |
131 | 160 |
132 | 161 |
133 /////////////////////////////////////////////////////////////////////////////// | 162 /////////////////////////////////////////////////////////////////////////////// |
134 // WindowImpl, public | 163 // WindowImpl, public |
135 | 164 |
136 WindowImpl::WindowImpl() | 165 WindowImpl::WindowImpl() |
137 : window_style_(0), | 166 : window_style_(0), |
138 window_ex_style_(kWindowDefaultExStyle), | 167 window_ex_style_(kWindowDefaultExStyle), |
139 class_style_(CS_DBLCLKS), | 168 class_style_(CS_DBLCLKS), |
140 hwnd_(NULL), | 169 hwnd_(NULL), |
141 got_create_(false), | 170 got_create_(false), |
142 got_valid_hwnd_(false), | 171 got_valid_hwnd_(false), |
143 destroyed_(NULL) { | 172 destroyed_(NULL) { |
144 } | 173 } |
145 | 174 |
146 WindowImpl::~WindowImpl() { | 175 WindowImpl::~WindowImpl() { |
147 if (destroyed_) | 176 if (destroyed_) |
148 *destroyed_ = true; | 177 *destroyed_ = true; |
149 ClearUserData(); | 178 ClearUserData(); |
150 } | 179 } |
151 | 180 |
| 181 // static |
| 182 void WindowImpl::UnregisterClassesAtExit() { |
| 183 base::AtExitManager::RegisterTask( |
| 184 base::Bind(&ClassRegistrar::UnregisterClasses, |
| 185 base::Unretained(ClassRegistrar::GetInstance()))); |
| 186 } |
| 187 |
152 void WindowImpl::Init(HWND parent, const Rect& bounds) { | 188 void WindowImpl::Init(HWND parent, const Rect& bounds) { |
153 if (window_style_ == 0) | 189 if (window_style_ == 0) |
154 window_style_ = parent ? kWindowDefaultChildStyle : kWindowDefaultStyle; | 190 window_style_ = parent ? kWindowDefaultChildStyle : kWindowDefaultStyle; |
155 | 191 |
156 if (parent == HWND_DESKTOP) { | 192 if (parent == HWND_DESKTOP) { |
157 // Only non-child windows can have HWND_DESKTOP (0) as their parent. | 193 // Only non-child windows can have HWND_DESKTOP (0) as their parent. |
158 CHECK((window_style_ & WS_CHILD) == 0); | 194 CHECK((window_style_ & WS_CHILD) == 0); |
159 parent = GetWindowToParentTo(false); | 195 parent = GetWindowToParentTo(false); |
160 } else if (parent == ::GetDesktopWindow()) { | 196 } else if (parent == ::GetDesktopWindow()) { |
161 // Any type of window can have the "Desktop Window" as their parent. | 197 // Any type of window can have the "Desktop Window" as their parent. |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 return window->OnWndProc(message, w_param, l_param); | 303 return window->OnWndProc(message, w_param, l_param); |
268 } | 304 } |
269 | 305 |
270 ATOM WindowImpl::GetWindowClassAtom() { | 306 ATOM WindowImpl::GetWindowClassAtom() { |
271 HICON icon = GetDefaultWindowIcon(); | 307 HICON icon = GetDefaultWindowIcon(); |
272 ClassInfo class_info(initial_class_style(), icon); | 308 ClassInfo class_info(initial_class_style(), icon); |
273 return ClassRegistrar::GetInstance()->RetrieveClassAtom(class_info); | 309 return ClassRegistrar::GetInstance()->RetrieveClassAtom(class_info); |
274 } | 310 } |
275 | 311 |
276 } // namespace gfx | 312 } // namespace gfx |
OLD | NEW |