Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(293)

Side by Side Diff: chrome/views/widget/widget_win.cc

Issue 101004: Ensure Windows window classes are unregistered on shutdown (take 2) (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/process_singleton_win.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 "chrome/views/widget/widget_win.h" 5 #include "chrome/views/widget/widget_win.h"
6 6
7 #include "base/gfx/native_theme.h" 7 #include "base/gfx/native_theme.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "base/win_util.h" 9 #include "base/win_util.h"
10 #include "chrome/app/chrome_dll_resource.h" 10 #include "chrome/app/chrome_dll_resource.h"
(...skipping 24 matching lines...) Expand all
35 35
36 RootView* GetRootViewForHWND(HWND hwnd) { 36 RootView* GetRootViewForHWND(HWND hwnd) {
37 return reinterpret_cast<RootView*>(::GetProp(hwnd, kRootViewWindowProperty)); 37 return reinterpret_cast<RootView*>(::GetProp(hwnd, kRootViewWindowProperty));
38 } 38 }
39 39
40 NativeControlWin* GetNativeControlWinForHWND(HWND hwnd) { 40 NativeControlWin* GetNativeControlWinForHWND(HWND hwnd) {
41 return reinterpret_cast<NativeControlWin*>( 41 return reinterpret_cast<NativeControlWin*>(
42 ::GetProp(hwnd, NativeControlWin::kNativeControlWinKey)); 42 ::GetProp(hwnd, NativeControlWin::kNativeControlWinKey));
43 } 43 }
44 44
45 // Used to locate the WidgetWin issuing the current Create. Only valid for the
46 // life of Create.
47 //
48 // This obviously assumes we only create WidgetWins from the same thread,
49 // which is currently the case.
50 static WidgetWin* instance_issuing_create = NULL;
51
52 /////////////////////////////////////////////////////////////////////////////// 45 ///////////////////////////////////////////////////////////////////////////////
53 // Window class tracking. 46 // Window class tracking.
54 47
55 // static 48 // static
56 const wchar_t* const WidgetWin::kBaseClassName = 49 const wchar_t* const WidgetWin::kBaseClassName =
57 L"Chrome_WidgetWin_"; 50 L"Chrome_WidgetWin_";
58 51
59 // Window class information used for registering unique windows. 52 // Window class information used for registering unique windows.
60 struct ClassInfo { 53 struct ClassInfo {
61 UINT style; 54 UINT style;
62 HBRUSH background; 55 HBRUSH background;
63 56
64 explicit ClassInfo(int style) 57 explicit ClassInfo(int style)
65 : style(style), 58 : style(style),
66 background(NULL) {} 59 background(NULL) {}
67 60
68 // Compares two ClassInfos. Returns true if all members match. 61 // Compares two ClassInfos. Returns true if all members match.
69 bool Equals(const ClassInfo& other) { 62 bool Equals(const ClassInfo& other) const {
70 return (other.style == style && other.background == background); 63 return (other.style == style && other.background == background);
71 } 64 }
72 }; 65 };
73 66
74 // Represents a registered window class. 67 class ClassRegistrar {
75 struct RegisteredClass { 68 public:
76 RegisteredClass(const ClassInfo& info, 69 ~ClassRegistrar() {
77 const std::wstring& name, 70 for (RegisteredClasses::iterator i = registered_classes_.begin();
78 ATOM atom) 71 i != registered_classes_.end(); ++i) {
79 : info(info), 72 UnregisterClass(i->name.c_str(), NULL);
80 name(name), 73 }
81 atom(atom) {
82 } 74 }
83 75
84 // Info used to create the class. 76 // Puts the name for the class matching |class_info| in |class_name|, creating
85 ClassInfo info; 77 // a new name if the class is not yet known.
78 // Returns true if this class was already known, false otherwise.
79 bool RetrieveClassName(const ClassInfo& class_info, std::wstring* name) {
80 for (RegisteredClasses::const_iterator i = registered_classes_.begin();
81 i != registered_classes_.end(); ++i) {
82 if (class_info.Equals(i->info)) {
83 name->assign(i->name);
84 return true;
85 }
86 }
86 87
87 // The name given to the window. 88 name->assign(std::wstring(WidgetWin::kBaseClassName) +
88 std::wstring name; 89 IntToWString(registered_count_++));
90 return false;
91 }
89 92
90 // The ATOM returned from creating the window. 93 void RegisterClass(const ClassInfo& class_info,
91 ATOM atom; 94 const std::wstring& name,
95 ATOM atom) {
96 registered_classes_.push_back(RegisteredClass(class_info, name, atom));
97 }
98
99 private:
100 // Represents a registered window class.
101 struct RegisteredClass {
102 RegisteredClass(const ClassInfo& info,
103 const std::wstring& name,
104 ATOM atom)
105 : info(info),
106 name(name),
107 atom(atom) {
108 }
109
110 // Info used to create the class.
111 ClassInfo info;
112
113 // The name given to the window.
114 std::wstring name;
115
116 // The ATOM returned from creating the window.
117 ATOM atom;
118 };
119
120 ClassRegistrar() : registered_count_(0) { }
121 friend struct DefaultSingletonTraits<ClassRegistrar>;
122
123 typedef std::list<RegisteredClass> RegisteredClasses;
124 RegisteredClasses registered_classes_;
125
126 // Counter of how many classes have ben registered so far.
127 int registered_count_;
128
129 DISALLOW_COPY_AND_ASSIGN(ClassRegistrar);
92 }; 130 };
93 131
94 typedef std::list<RegisteredClass> RegisteredClasses;
95
96 // The list of registered classes.
97 static RegisteredClasses* registered_classes = NULL;
98
99
100 /////////////////////////////////////////////////////////////////////////////// 132 ///////////////////////////////////////////////////////////////////////////////
101 // WidgetWin, public 133 // WidgetWin, public
102 134
103 WidgetWin::WidgetWin() 135 WidgetWin::WidgetWin()
104 : close_widget_factory_(this), 136 : close_widget_factory_(this),
105 active_mouse_tracking_flags_(0), 137 active_mouse_tracking_flags_(0),
106 has_capture_(false), 138 has_capture_(false),
107 current_action_(FA_NONE), 139 current_action_(FA_NONE),
108 window_style_(0), 140 window_style_(0),
109 window_ex_style_(kWindowDefaultExStyle), 141 window_ex_style_(kWindowDefaultExStyle),
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 CPoint window_position = wr.TopLeft(); 880 CPoint window_position = wr.TopLeft();
849 881
850 BLENDFUNCTION blend = {AC_SRC_OVER, 0, layered_alpha_, AC_SRC_ALPHA}; 882 BLENDFUNCTION blend = {AC_SRC_OVER, 0, layered_alpha_, AC_SRC_ALPHA};
851 ::UpdateLayeredWindow( 883 ::UpdateLayeredWindow(
852 hwnd_, NULL, &window_position, &size, dib_dc, &zero_origin, 884 hwnd_, NULL, &window_position, &size, dib_dc, &zero_origin,
853 RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA); 885 RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA);
854 } 886 }
855 } 887 }
856 888
857 std::wstring WidgetWin::GetWindowClassName() { 889 std::wstring WidgetWin::GetWindowClassName() {
858 if (!registered_classes)
859 registered_classes = new RegisteredClasses();
860 ClassInfo class_info(initial_class_style()); 890 ClassInfo class_info(initial_class_style());
861 for (RegisteredClasses::iterator i = registered_classes->begin(); 891 std::wstring name;
862 i != registered_classes->end(); ++i) { 892 if (Singleton<ClassRegistrar>()->RetrieveClassName(class_info, &name))
863 if (class_info.Equals(i->info)) 893 return name;
864 return i->name;
865 }
866 894
867 // No class found, need to register one. 895 // No class found, need to register one.
868 static int registered_count = 0;
869 std::wstring name =
870 std::wstring(kBaseClassName) + IntToWString(registered_count++);
871 WNDCLASSEX class_ex; 896 WNDCLASSEX class_ex;
872 class_ex.cbSize = sizeof(WNDCLASSEX); 897 class_ex.cbSize = sizeof(WNDCLASSEX);
873 class_ex.style = class_info.style; 898 class_ex.style = class_info.style;
874 class_ex.lpfnWndProc = &WidgetWin::WndProc; 899 class_ex.lpfnWndProc = &WidgetWin::WndProc;
875 class_ex.cbClsExtra = 0; 900 class_ex.cbClsExtra = 0;
876 class_ex.cbWndExtra = 0; 901 class_ex.cbWndExtra = 0;
877 class_ex.hInstance = NULL; 902 class_ex.hInstance = NULL;
878 class_ex.hIcon = LoadIcon(GetModuleHandle(L"chrome.dll"), 903 class_ex.hIcon = LoadIcon(GetModuleHandle(L"chrome.dll"),
879 MAKEINTRESOURCE(IDR_MAINFRAME)); 904 MAKEINTRESOURCE(IDR_MAINFRAME));
880 class_ex.hCursor = LoadCursor(NULL, IDC_ARROW); 905 class_ex.hCursor = LoadCursor(NULL, IDC_ARROW);
881 class_ex.hbrBackground = reinterpret_cast<HBRUSH>(class_info.background + 1); 906 class_ex.hbrBackground = reinterpret_cast<HBRUSH>(class_info.background + 1);
882 class_ex.lpszMenuName = NULL; 907 class_ex.lpszMenuName = NULL;
883 class_ex.lpszClassName = name.c_str(); 908 class_ex.lpszClassName = name.c_str();
884 class_ex.hIconSm = class_ex.hIcon; 909 class_ex.hIconSm = class_ex.hIcon;
885 ATOM atom = RegisterClassEx(&class_ex); 910 ATOM atom = RegisterClassEx(&class_ex);
886 DCHECK(atom); 911 DCHECK(atom);
887 RegisteredClass registered_class(class_info, name, atom); 912
888 registered_classes->push_back(registered_class); 913 Singleton<ClassRegistrar>()->RegisterClass(class_info, name, atom);
914
889 return name; 915 return name;
890 } 916 }
891 917
892 // Get the source HWND of the specified message. Depending on the message, the 918 // Get the source HWND of the specified message. Depending on the message, the
893 // source HWND is encoded in either the WPARAM or the LPARAM value. 919 // source HWND is encoded in either the WPARAM or the LPARAM value.
894 HWND GetControlHWNDForMessage(UINT message, WPARAM w_param, LPARAM l_param) { 920 HWND GetControlHWNDForMessage(UINT message, WPARAM w_param, LPARAM l_param) {
895 // Each of the following messages can be sent by a child HWND and must be 921 // Each of the following messages can be sent by a child HWND and must be
896 // forwarded to its associated NativeControlWin for handling. 922 // forwarded to its associated NativeControlWin for handling.
897 switch (message) { 923 switch (message) {
898 case WM_NOTIFY: 924 case WM_NOTIFY:
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 result = DefWindowProc(window, message, w_param, l_param); 988 result = DefWindowProc(window, message, w_param, l_param);
963 if (message == WM_NCDESTROY) { 989 if (message == WM_NCDESTROY) {
964 TRACK_HWND_DESTRUCTION(window); 990 TRACK_HWND_DESTRUCTION(window);
965 widget->hwnd_ = NULL; 991 widget->hwnd_ = NULL;
966 widget->OnFinalMessage(window); 992 widget->OnFinalMessage(window);
967 } 993 }
968 return result; 994 return result;
969 } 995 }
970 996
971 } // namespace views 997 } // namespace views
OLDNEW
« no previous file with comments | « chrome/browser/process_singleton_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698