OLD | NEW |
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 "views/widget/widget_win.h" | 5 #include "views/widget/widget_win.h" |
6 | 6 |
7 #include "app/gfx/canvas.h" | 7 #include "app/gfx/canvas.h" |
8 #include "app/gfx/path.h" | 8 #include "app/gfx/path.h" |
9 #include "app/l10n_util_win.h" | 9 #include "app/l10n_util_win.h" |
10 #include "app/win_util.h" | 10 #include "app/win_util.h" |
11 #include "base/gfx/native_theme.h" | 11 #include "base/gfx/native_theme.h" |
12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
13 #include "base/win_util.h" | 13 #include "base/win_util.h" |
14 #include "views/accessibility/view_accessibility.h" | 14 #include "views/accessibility/view_accessibility.h" |
15 #include "views/controls/native_control_win.h" | 15 #include "views/controls/native_control_win.h" |
16 #include "views/focus/focus_util_win.h" | 16 #include "views/focus/focus_util_win.h" |
17 #include "views/views_delegate.h" | 17 #include "views/views_delegate.h" |
18 #include "views/widget/aero_tooltip_manager.h" | 18 #include "views/widget/aero_tooltip_manager.h" |
19 #include "views/widget/default_theme_provider.h" | 19 #include "views/widget/default_theme_provider.h" |
20 #include "views/widget/root_view.h" | 20 #include "views/widget/root_view.h" |
21 #include "views/window/window_win.h" | 21 #include "views/window/window_win.h" |
22 | 22 |
23 namespace views { | 23 namespace views { |
24 | 24 |
25 static const DWORD kWindowDefaultChildStyle = | |
26 WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; | |
27 static const DWORD kWindowDefaultStyle = WS_OVERLAPPEDWINDOW; | |
28 static const DWORD kWindowDefaultExStyle = 0; | |
29 | |
30 // Property used to link the HWND to its RootView. | 25 // Property used to link the HWND to its RootView. |
31 static const wchar_t* const kRootViewWindowProperty = L"__ROOT_VIEW__"; | 26 static const wchar_t* const kRootViewWindowProperty = L"__ROOT_VIEW__"; |
32 | 27 |
33 bool SetRootViewForHWND(HWND hwnd, RootView* root_view) { | 28 bool SetRootViewForHWND(HWND hwnd, RootView* root_view) { |
34 return ::SetProp(hwnd, kRootViewWindowProperty, root_view) ? true : false; | 29 return ::SetProp(hwnd, kRootViewWindowProperty, root_view) ? true : false; |
35 } | 30 } |
36 | 31 |
37 RootView* GetRootViewForHWND(HWND hwnd) { | 32 RootView* GetRootViewForHWND(HWND hwnd) { |
38 return reinterpret_cast<RootView*>(::GetProp(hwnd, kRootViewWindowProperty)); | 33 return reinterpret_cast<RootView*>(::GetProp(hwnd, kRootViewWindowProperty)); |
39 } | 34 } |
40 | 35 |
41 NativeControlWin* GetNativeControlWinForHWND(HWND hwnd) { | 36 NativeControlWin* GetNativeControlWinForHWND(HWND hwnd) { |
42 return reinterpret_cast<NativeControlWin*>( | 37 return reinterpret_cast<NativeControlWin*>( |
43 ::GetProp(hwnd, NativeControlWin::kNativeControlWinKey)); | 38 ::GetProp(hwnd, NativeControlWin::kNativeControlWinKey)); |
44 } | 39 } |
45 | 40 |
46 /////////////////////////////////////////////////////////////////////////////// | 41 /////////////////////////////////////////////////////////////////////////////// |
47 // Window class tracking. | |
48 | |
49 // static | |
50 const wchar_t* const WidgetWin::kBaseClassName = | |
51 L"Chrome_WidgetWin_"; | |
52 | |
53 // Window class information used for registering unique windows. | |
54 struct ClassInfo { | |
55 UINT style; | |
56 HBRUSH background; | |
57 | |
58 explicit ClassInfo(int style) | |
59 : style(style), | |
60 background(NULL) {} | |
61 | |
62 // Compares two ClassInfos. Returns true if all members match. | |
63 bool Equals(const ClassInfo& other) const { | |
64 return (other.style == style && other.background == background); | |
65 } | |
66 }; | |
67 | |
68 class ClassRegistrar { | |
69 public: | |
70 ~ClassRegistrar() { | |
71 for (RegisteredClasses::iterator i = registered_classes_.begin(); | |
72 i != registered_classes_.end(); ++i) { | |
73 UnregisterClass(i->name.c_str(), NULL); | |
74 } | |
75 } | |
76 | |
77 // Puts the name for the class matching |class_info| in |class_name|, creating | |
78 // a new name if the class is not yet known. | |
79 // Returns true if this class was already known, false otherwise. | |
80 bool RetrieveClassName(const ClassInfo& class_info, std::wstring* name) { | |
81 for (RegisteredClasses::const_iterator i = registered_classes_.begin(); | |
82 i != registered_classes_.end(); ++i) { | |
83 if (class_info.Equals(i->info)) { | |
84 name->assign(i->name); | |
85 return true; | |
86 } | |
87 } | |
88 | |
89 name->assign(std::wstring(WidgetWin::kBaseClassName) + | |
90 IntToWString(registered_count_++)); | |
91 return false; | |
92 } | |
93 | |
94 void RegisterClass(const ClassInfo& class_info, | |
95 const std::wstring& name, | |
96 ATOM atom) { | |
97 registered_classes_.push_back(RegisteredClass(class_info, name, atom)); | |
98 } | |
99 | |
100 private: | |
101 // Represents a registered window class. | |
102 struct RegisteredClass { | |
103 RegisteredClass(const ClassInfo& info, | |
104 const std::wstring& name, | |
105 ATOM atom) | |
106 : info(info), | |
107 name(name), | |
108 atom(atom) { | |
109 } | |
110 | |
111 // Info used to create the class. | |
112 ClassInfo info; | |
113 | |
114 // The name given to the window. | |
115 std::wstring name; | |
116 | |
117 // The ATOM returned from creating the window. | |
118 ATOM atom; | |
119 }; | |
120 | |
121 ClassRegistrar() : registered_count_(0) { } | |
122 friend struct DefaultSingletonTraits<ClassRegistrar>; | |
123 | |
124 typedef std::list<RegisteredClass> RegisteredClasses; | |
125 RegisteredClasses registered_classes_; | |
126 | |
127 // Counter of how many classes have ben registered so far. | |
128 int registered_count_; | |
129 | |
130 DISALLOW_COPY_AND_ASSIGN(ClassRegistrar); | |
131 }; | |
132 | |
133 /////////////////////////////////////////////////////////////////////////////// | |
134 // WidgetWin, public | 42 // WidgetWin, public |
135 | 43 |
136 WidgetWin::WidgetWin() | 44 WidgetWin::WidgetWin() |
137 : close_widget_factory_(this), | 45 : close_widget_factory_(this), |
138 active_mouse_tracking_flags_(0), | 46 active_mouse_tracking_flags_(0), |
139 has_capture_(false), | 47 has_capture_(false), |
140 window_style_(0), | |
141 window_ex_style_(kWindowDefaultExStyle), | |
142 use_layered_buffer_(true), | 48 use_layered_buffer_(true), |
143 layered_alpha_(255), | 49 layered_alpha_(255), |
144 delete_on_destroy_(true), | 50 delete_on_destroy_(true), |
145 can_update_layered_window_(true), | 51 can_update_layered_window_(true), |
146 last_mouse_event_was_move_(false), | 52 last_mouse_event_was_move_(false), |
147 is_mouse_down_(false), | 53 is_mouse_down_(false), |
148 is_window_(false), | 54 is_window_(false) { |
149 class_style_(CS_DBLCLKS), | |
150 hwnd_(NULL) { | |
151 } | 55 } |
152 | 56 |
153 WidgetWin::~WidgetWin() { | 57 WidgetWin::~WidgetWin() { |
154 MessageLoopForUI::current()->RemoveObserver(this); | 58 MessageLoopForUI::current()->RemoveObserver(this); |
155 } | 59 } |
156 | 60 |
157 /////////////////////////////////////////////////////////////////////////////// | 61 /////////////////////////////////////////////////////////////////////////////// |
158 // Widget implementation: | 62 // Widget implementation: |
159 | 63 |
160 void WidgetWin::Init(gfx::NativeView parent, const gfx::Rect& bounds) { | 64 void WidgetWin::Init(gfx::NativeView parent, const gfx::Rect& bounds) { |
161 if (window_style_ == 0) | 65 // Force creation of the RootView; otherwise, we may get a WM_SIZE after the |
162 window_style_ = parent ? kWindowDefaultChildStyle : kWindowDefaultStyle; | 66 // window is created and before the root view is set up. |
| 67 GetRootView(); |
| 68 |
| 69 // Create the window. |
| 70 WindowImpl::Init(parent, bounds); |
163 | 71 |
164 // See if the style has been overridden. | 72 // See if the style has been overridden. |
165 opaque_ = !(window_ex_style_ & WS_EX_TRANSPARENT); | 73 opaque_ = !(window_ex_style() & WS_EX_TRANSPARENT); |
166 use_layered_buffer_ = (use_layered_buffer_ && | 74 use_layered_buffer_ = (use_layered_buffer_ && |
167 !!(window_ex_style_ & WS_EX_LAYERED)); | 75 !!(window_ex_style() & WS_EX_LAYERED)); |
168 | |
169 // Force creation of the RootView if it hasn't been created yet. | |
170 GetRootView(); | |
171 | 76 |
172 default_theme_provider_.reset(new DefaultThemeProvider()); | 77 default_theme_provider_.reset(new DefaultThemeProvider()); |
173 | 78 |
174 // Ensures the parent we have been passed is valid, otherwise CreateWindowEx | 79 SetWindowSupportsRerouteMouseWheel(GetNativeView()); |
175 // will fail. | |
176 if (parent && !::IsWindow(parent)) { | |
177 NOTREACHED() << "invalid parent window specified."; | |
178 parent = NULL; | |
179 } | |
180 | |
181 hwnd_ = CreateWindowEx(window_ex_style_, GetWindowClassName().c_str(), L"", | |
182 window_style_, bounds.x(), bounds.y(), bounds.width(), | |
183 bounds.height(), parent, NULL, NULL, this); | |
184 DCHECK(hwnd_); | |
185 SetWindowSupportsRerouteMouseWheel(hwnd_); | |
186 | |
187 // The window procedure should have set the data for us. | |
188 DCHECK(win_util::GetWindowUserData(hwnd_) == this); | |
189 | 80 |
190 root_view_->OnWidgetCreated(); | 81 root_view_->OnWidgetCreated(); |
191 | 82 |
192 if ((window_style_ & WS_CHILD) == 0) { | 83 if ((window_style() & WS_CHILD) == 0) { |
193 // Top-level widgets get a FocusManager. | 84 // Top-level widgets get a FocusManager. |
194 focus_manager_.reset(new FocusManager(this)); | 85 focus_manager_.reset(new FocusManager(this)); |
195 } | 86 } |
196 | 87 |
197 // Sets the RootView as a property, so the automation can introspect windows. | 88 // Sets the RootView as a property, so the automation can introspect windows. |
198 SetRootViewForHWND(hwnd_, root_view_.get()); | 89 SetRootViewForHWND(GetNativeView(), root_view_.get()); |
199 | 90 |
200 MessageLoopForUI::current()->AddObserver(this); | 91 MessageLoopForUI::current()->AddObserver(this); |
201 | 92 |
202 // Windows special DWM window frame requires a special tooltip manager so | 93 // Windows special DWM window frame requires a special tooltip manager so |
203 // that window controls in Chrome windows don't flicker when you move your | 94 // that window controls in Chrome windows don't flicker when you move your |
204 // mouse over them. See comment in aero_tooltip_manager.h. | 95 // mouse over them. See comment in aero_tooltip_manager.h. |
205 if (GetThemeProvider()->ShouldUseNativeFrame()) { | 96 if (GetThemeProvider()->ShouldUseNativeFrame()) { |
206 tooltip_manager_.reset(new AeroTooltipManager(this)); | 97 tooltip_manager_.reset(new AeroTooltipManager(this)); |
207 } else { | 98 } else { |
208 tooltip_manager_.reset(new TooltipManagerWin(this)); | 99 tooltip_manager_.reset(new TooltipManagerWin(this)); |
(...skipping 18 matching lines...) Expand all Loading... |
227 void WidgetWin::GetBounds(gfx::Rect* out, bool including_frame) const { | 118 void WidgetWin::GetBounds(gfx::Rect* out, bool including_frame) const { |
228 CRect crect; | 119 CRect crect; |
229 if (including_frame) { | 120 if (including_frame) { |
230 GetWindowRect(&crect); | 121 GetWindowRect(&crect); |
231 *out = gfx::Rect(crect); | 122 *out = gfx::Rect(crect); |
232 return; | 123 return; |
233 } | 124 } |
234 | 125 |
235 GetClientRect(&crect); | 126 GetClientRect(&crect); |
236 POINT p = {0, 0}; | 127 POINT p = {0, 0}; |
237 ::ClientToScreen(hwnd_, &p); | 128 ::ClientToScreen(GetNativeView(), &p); |
238 out->SetRect(crect.left + p.x, crect.top + p.y, | 129 out->SetRect(crect.left + p.x, crect.top + p.y, |
239 crect.Width(), crect.Height()); | 130 crect.Width(), crect.Height()); |
240 } | 131 } |
241 | 132 |
242 void WidgetWin::SetBounds(const gfx::Rect& bounds) { | 133 void WidgetWin::SetBounds(const gfx::Rect& bounds) { |
243 SetWindowPos(NULL, bounds.x(), bounds.y(), bounds.width(), bounds.height(), | 134 SetWindowPos(NULL, bounds.x(), bounds.y(), bounds.width(), bounds.height(), |
244 SWP_NOACTIVATE | SWP_NOZORDER); | 135 SWP_NOACTIVATE | SWP_NOZORDER); |
245 } | 136 } |
246 | 137 |
247 void WidgetWin::SetShape(const gfx::Path& shape) { | 138 void WidgetWin::SetShape(const gfx::Path& shape) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 // ShowWindow(SW_HIDE) will automatically activate another window). This | 177 // ShowWindow(SW_HIDE) will automatically activate another window). This |
287 // code can be called while a window is being deactivated, and activating | 178 // code can be called while a window is being deactivated, and activating |
288 // another window will screw up the activation that is already in progress. | 179 // another window will screw up the activation that is already in progress. |
289 SetWindowPos(NULL, 0, 0, 0, 0, | 180 SetWindowPos(NULL, 0, 0, 0, 0, |
290 SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | | 181 SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | |
291 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER); | 182 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER); |
292 } | 183 } |
293 } | 184 } |
294 | 185 |
295 gfx::NativeView WidgetWin::GetNativeView() const { | 186 gfx::NativeView WidgetWin::GetNativeView() const { |
296 return hwnd_; | 187 return WindowImpl::GetNativeView(); |
297 } | 188 } |
298 | 189 |
299 static BOOL CALLBACK EnumChildProcForRedraw(HWND hwnd, LPARAM lparam) { | 190 static BOOL CALLBACK EnumChildProcForRedraw(HWND hwnd, LPARAM lparam) { |
300 DWORD process_id; | 191 DWORD process_id; |
301 GetWindowThreadProcessId(hwnd, &process_id); | 192 GetWindowThreadProcessId(hwnd, &process_id); |
302 gfx::Rect invalid_rect = *reinterpret_cast<gfx::Rect*>(lparam); | 193 gfx::Rect invalid_rect = *reinterpret_cast<gfx::Rect*>(lparam); |
303 | 194 |
304 RECT window_rect; | 195 RECT window_rect; |
305 GetWindowRect(hwnd, &window_rect); | 196 GetWindowRect(hwnd, &window_rect); |
306 invalid_rect.Offset(-window_rect.left, -window_rect.top); | 197 invalid_rect.Offset(-window_rect.left, -window_rect.top); |
307 | 198 |
308 int flags = RDW_INVALIDATE | RDW_NOCHILDREN | RDW_FRAME; | 199 int flags = RDW_INVALIDATE | RDW_NOCHILDREN | RDW_FRAME; |
309 if (process_id == GetCurrentProcessId()) | 200 if (process_id == GetCurrentProcessId()) |
310 flags |= RDW_UPDATENOW; | 201 flags |= RDW_UPDATENOW; |
311 RedrawWindow(hwnd, &invalid_rect.ToRECT(), NULL, flags); | 202 RedrawWindow(hwnd, &invalid_rect.ToRECT(), NULL, flags); |
312 return TRUE; | 203 return TRUE; |
313 } | 204 } |
314 | 205 |
315 void WidgetWin::PaintNow(const gfx::Rect& update_rect) { | 206 void WidgetWin::PaintNow(const gfx::Rect& update_rect) { |
316 if (use_layered_buffer_) { | 207 if (use_layered_buffer_) { |
317 PaintLayeredWindow(); | 208 PaintLayeredWindow(); |
318 } else if (root_view_->NeedsPainting(false) && IsWindow()) { | 209 } else if (root_view_->NeedsPainting(false) && IsWindow()) { |
319 if (!opaque_ && GetParent()) { | 210 if (!opaque_ && GetParent()) { |
320 // We're transparent. Need to force painting to occur from our parent. | 211 // We're transparent. Need to force painting to occur from our parent. |
321 CRect parent_update_rect = update_rect.ToRECT(); | 212 CRect parent_update_rect = update_rect.ToRECT(); |
322 POINT location_in_parent = { 0, 0 }; | 213 POINT location_in_parent = { 0, 0 }; |
323 ClientToScreen(hwnd_, &location_in_parent); | 214 ClientToScreen(GetNativeView(), &location_in_parent); |
324 ::ScreenToClient(GetParent(), &location_in_parent); | 215 ::ScreenToClient(GetParent(), &location_in_parent); |
325 parent_update_rect.OffsetRect(location_in_parent); | 216 parent_update_rect.OffsetRect(location_in_parent); |
326 ::RedrawWindow(GetParent(), parent_update_rect, NULL, | 217 ::RedrawWindow(GetParent(), parent_update_rect, NULL, |
327 RDW_UPDATENOW | RDW_INVALIDATE | RDW_ALLCHILDREN); | 218 RDW_UPDATENOW | RDW_INVALIDATE | RDW_ALLCHILDREN); |
328 } else { | 219 } else { |
329 // Paint child windows that are in a different process asynchronously. | 220 // Paint child windows that are in a different process asynchronously. |
330 // This prevents a hang in other processes from blocking this process. | 221 // This prevents a hang in other processes from blocking this process. |
331 | 222 |
332 // Calculate the invalid rect in screen coordinates before the first | 223 // Calculate the invalid rect in screen coordinates before the first |
333 // RedrawWindow call to the parent HWND, since that will empty update_rect | 224 // RedrawWindow call to the parent HWND, since that will empty update_rect |
334 // (which comes from a member variable) in the OnPaint call. | 225 // (which comes from a member variable) in the OnPaint call. |
335 CRect screen_rect_temp; | 226 CRect screen_rect_temp; |
336 GetWindowRect(&screen_rect_temp); | 227 GetWindowRect(&screen_rect_temp); |
337 gfx::Rect screen_rect(screen_rect_temp); | 228 gfx::Rect screen_rect(screen_rect_temp); |
338 gfx::Rect invalid_screen_rect = update_rect; | 229 gfx::Rect invalid_screen_rect = update_rect; |
339 invalid_screen_rect.Offset(screen_rect.x(), screen_rect.y()); | 230 invalid_screen_rect.Offset(screen_rect.x(), screen_rect.y()); |
340 | 231 |
341 ::RedrawWindow(hwnd_, &update_rect.ToRECT(), NULL, | 232 ::RedrawWindow(GetNativeView(), &update_rect.ToRECT(), NULL, |
342 RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN); | 233 RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN); |
343 | 234 |
344 LPARAM lparam = reinterpret_cast<LPARAM>(&invalid_screen_rect); | 235 LPARAM lparam = reinterpret_cast<LPARAM>(&invalid_screen_rect); |
345 EnumChildWindows(hwnd_, EnumChildProcForRedraw, lparam); | 236 EnumChildWindows(GetNativeView(), EnumChildProcForRedraw, lparam); |
346 } | 237 } |
347 // As we were created with a style of WS_CLIPCHILDREN redraw requests may | 238 // As we were created with a style of WS_CLIPCHILDREN redraw requests may |
348 // result in an empty paint rect in WM_PAINT (this'll happen if a | 239 // result in an empty paint rect in WM_PAINT (this'll happen if a |
349 // child HWND completely contains the update _rect). In such a scenario | 240 // child HWND completely contains the update _rect). In such a scenario |
350 // RootView would never get a ProcessPaint and always think it needs to | 241 // RootView would never get a ProcessPaint and always think it needs to |
351 // be painted (leading to a steady stream of RedrawWindow requests on every | 242 // be painted (leading to a steady stream of RedrawWindow requests on every |
352 // event). For this reason we tell RootView it doesn't need to paint | 243 // event). For this reason we tell RootView it doesn't need to paint |
353 // here. | 244 // here. |
354 root_view_->ClearPaintRect(); | 245 root_view_->ClearPaintRect(); |
355 } | 246 } |
356 } | 247 } |
357 | 248 |
358 void WidgetWin::SetOpacity(unsigned char opacity) { | 249 void WidgetWin::SetOpacity(unsigned char opacity) { |
359 layered_alpha_ = static_cast<BYTE>(opacity); | 250 layered_alpha_ = static_cast<BYTE>(opacity); |
360 } | 251 } |
361 | 252 |
362 RootView* WidgetWin::GetRootView() { | 253 RootView* WidgetWin::GetRootView() { |
363 if (!root_view_.get()) { | 254 if (!root_view_.get()) { |
364 // First time the root view is being asked for, create it now. | 255 // First time the root view is being asked for, create it now. |
365 root_view_.reset(CreateRootView()); | 256 root_view_.reset(CreateRootView()); |
366 } | 257 } |
367 return root_view_.get(); | 258 return root_view_.get(); |
368 } | 259 } |
369 | 260 |
370 Widget* WidgetWin::GetRootWidget() const { | 261 Widget* WidgetWin::GetRootWidget() const { |
371 return reinterpret_cast<WidgetWin*>( | 262 return reinterpret_cast<WidgetWin*>( |
372 win_util::GetWindowUserData(GetAncestor(hwnd_, GA_ROOT))); | 263 win_util::GetWindowUserData(GetAncestor(GetNativeView(), GA_ROOT))); |
373 } | 264 } |
374 | 265 |
375 bool WidgetWin::IsVisible() const { | 266 bool WidgetWin::IsVisible() const { |
376 return !!::IsWindowVisible(GetNativeView()); | 267 return !!::IsWindowVisible(GetNativeView()); |
377 } | 268 } |
378 | 269 |
379 bool WidgetWin::IsActive() const { | 270 bool WidgetWin::IsActive() const { |
380 return win_util::IsWindowActive(GetNativeView()); | 271 return win_util::IsWindowActive(GetNativeView()); |
381 } | 272 } |
382 | 273 |
(...skipping 19 matching lines...) Expand all Loading... |
402 return provider; | 293 return provider; |
403 | 294 |
404 provider = widget->GetDefaultThemeProvider(); | 295 provider = widget->GetDefaultThemeProvider(); |
405 if (provider) | 296 if (provider) |
406 return provider; | 297 return provider; |
407 } | 298 } |
408 return default_theme_provider_.get(); | 299 return default_theme_provider_.get(); |
409 } | 300 } |
410 | 301 |
411 Window* WidgetWin::GetWindow() { | 302 Window* WidgetWin::GetWindow() { |
412 return GetWindowImpl(hwnd_); | 303 return GetWindowImpl(GetNativeView()); |
413 } | 304 } |
414 | 305 |
415 const Window* WidgetWin::GetWindow() const { | 306 const Window* WidgetWin::GetWindow() const { |
416 return GetWindowImpl(hwnd_); | 307 return GetWindowImpl(GetNativeView()); |
417 } | 308 } |
418 | 309 |
419 FocusManager* WidgetWin::GetFocusManager() { | 310 FocusManager* WidgetWin::GetFocusManager() { |
420 if (focus_manager_.get()) | 311 if (focus_manager_.get()) |
421 return focus_manager_.get(); | 312 return focus_manager_.get(); |
422 | 313 |
423 WidgetWin* widget = static_cast<WidgetWin*>(GetRootWidget()); | 314 WidgetWin* widget = static_cast<WidgetWin*>(GetRootWidget()); |
424 if (widget && widget != this) { | 315 if (widget && widget != this) { |
425 // WidgetWin subclasses may override GetFocusManager(), for example for | 316 // WidgetWin subclasses may override GetFocusManager(), for example for |
426 // dealing with cases where the widget has been unparented. | 317 // dealing with cases where the widget has been unparented. |
427 return widget->GetFocusManager(); | 318 return widget->GetFocusManager(); |
428 } | 319 } |
429 return NULL; | 320 return NULL; |
430 } | 321 } |
431 | 322 |
432 void WidgetWin::SetUseLayeredBuffer(bool use_layered_buffer) { | 323 void WidgetWin::SetUseLayeredBuffer(bool use_layered_buffer) { |
433 if (use_layered_buffer_ == use_layered_buffer) | 324 if (use_layered_buffer_ == use_layered_buffer) |
434 return; | 325 return; |
435 | 326 |
436 use_layered_buffer_ = use_layered_buffer; | 327 use_layered_buffer_ = use_layered_buffer; |
437 if (!hwnd_) | 328 if (!GetNativeView()) |
438 return; | 329 return; |
439 | 330 |
440 if (use_layered_buffer_) { | 331 if (use_layered_buffer_) { |
441 // Force creation of the buffer at the right size. | 332 // Force creation of the buffer at the right size. |
442 RECT wr; | 333 RECT wr; |
443 GetWindowRect(&wr); | 334 GetWindowRect(&wr); |
444 ChangeSize(0, CSize(wr.right - wr.left, wr.bottom - wr.top)); | 335 ChangeSize(0, CSize(wr.right - wr.left, wr.bottom - wr.top)); |
445 } else { | 336 } else { |
446 contents_.reset(NULL); | 337 contents_.reset(NULL); |
447 } | 338 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 } | 427 } |
537 } | 428 } |
538 | 429 |
539 void WidgetWin::OnClose() { | 430 void WidgetWin::OnClose() { |
540 Close(); | 431 Close(); |
541 } | 432 } |
542 | 433 |
543 void WidgetWin::OnDestroy() { | 434 void WidgetWin::OnDestroy() { |
544 root_view_->OnWidgetDestroyed(); | 435 root_view_->OnWidgetDestroyed(); |
545 | 436 |
546 RemoveProp(hwnd_, kRootViewWindowProperty); | 437 RemoveProp(GetNativeView(), kRootViewWindowProperty); |
547 } | 438 } |
548 | 439 |
549 LRESULT WidgetWin::OnEraseBkgnd(HDC dc) { | 440 LRESULT WidgetWin::OnEraseBkgnd(HDC dc) { |
550 // This is needed for magical win32 flicker ju-ju | 441 // This is needed for magical win32 flicker ju-ju |
551 return 1; | 442 return 1; |
552 } | 443 } |
553 | 444 |
554 LRESULT WidgetWin::OnGetObject(UINT uMsg, WPARAM w_param, LPARAM l_param) { | 445 LRESULT WidgetWin::OnGetObject(UINT uMsg, WPARAM w_param, LPARAM l_param) { |
555 LRESULT reference_result = static_cast<LRESULT>(0L); | 446 LRESULT reference_result = static_cast<LRESULT>(0L); |
556 | 447 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 LRESULT WidgetWin::OnMouseLeave(UINT message, WPARAM w_param, LPARAM l_param) { | 531 LRESULT WidgetWin::OnMouseLeave(UINT message, WPARAM w_param, LPARAM l_param) { |
641 tooltip_manager_->OnMouseLeave(); | 532 tooltip_manager_->OnMouseLeave(); |
642 ProcessMouseExited(); | 533 ProcessMouseExited(); |
643 return 0; | 534 return 0; |
644 } | 535 } |
645 | 536 |
646 LRESULT WidgetWin::OnMouseWheel(UINT message, WPARAM w_param, LPARAM l_param) { | 537 LRESULT WidgetWin::OnMouseWheel(UINT message, WPARAM w_param, LPARAM l_param) { |
647 // Reroute the mouse-wheel to the window under the mouse pointer if | 538 // Reroute the mouse-wheel to the window under the mouse pointer if |
648 // applicable. | 539 // applicable. |
649 if (message == WM_MOUSEWHEEL && | 540 if (message == WM_MOUSEWHEEL && |
650 views::RerouteMouseWheel(hwnd_, w_param, l_param)) { | 541 views::RerouteMouseWheel(GetNativeView(), w_param, l_param)) { |
651 return 0; | 542 return 0; |
652 } | 543 } |
653 | 544 |
654 int flags = GET_KEYSTATE_WPARAM(w_param); | 545 int flags = GET_KEYSTATE_WPARAM(w_param); |
655 short distance = GET_WHEEL_DELTA_WPARAM(w_param); | 546 short distance = GET_WHEEL_DELTA_WPARAM(w_param); |
656 int x = GET_X_LPARAM(l_param); | 547 int x = GET_X_LPARAM(l_param); |
657 int y = GET_Y_LPARAM(l_param); | 548 int y = GET_Y_LPARAM(l_param); |
658 MouseWheelEvent e(distance, x, y, Event::ConvertWindowsFlags(flags)); | 549 MouseWheelEvent e(distance, x, y, Event::ConvertWindowsFlags(flags)); |
659 return root_view_->ProcessMouseWheelEvent(e) ? 0 : 1; | 550 return root_view_->ProcessMouseWheelEvent(e) ? 0 : 1; |
660 } | 551 } |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 DCHECK(use_layered_buffer_); | 832 DCHECK(use_layered_buffer_); |
942 if (can_update_layered_window_) { | 833 if (can_update_layered_window_) { |
943 CRect wr; | 834 CRect wr; |
944 GetWindowRect(&wr); | 835 GetWindowRect(&wr); |
945 CSize size(wr.right - wr.left, wr.bottom - wr.top); | 836 CSize size(wr.right - wr.left, wr.bottom - wr.top); |
946 CPoint zero_origin(0, 0); | 837 CPoint zero_origin(0, 0); |
947 CPoint window_position = wr.TopLeft(); | 838 CPoint window_position = wr.TopLeft(); |
948 | 839 |
949 BLENDFUNCTION blend = {AC_SRC_OVER, 0, layered_alpha_, AC_SRC_ALPHA}; | 840 BLENDFUNCTION blend = {AC_SRC_OVER, 0, layered_alpha_, AC_SRC_ALPHA}; |
950 ::UpdateLayeredWindow( | 841 ::UpdateLayeredWindow( |
951 hwnd_, NULL, &window_position, &size, dib_dc, &zero_origin, | 842 GetNativeView(), NULL, &window_position, &size, dib_dc, &zero_origin, |
952 RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA); | 843 RGB(0xFF, 0xFF, 0xFF), &blend, ULW_ALPHA); |
953 } | 844 } |
954 } | 845 } |
955 | 846 |
956 std::wstring WidgetWin::GetWindowClassName() { | |
957 ClassInfo class_info(initial_class_style()); | |
958 std::wstring name; | |
959 if (Singleton<ClassRegistrar>()->RetrieveClassName(class_info, &name)) | |
960 return name; | |
961 | |
962 // No class found, need to register one. | |
963 WNDCLASSEX class_ex; | |
964 class_ex.cbSize = sizeof(WNDCLASSEX); | |
965 class_ex.style = class_info.style; | |
966 class_ex.lpfnWndProc = &WidgetWin::WndProc; | |
967 class_ex.cbClsExtra = 0; | |
968 class_ex.cbWndExtra = 0; | |
969 class_ex.hInstance = NULL; | |
970 class_ex.hIcon = NULL; | |
971 if (ViewsDelegate::views_delegate) | |
972 class_ex.hIcon = ViewsDelegate::views_delegate->GetDefaultWindowIcon(); | |
973 class_ex.hCursor = LoadCursor(NULL, IDC_ARROW); | |
974 class_ex.hbrBackground = reinterpret_cast<HBRUSH>(class_info.background + 1); | |
975 class_ex.lpszMenuName = NULL; | |
976 class_ex.lpszClassName = name.c_str(); | |
977 class_ex.hIconSm = class_ex.hIcon; | |
978 ATOM atom = RegisterClassEx(&class_ex); | |
979 DCHECK(atom); | |
980 | |
981 Singleton<ClassRegistrar>()->RegisterClass(class_info, name, atom); | |
982 | |
983 return name; | |
984 } | |
985 | |
986 // Get the source HWND of the specified message. Depending on the message, the | 847 // Get the source HWND of the specified message. Depending on the message, the |
987 // source HWND is encoded in either the WPARAM or the LPARAM value. | 848 // source HWND is encoded in either the WPARAM or the LPARAM value. |
988 HWND GetControlHWNDForMessage(UINT message, WPARAM w_param, LPARAM l_param) { | 849 HWND GetControlHWNDForMessage(UINT message, WPARAM w_param, LPARAM l_param) { |
989 // Each of the following messages can be sent by a child HWND and must be | 850 // Each of the following messages can be sent by a child HWND and must be |
990 // forwarded to its associated NativeControlWin for handling. | 851 // forwarded to its associated NativeControlWin for handling. |
991 switch (message) { | 852 switch (message) { |
992 case WM_NOTIFY: | 853 case WM_NOTIFY: |
993 return reinterpret_cast<NMHDR*>(l_param)->hwndFrom; | 854 return reinterpret_cast<NMHDR*>(l_param)->hwndFrom; |
994 case WM_COMMAND: | 855 case WM_COMMAND: |
995 return reinterpret_cast<HWND>(l_param); | 856 return reinterpret_cast<HWND>(l_param); |
996 case WM_CONTEXTMENU: | 857 case WM_CONTEXTMENU: |
997 return reinterpret_cast<HWND>(w_param); | 858 return reinterpret_cast<HWND>(w_param); |
998 case WM_CTLCOLORBTN: | 859 case WM_CTLCOLORBTN: |
999 case WM_CTLCOLORSTATIC: | 860 case WM_CTLCOLORSTATIC: |
1000 return reinterpret_cast<HWND>(l_param); | 861 return reinterpret_cast<HWND>(l_param); |
1001 } | 862 } |
1002 return NULL; | 863 return NULL; |
1003 } | 864 } |
1004 | 865 |
| 866 HICON WidgetWin::GetDefaultWindowIcon() const { |
| 867 if (ViewsDelegate::views_delegate) |
| 868 return ViewsDelegate::views_delegate->GetDefaultWindowIcon(); |
| 869 return NULL; |
| 870 } |
| 871 |
1005 // Some messages may be sent to us by a child HWND managed by | 872 // Some messages may be sent to us by a child HWND managed by |
1006 // NativeControlWin. If this is the case, this function will forward those | 873 // NativeControlWin. If this is the case, this function will forward those |
1007 // messages on to the object associated with the source HWND and return true, | 874 // messages on to the object associated with the source HWND and return true, |
1008 // in which case the window procedure must not do any further processing of | 875 // in which case the window procedure must not do any further processing of |
1009 // the message. If there is no associated NativeControlWin, the return value | 876 // the message. If there is no associated NativeControlWin, the return value |
1010 // will be false and the WndProc can continue processing the message normally. | 877 // will be false and the WndProc can continue processing the message normally. |
1011 // |l_result| contains the result of the message processing by the control and | 878 // |l_result| contains the result of the message processing by the control and |
1012 // must be returned by the WndProc if the return value is true. | 879 // must be returned by the WndProc if the return value is true. |
1013 bool ProcessNativeControlMessage(UINT message, | 880 bool ProcessNativeControlMessage(UINT message, |
1014 WPARAM w_param, | 881 WPARAM w_param, |
1015 LPARAM l_param, | 882 LPARAM l_param, |
1016 LRESULT* l_result) { | 883 LRESULT* l_result) { |
1017 *l_result = 0; | 884 *l_result = 0; |
1018 | 885 |
1019 HWND control_hwnd = GetControlHWNDForMessage(message, w_param, l_param); | 886 HWND control_hwnd = GetControlHWNDForMessage(message, w_param, l_param); |
1020 if (IsWindow(control_hwnd)) { | 887 if (IsWindow(control_hwnd)) { |
1021 NativeControlWin* wrapper = GetNativeControlWinForHWND(control_hwnd); | 888 NativeControlWin* wrapper = GetNativeControlWinForHWND(control_hwnd); |
1022 if (wrapper) | 889 if (wrapper) |
1023 return wrapper->ProcessMessage(message, w_param, l_param, l_result); | 890 return wrapper->ProcessMessage(message, w_param, l_param, l_result); |
1024 } | 891 } |
1025 | 892 |
1026 return false; | 893 return false; |
1027 } | 894 } |
1028 | 895 |
1029 // static | 896 LRESULT WidgetWin::OnWndProc(UINT message, WPARAM w_param, LPARAM l_param) { |
1030 LRESULT CALLBACK WidgetWin::WndProc(HWND window, UINT message, | 897 HWND window = GetNativeView(); |
1031 WPARAM w_param, LPARAM l_param) { | |
1032 if (message == WM_NCCREATE) { | |
1033 CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(l_param); | |
1034 WidgetWin* widget = reinterpret_cast<WidgetWin*>(cs->lpCreateParams); | |
1035 DCHECK(widget); | |
1036 win_util::SetWindowUserData(window, widget); | |
1037 widget->hwnd_ = window; | |
1038 return TRUE; | |
1039 } | |
1040 | |
1041 WidgetWin* widget = reinterpret_cast<WidgetWin*>( | |
1042 win_util::GetWindowUserData(window)); | |
1043 if (!widget) | |
1044 return 0; | |
1045 | |
1046 LRESULT result = 0; | 898 LRESULT result = 0; |
1047 | 899 |
1048 // First allow messages sent by child controls to be processed directly by | 900 // First allow messages sent by child controls to be processed directly by |
1049 // their associated views. If such a view is present, it will handle the | 901 // their associated views. If such a view is present, it will handle the |
1050 // message *instead of* this WidgetWin. | 902 // message *instead of* this WidgetWin. |
1051 if (ProcessNativeControlMessage(message, w_param, l_param, &result)) | 903 if (ProcessNativeControlMessage(message, w_param, l_param, &result)) |
1052 return result; | 904 return result; |
1053 | 905 |
1054 // Otherwise we handle everything else. | 906 // Otherwise we handle everything else. |
1055 if (!widget->ProcessWindowMessage(window, message, w_param, l_param, result)) | 907 if (!ProcessWindowMessage(window, message, w_param, l_param, result)) |
1056 result = DefWindowProc(window, message, w_param, l_param); | 908 result = DefWindowProc(window, message, w_param, l_param); |
1057 if (message == WM_NCDESTROY) | 909 if (message == WM_NCDESTROY) |
1058 widget->OnFinalMessage(window); | 910 OnFinalMessage(window); |
1059 if (message == WM_ACTIVATE) | 911 if (message == WM_ACTIVATE) |
1060 PostProcessActivateMessage(widget, LOWORD(w_param)); | 912 PostProcessActivateMessage(this, LOWORD(w_param)); |
1061 return result; | 913 return result; |
1062 } | 914 } |
1063 | 915 |
1064 // static | 916 // static |
1065 void WidgetWin::PostProcessActivateMessage(WidgetWin* widget, | 917 void WidgetWin::PostProcessActivateMessage(WidgetWin* widget, |
1066 int activation_state) { | 918 int activation_state) { |
1067 if (!widget->focus_manager_.get()) { | 919 if (!widget->focus_manager_.get()) { |
1068 NOTREACHED(); | 920 NOTREACHED(); |
1069 return; | 921 return; |
1070 } | 922 } |
(...skipping 14 matching lines...) Expand all Loading... |
1085 WidgetWin* popup = new WidgetWin; | 937 WidgetWin* popup = new WidgetWin; |
1086 popup->set_window_style(WS_POPUP); | 938 popup->set_window_style(WS_POPUP); |
1087 popup->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW | | 939 popup->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW | |
1088 WS_EX_TRANSPARENT | | 940 WS_EX_TRANSPARENT | |
1089 l10n_util::GetExtendedTooltipStyles()); | 941 l10n_util::GetExtendedTooltipStyles()); |
1090 popup->set_delete_on_destroy(delete_on_destroy); | 942 popup->set_delete_on_destroy(delete_on_destroy); |
1091 return popup; | 943 return popup; |
1092 } | 944 } |
1093 | 945 |
1094 } // namespace views | 946 } // namespace views |
1095 | |
OLD | NEW |