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/controls/native_control.h" | 5 #include "views/controls/native_control.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <atlbase.h> |
| 8 #include <atlapp.h> |
| 9 #include <atlcrack.h> |
| 10 #include <atlframe.h> |
| 11 #include <atlmisc.h> |
8 | 12 |
9 #include "app/l10n_util_win.h" | 13 #include "app/l10n_util_win.h" |
10 #include "base/logging.h" | 14 #include "base/logging.h" |
11 #include "base/win_util.h" | 15 #include "base/win_util.h" |
12 #include "base/window_impl.h" | |
13 #include "views/background.h" | 16 #include "views/background.h" |
14 #include "views/border.h" | 17 #include "views/border.h" |
15 #include "views/controls/native/native_view_host.h" | 18 #include "views/controls/native/native_view_host.h" |
16 #include "views/focus/focus_manager.h" | 19 #include "views/focus/focus_manager.h" |
17 #include "views/widget/widget.h" | 20 #include "views/widget/widget.h" |
18 #include "base/gfx/native_theme.h" | 21 #include "base/gfx/native_theme.h" |
19 | 22 |
20 namespace views { | 23 namespace views { |
21 | 24 |
22 // Maps to the original WNDPROC for the controller window before we subclassed | 25 // Maps to the original WNDPROC for the controller window before we subclassed |
23 // it. | 26 // it. |
24 static const wchar_t* const kHandlerKey = | 27 static const wchar_t* const kHandlerKey = |
25 L"__CONTROL_ORIGINAL_MESSAGE_HANDLER__"; | 28 L"__CONTROL_ORIGINAL_MESSAGE_HANDLER__"; |
26 | 29 |
27 // Maps to the NativeControl. | 30 // Maps to the NativeControl. |
28 static const wchar_t* const kNativeControlKey = L"__NATIVE_CONTROL__"; | 31 static const wchar_t* const kNativeControlKey = L"__NATIVE_CONTROL__"; |
29 | 32 |
30 class NativeControlContainer : public base::WindowImpl { | 33 class NativeControlContainer : public CWindowImpl<NativeControlContainer, |
| 34 CWindow, |
| 35 CWinTraits<WS_CHILD | WS_CLIPSIBLINGS | |
| 36 WS_CLIPCHILDREN>> { |
31 public: | 37 public: |
| 38 |
32 explicit NativeControlContainer(NativeControl* parent) : parent_(parent), | 39 explicit NativeControlContainer(NativeControl* parent) : parent_(parent), |
33 control_(NULL) { | 40 control_(NULL) { |
34 set_window_style(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); | 41 Create(parent->GetWidget()->GetNativeView()); |
35 Init(parent->GetWidget()->GetNativeView(), gfx::Rect()); | 42 ::ShowWindow(m_hWnd, SW_SHOW); |
36 ShowWindow(hwnd(), SW_SHOW); | |
37 } | 43 } |
38 | 44 |
39 virtual ~NativeControlContainer() { | 45 virtual ~NativeControlContainer() { |
40 } | 46 } |
41 | 47 |
42 // NOTE: If you add a new message, be sure and verify parent_ is valid before | 48 // NOTE: If you add a new message, be sure and verify parent_ is valid before |
43 // calling into parent_. | 49 // calling into parent_. |
44 BEGIN_MSG_MAP_EX(NativeControlContainer); | 50 DECLARE_FRAME_WND_CLASS(L"ChromeViewsNativeControlContainer", NULL); |
| 51 BEGIN_MSG_MAP(NativeControlContainer); |
45 MSG_WM_CREATE(OnCreate); | 52 MSG_WM_CREATE(OnCreate); |
46 MSG_WM_ERASEBKGND(OnEraseBkgnd); | 53 MSG_WM_ERASEBKGND(OnEraseBkgnd); |
47 MSG_WM_PAINT(OnPaint); | 54 MSG_WM_PAINT(OnPaint); |
48 MSG_WM_SIZE(OnSize); | 55 MSG_WM_SIZE(OnSize); |
49 MSG_WM_NOTIFY(OnNotify); | 56 MSG_WM_NOTIFY(OnNotify); |
50 MSG_WM_COMMAND(OnCommand); | 57 MSG_WM_COMMAND(OnCommand); |
51 MSG_WM_DESTROY(OnDestroy); | 58 MSG_WM_DESTROY(OnDestroy); |
52 MSG_WM_CONTEXTMENU(OnContextMenu); | 59 MSG_WM_CONTEXTMENU(OnContextMenu); |
53 MSG_WM_CTLCOLORBTN(OnCtlColorBtn); | 60 MSG_WM_CTLCOLORBTN(OnCtlColorBtn); |
54 MSG_WM_CTLCOLORSTATIC(OnCtlColorStatic) | 61 MSG_WM_CTLCOLORSTATIC(OnCtlColorStatic) |
(...skipping 10 matching lines...) Expand all Loading... |
65 } | 72 } |
66 | 73 |
67 void OnFinalMessage(HWND hwnd) { | 74 void OnFinalMessage(HWND hwnd) { |
68 if (parent_) | 75 if (parent_) |
69 parent_->NativeControlDestroyed(); | 76 parent_->NativeControlDestroyed(); |
70 delete this; | 77 delete this; |
71 } | 78 } |
72 private: | 79 private: |
73 | 80 |
74 LRESULT OnCreate(LPCREATESTRUCT create_struct) { | 81 LRESULT OnCreate(LPCREATESTRUCT create_struct) { |
75 control_ = parent_->CreateNativeControl(hwnd()); | 82 control_ = parent_->CreateNativeControl(m_hWnd); |
76 | 83 |
77 // We subclass the control hwnd so we get the WM_KEYDOWN messages. | 84 // We subclass the control hwnd so we get the WM_KEYDOWN messages. |
78 WNDPROC original_handler = | 85 WNDPROC original_handler = |
79 win_util::SetWindowProc(control_, | 86 win_util::SetWindowProc(control_, |
80 &NativeControl::NativeControlWndProc); | 87 &NativeControl::NativeControlWndProc); |
81 SetProp(control_, kHandlerKey, original_handler); | 88 SetProp(control_, kHandlerKey, original_handler); |
82 SetProp(control_, kNativeControlKey , parent_); | 89 SetProp(control_, kNativeControlKey , parent_); |
83 | 90 |
84 ShowWindow(control_, SW_SHOW); | 91 ::ShowWindow(control_, SW_SHOW); |
85 return 1; | 92 return 1; |
86 } | 93 } |
87 | 94 |
88 LRESULT OnEraseBkgnd(HDC dc) { | 95 LRESULT OnEraseBkgnd(HDC dc) { |
89 return 1; | 96 return 1; |
90 } | 97 } |
91 | 98 |
92 void OnPaint(HDC ignore) { | 99 void OnPaint(HDC ignore) { |
93 PAINTSTRUCT ps; | 100 PAINTSTRUCT ps; |
94 HDC dc = BeginPaint(hwnd(), &ps); | 101 HDC dc = ::BeginPaint(*this, &ps); |
95 EndPaint(hwnd(), &ps); | 102 ::EndPaint(*this, &ps); |
96 } | 103 } |
97 | 104 |
98 void OnSize(int type, const CSize& sz) { | 105 void OnSize(int type, const CSize& sz) { |
99 MoveWindow(control_, 0, 0, sz.cx, sz.cy, TRUE); | 106 ::MoveWindow(control_, 0, 0, sz.cx, sz.cy, TRUE); |
100 } | 107 } |
101 | 108 |
102 LRESULT OnCommand(UINT code, int id, HWND source) { | 109 LRESULT OnCommand(UINT code, int id, HWND source) { |
103 return parent_ ? parent_->OnCommand(code, id, source) : 0; | 110 return parent_ ? parent_->OnCommand(code, id, source) : 0; |
104 } | 111 } |
105 | 112 |
106 LRESULT OnNotify(int w_param, LPNMHDR l_param) { | 113 LRESULT OnNotify(int w_param, LPNMHDR l_param) { |
107 if (parent_) | 114 if (parent_) |
108 return parent_->OnNotify(w_param, l_param); | 115 return parent_->OnNotify(w_param, l_param); |
109 else | 116 else |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 horizontal_alignment_(CENTER), | 167 horizontal_alignment_(CENTER), |
161 fixed_height_(-1), | 168 fixed_height_(-1), |
162 vertical_alignment_(CENTER) { | 169 vertical_alignment_(CENTER) { |
163 enabled_ = true; | 170 enabled_ = true; |
164 focusable_ = true; | 171 focusable_ = true; |
165 } | 172 } |
166 | 173 |
167 NativeControl::~NativeControl() { | 174 NativeControl::~NativeControl() { |
168 if (container_) { | 175 if (container_) { |
169 container_->ResetParent(); | 176 container_->ResetParent(); |
170 DestroyWindow(container_->hwnd()); | 177 ::DestroyWindow(*container_); |
171 } | 178 } |
172 } | 179 } |
173 | 180 |
174 void NativeControl::ValidateNativeControl() { | 181 void NativeControl::ValidateNativeControl() { |
175 if (hwnd_view_ == NULL) { | 182 if (hwnd_view_ == NULL) { |
176 hwnd_view_ = new NativeViewHost; | 183 hwnd_view_ = new NativeViewHost; |
177 AddChildView(hwnd_view_); | 184 AddChildView(hwnd_view_); |
178 } | 185 } |
179 | 186 |
180 if (!container_ && IsVisible()) { | 187 if (!container_ && IsVisible()) { |
181 container_ = new NativeControlContainer(this); | 188 container_ = new NativeControlContainer(this); |
182 hwnd_view_->Attach(container_->hwnd()); | 189 hwnd_view_->Attach(*container_); |
183 if (!enabled_) | 190 if (!enabled_) |
184 EnableWindow(GetNativeControlHWND(), enabled_); | 191 EnableWindow(GetNativeControlHWND(), enabled_); |
185 | 192 |
186 // This message ensures that the focus border is shown. | 193 // This message ensures that the focus border is shown. |
187 SendMessage(container_->GetControl(), | 194 ::SendMessage(container_->GetControl(), |
188 WM_CHANGEUISTATE, | 195 WM_CHANGEUISTATE, |
189 MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS), | 196 MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS), |
190 0); | 197 0); |
191 } | 198 } |
192 } | 199 } |
193 | 200 |
194 void NativeControl::ViewHierarchyChanged(bool is_add, View *parent, | 201 void NativeControl::ViewHierarchyChanged(bool is_add, View *parent, |
195 View *child) { | 202 View *child) { |
196 if (is_add && child == this && GetWidget()) { | 203 if (is_add && child == this && GetWidget()) { |
197 ValidateNativeControl(); | 204 ValidateNativeControl(); |
198 Layout(); | 205 Layout(); |
199 } | 206 } |
200 } | 207 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 x = point.x(); | 267 x = point.x(); |
261 y = point.y(); | 268 y = point.y(); |
262 is_mouse = false; | 269 is_mouse = false; |
263 } | 270 } |
264 ShowContextMenu(x, y, is_mouse); | 271 ShowContextMenu(x, y, is_mouse); |
265 } | 272 } |
266 | 273 |
267 void NativeControl::Focus() { | 274 void NativeControl::Focus() { |
268 if (container_) { | 275 if (container_) { |
269 DCHECK(container_->GetControl()); | 276 DCHECK(container_->GetControl()); |
270 SetFocus(container_->GetControl()); | 277 ::SetFocus(container_->GetControl()); |
271 } | 278 } |
272 } | 279 } |
273 | 280 |
274 HWND NativeControl::GetNativeControlHWND() { | 281 HWND NativeControl::GetNativeControlHWND() { |
275 if (container_) | 282 if (container_) |
276 return container_->GetControl(); | 283 return container_->GetControl(); |
277 else | 284 else |
278 return NULL; | 285 return NULL; |
279 } | 286 } |
280 | 287 |
281 void NativeControl::NativeControlDestroyed() { | 288 void NativeControl::NativeControlDestroyed() { |
282 if (hwnd_view_) | 289 if (hwnd_view_) |
283 hwnd_view_->Detach(); | 290 hwnd_view_->Detach(); |
284 container_ = NULL; | 291 container_ = NULL; |
285 } | 292 } |
286 | 293 |
287 void NativeControl::SetVisible(bool f) { | 294 void NativeControl::SetVisible(bool f) { |
288 if (f != IsVisible()) { | 295 if (f != IsVisible()) { |
289 View::SetVisible(f); | 296 View::SetVisible(f); |
290 if (!f && container_) { | 297 if (!f && container_) { |
291 DestroyWindow(container_->hwnd()); | 298 ::DestroyWindow(*container_); |
292 } else if (f && !container_) { | 299 } else if (f && !container_) { |
293 ValidateNativeControl(); | 300 ValidateNativeControl(); |
294 } | 301 } |
295 } | 302 } |
296 } | 303 } |
297 | 304 |
298 void NativeControl::SetEnabled(bool enabled) { | 305 void NativeControl::SetEnabled(bool enabled) { |
299 if (enabled_ != enabled) { | 306 if (enabled_ != enabled) { |
300 View::SetEnabled(enabled); | 307 View::SetEnabled(enabled); |
301 if (GetNativeControlHWND()) { | 308 if (GetNativeControlHWND()) { |
302 EnableWindow(GetNativeControlHWND(), enabled_); | 309 EnableWindow(GetNativeControlHWND(), enabled_); |
303 } | 310 } |
304 } | 311 } |
305 } | 312 } |
306 | 313 |
307 void NativeControl::Paint(gfx::Canvas* canvas) { | 314 void NativeControl::Paint(gfx::Canvas* canvas) { |
308 } | 315 } |
309 | 316 |
310 void NativeControl::VisibilityChanged(View* starting_from, bool is_visible) { | 317 void NativeControl::VisibilityChanged(View* starting_from, bool is_visible) { |
311 SetVisible(is_visible); | 318 SetVisible(is_visible); |
312 } | 319 } |
313 | 320 |
314 void NativeControl::SetFixedWidth(int width, Alignment alignment) { | 321 void NativeControl::SetFixedWidth(int width, Alignment alignment) { |
315 DCHECK_GT(width, 0); | 322 DCHECK(width > 0); |
316 fixed_width_ = width; | 323 fixed_width_ = width; |
317 horizontal_alignment_ = alignment; | 324 horizontal_alignment_ = alignment; |
318 } | 325 } |
319 | 326 |
320 void NativeControl::SetFixedHeight(int height, Alignment alignment) { | 327 void NativeControl::SetFixedHeight(int height, Alignment alignment) { |
321 DCHECK_GT(height, 0); | 328 DCHECK(height > 0); |
322 fixed_height_ = height; | 329 fixed_height_ = height; |
323 vertical_alignment_ = alignment; | 330 vertical_alignment_ = alignment; |
324 } | 331 } |
325 | 332 |
326 DWORD NativeControl::GetAdditionalExStyle() const { | 333 DWORD NativeControl::GetAdditionalExStyle() const { |
327 // If the UI for the view is mirrored, we should make sure we add the | 334 // If the UI for the view is mirrored, we should make sure we add the |
328 // extended window style for a right-to-left layout so the subclass creates | 335 // extended window style for a right-to-left layout so the subclass creates |
329 // a mirrored HWND for the underlying control. | 336 // a mirrored HWND for the underlying control. |
330 DWORD ex_style = 0; | 337 DWORD ex_style = 0; |
331 if (UILayoutIsRightToLeft()) | 338 if (UILayoutIsRightToLeft()) |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 reinterpret_cast<WNDPROC>(original_handler)); | 378 reinterpret_cast<WNDPROC>(original_handler)); |
372 RemoveProp(window, kHandlerKey); | 379 RemoveProp(window, kHandlerKey); |
373 RemoveProp(window, kNativeControlKey); | 380 RemoveProp(window, kNativeControlKey); |
374 } | 381 } |
375 | 382 |
376 return CallWindowProc(reinterpret_cast<WNDPROC>(original_handler), window, | 383 return CallWindowProc(reinterpret_cast<WNDPROC>(original_handler), window, |
377 message, w_param, l_param); | 384 message, w_param, l_param); |
378 } | 385 } |
379 | 386 |
380 } // namespace views | 387 } // namespace views |
OLD | NEW |