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