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