| 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 |