| Index: ui/views/controls/native_control.cc
|
| diff --git a/ui/views/controls/native_control.cc b/ui/views/controls/native_control.cc
|
| deleted file mode 100644
|
| index faebbc81f9021bb041316fb1049106511a2d324f..0000000000000000000000000000000000000000
|
| --- a/ui/views/controls/native_control.cc
|
| +++ /dev/null
|
| @@ -1,389 +0,0 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "ui/views/controls/native_control.h"
|
| -
|
| -#include <atlbase.h>
|
| -#include <atlapp.h>
|
| -#include <atlcrack.h>
|
| -#include <atlframe.h>
|
| -#include <atlmisc.h>
|
| -
|
| -#include "base/logging.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "ui/base/accessibility/accessibility_types.h"
|
| -#include "ui/base/l10n/l10n_util_win.h"
|
| -#include "ui/base/view_prop.h"
|
| -#include "ui/events/keycodes/keyboard_code_conversion_win.h"
|
| -#include "ui/events/keycodes/keyboard_codes.h"
|
| -#include "ui/gfx/win/hwnd_util.h"
|
| -#include "ui/views/background.h"
|
| -#include "ui/views/controls/native/native_view_host.h"
|
| -#include "ui/views/focus/focus_manager.h"
|
| -#include "ui/views/widget/widget.h"
|
| -
|
| -using ui::ViewProp;
|
| -
|
| -namespace views {
|
| -
|
| -// Maps to the NativeControl.
|
| -static const char* const kNativeControlKey = "__NATIVE_CONTROL__";
|
| -
|
| -class NativeControlContainer : public CWindowImpl<NativeControlContainer,
|
| - CWindow,
|
| - CWinTraits<WS_CHILD | WS_CLIPSIBLINGS |
|
| - WS_CLIPCHILDREN>> {
|
| - public:
|
| - explicit NativeControlContainer(NativeControl* parent)
|
| - : parent_(parent),
|
| - control_(NULL),
|
| - original_handler_(NULL) {
|
| - }
|
| -
|
| - void Init() {
|
| - Create(parent_->GetWidget()->GetNativeView());
|
| - ::ShowWindow(m_hWnd, SW_SHOW);
|
| - }
|
| -
|
| - virtual ~NativeControlContainer() {
|
| - }
|
| -
|
| - // NOTE: If you add a new message, be sure and verify parent_ is valid before
|
| - // calling into parent_.
|
| - DECLARE_FRAME_WND_CLASS(L"ChromeViewsNativeControlContainer", NULL);
|
| - BEGIN_MSG_MAP(NativeControlContainer);
|
| - MSG_WM_CREATE(OnCreate);
|
| - MSG_WM_ERASEBKGND(OnEraseBkgnd);
|
| - MSG_WM_PAINT(OnPaint);
|
| - MSG_WM_SIZE(OnSize);
|
| - MSG_WM_NOTIFY(OnNotify);
|
| - MSG_WM_COMMAND(OnCommand);
|
| - MSG_WM_DESTROY(OnDestroy);
|
| - MSG_WM_CONTEXTMENU(OnContextMenu);
|
| - MSG_WM_CTLCOLORBTN(OnCtlColorBtn);
|
| - MSG_WM_CTLCOLORSTATIC(OnCtlColorStatic)
|
| - END_MSG_MAP();
|
| -
|
| - HWND GetControl() {
|
| - return control_;
|
| - }
|
| -
|
| - // Called when the parent is getting deleted. This control stays around until
|
| - // it gets the OnFinalMessage call.
|
| - void ResetParent() {
|
| - parent_ = NULL;
|
| - }
|
| -
|
| - void OnFinalMessage(HWND hwnd) {
|
| - if (parent_)
|
| - parent_->NativeControlDestroyed();
|
| - delete this;
|
| - }
|
| -
|
| - private:
|
| - friend class NativeControl;
|
| -
|
| - LRESULT OnCreate(LPCREATESTRUCT create_struct) {
|
| - control_ = parent_->CreateNativeControl(m_hWnd);
|
| -
|
| - // We subclass the control hwnd so we get the WM_KEYDOWN messages.
|
| - original_handler_ = gfx::SetWindowProc(
|
| - control_, &NativeControl::NativeControlWndProc);
|
| - prop_.reset(new ViewProp(control_, kNativeControlKey , parent_));
|
| -
|
| - ::ShowWindow(control_, SW_SHOW);
|
| - return 1;
|
| - }
|
| -
|
| - LRESULT OnEraseBkgnd(HDC dc) {
|
| - return 1;
|
| - }
|
| -
|
| - void OnPaint(HDC ignore) {
|
| - PAINTSTRUCT ps;
|
| - HDC dc = ::BeginPaint(*this, &ps);
|
| - ::EndPaint(*this, &ps);
|
| - }
|
| -
|
| - void OnSize(int type, const CSize& sz) {
|
| - ::MoveWindow(control_, 0, 0, sz.cx, sz.cy, TRUE);
|
| - }
|
| -
|
| - LRESULT OnCommand(UINT code, int id, HWND source) {
|
| - return parent_ ? parent_->OnCommand(code, id, source) : 0;
|
| - }
|
| -
|
| - LRESULT OnNotify(int w_param, LPNMHDR l_param) {
|
| - if (parent_)
|
| - return parent_->OnNotify(w_param, l_param);
|
| - else
|
| - return 0;
|
| - }
|
| -
|
| - void OnDestroy() {
|
| - if (parent_)
|
| - parent_->OnDestroy();
|
| - }
|
| -
|
| - void OnContextMenu(HWND window, const POINT& location) {
|
| - if (parent_)
|
| - parent_->OnContextMenu(location);
|
| - }
|
| -
|
| - // We need to find an ancestor with a non-null background, and
|
| - // ask it for a (solid color) brush that approximates
|
| - // the background. The caller will use this when drawing
|
| - // the native control as a background color, particularly
|
| - // for radiobuttons and XP style pushbuttons.
|
| - LRESULT OnCtlColor(UINT msg, HDC dc, HWND control) {
|
| - const View *ancestor = parent_;
|
| - while (ancestor) {
|
| - const Background *background = ancestor->background();
|
| - if (background) {
|
| - HBRUSH brush = background->GetNativeControlBrush();
|
| - if (brush)
|
| - return reinterpret_cast<LRESULT>(brush);
|
| - }
|
| - ancestor = ancestor->parent();
|
| - }
|
| -
|
| - // COLOR_BTNFACE is the default for dialog box backgrounds.
|
| - return reinterpret_cast<LRESULT>(GetSysColorBrush(COLOR_BTNFACE));
|
| - }
|
| -
|
| - LRESULT OnCtlColorBtn(HDC dc, HWND control) {
|
| - return OnCtlColor(WM_CTLCOLORBTN, dc, control);
|
| - }
|
| -
|
| - LRESULT OnCtlColorStatic(HDC dc, HWND control) {
|
| - return OnCtlColor(WM_CTLCOLORSTATIC, dc, control);
|
| - }
|
| -
|
| - NativeControl* parent_;
|
| - HWND control_;
|
| -
|
| - // Message handler that was set before we reset it.
|
| - WNDPROC original_handler_;
|
| -
|
| - scoped_ptr<ViewProp> prop_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(NativeControlContainer);
|
| -};
|
| -
|
| -NativeControl::NativeControl() : hwnd_view_(NULL),
|
| - container_(NULL),
|
| - fixed_width_(-1),
|
| - horizontal_alignment_(CENTER),
|
| - fixed_height_(-1),
|
| - vertical_alignment_(CENTER) {
|
| - SetFocusable(true);
|
| -}
|
| -
|
| -NativeControl::~NativeControl() {
|
| - if (container_) {
|
| - container_->ResetParent();
|
| - ::DestroyWindow(*container_);
|
| - }
|
| -}
|
| -
|
| -void NativeControl::ValidateNativeControl() {
|
| - if (hwnd_view_ == NULL) {
|
| - hwnd_view_ = new NativeViewHost;
|
| - AddChildView(hwnd_view_);
|
| - }
|
| -
|
| - if (!container_ && visible()) {
|
| - container_ = new NativeControlContainer(this);
|
| - container_->Init();
|
| - hwnd_view_->Attach(*container_);
|
| - if (!enabled())
|
| - EnableWindow(GetNativeControlHWND(), enabled());
|
| -
|
| - // This message ensures that the focus border is shown.
|
| - ::SendMessage(container_->GetControl(),
|
| - WM_CHANGEUISTATE,
|
| - MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS),
|
| - 0);
|
| - }
|
| -}
|
| -
|
| -void NativeControl::ViewHierarchyChanged(
|
| - const ViewHierarchyChangedDetails& details) {
|
| - if (details.is_add && details.parent != this && !container_ && GetWidget()) {
|
| - ValidateNativeControl();
|
| - Layout();
|
| - }
|
| -}
|
| -
|
| -void NativeControl::Layout() {
|
| - if (!container_ && GetWidget())
|
| - ValidateNativeControl();
|
| -
|
| - if (hwnd_view_) {
|
| - gfx::Rect lb = GetLocalBounds();
|
| -
|
| - int x = lb.x();
|
| - int y = lb.y();
|
| - int width = lb.width();
|
| - int height = lb.height();
|
| - if (fixed_width_ > 0) {
|
| - width = std::min(fixed_width_, width);
|
| - switch (horizontal_alignment_) {
|
| - case LEADING:
|
| - // Nothing to do.
|
| - break;
|
| - case CENTER:
|
| - x += (lb.width() - width) / 2;
|
| - break;
|
| - case TRAILING:
|
| - x = x + lb.width() - width;
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - }
|
| - }
|
| -
|
| - if (fixed_height_ > 0) {
|
| - height = std::min(fixed_height_, height);
|
| - switch (vertical_alignment_) {
|
| - case LEADING:
|
| - // Nothing to do.
|
| - break;
|
| - case CENTER:
|
| - y += (lb.height() - height) / 2;
|
| - break;
|
| - case TRAILING:
|
| - y = y + lb.height() - height;
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - }
|
| - }
|
| -
|
| - hwnd_view_->SetBounds(x, y, width, height);
|
| - }
|
| -}
|
| -
|
| -void NativeControl::OnContextMenu(const POINT& location) {
|
| - if (!context_menu_controller())
|
| - return;
|
| -
|
| - if (location.x == -1 && location.y == -1) {
|
| - ShowContextMenu(GetKeyboardContextMenuLocation(),
|
| - ui::MENU_SOURCE_KEYBOARD);
|
| - } else {
|
| - ShowContextMenu(gfx::Point(location), ui::MENU_SOURCE_MOUSE);
|
| - }
|
| -}
|
| -
|
| -void NativeControl::OnFocus() {
|
| - if (container_) {
|
| - DCHECK(container_->GetControl());
|
| - ::SetFocus(container_->GetControl());
|
| - NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_FOCUS, false);
|
| - }
|
| -}
|
| -
|
| -HWND NativeControl::GetNativeControlHWND() {
|
| - if (container_)
|
| - return container_->GetControl();
|
| - else
|
| - return NULL;
|
| -}
|
| -
|
| -void NativeControl::NativeControlDestroyed() {
|
| - if (hwnd_view_)
|
| - hwnd_view_->Detach();
|
| - container_ = NULL;
|
| -}
|
| -
|
| -void NativeControl::SetVisible(bool is_visible) {
|
| - if (is_visible != visible()) {
|
| - View::SetVisible(is_visible);
|
| - if (!is_visible && container_)
|
| - ::DestroyWindow(*container_);
|
| - else if (is_visible && !container_)
|
| - ValidateNativeControl();
|
| - }
|
| -}
|
| -
|
| -void NativeControl::OnEnabledChanged() {
|
| - View::OnEnabledChanged();
|
| - if (GetNativeControlHWND())
|
| - EnableWindow(GetNativeControlHWND(), enabled());
|
| -}
|
| -
|
| -void NativeControl::OnPaint(gfx::Canvas* canvas) {
|
| -}
|
| -
|
| -void NativeControl::VisibilityChanged(View* starting_from, bool is_visible) {
|
| - SetVisible(is_visible);
|
| -}
|
| -
|
| -void NativeControl::SetFixedWidth(int width, Alignment alignment) {
|
| - DCHECK_GT(width, 0);
|
| - fixed_width_ = width;
|
| - horizontal_alignment_ = alignment;
|
| -}
|
| -
|
| -void NativeControl::SetFixedHeight(int height, Alignment alignment) {
|
| - DCHECK_GT(height, 0);
|
| - fixed_height_ = height;
|
| - vertical_alignment_ = alignment;
|
| -}
|
| -
|
| -DWORD NativeControl::GetAdditionalExStyle() const {
|
| - // If the UI for the view is mirrored, we should make sure we add the
|
| - // extended window style for a right-to-left layout so the subclass creates
|
| - // a mirrored HWND for the underlying control.
|
| - DWORD ex_style = 0;
|
| - if (base::i18n::IsRTL())
|
| - ex_style |= l10n_util::GetExtendedStyles();
|
| -
|
| - return ex_style;
|
| -}
|
| -
|
| -DWORD NativeControl::GetAdditionalRTLStyle() const {
|
| - // If the UI for the view is mirrored, we should make sure we add the
|
| - // extended window style for a right-to-left layout so the subclass creates
|
| - // a mirrored HWND for the underlying control.
|
| - DWORD ex_style = 0;
|
| - if (base::i18n::IsRTL())
|
| - ex_style |= l10n_util::GetExtendedTooltipStyles();
|
| -
|
| - return ex_style;
|
| -}
|
| -
|
| -// static
|
| -LRESULT CALLBACK NativeControl::NativeControlWndProc(HWND window,
|
| - UINT message,
|
| - WPARAM w_param,
|
| - LPARAM l_param) {
|
| - NativeControl* native_control = static_cast<NativeControl*>(
|
| - ViewProp::GetValue(window, kNativeControlKey));
|
| - DCHECK(native_control);
|
| - WNDPROC original_handler = native_control->container_->original_handler_;
|
| - DCHECK(original_handler);
|
| -
|
| - if (message == WM_KEYDOWN &&
|
| - native_control->OnKeyDown(ui::KeyboardCodeForWindowsKeyCode(w_param))) {
|
| - return 0;
|
| - } else if (message == WM_SETFOCUS) {
|
| - // Let the focus manager know that the focus changed.
|
| - FocusManager* focus_manager = native_control->GetFocusManager();
|
| - if (focus_manager) {
|
| - focus_manager->SetFocusedView(native_control);
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| - } else if (message == WM_DESTROY) {
|
| - gfx::SetWindowProc(window, reinterpret_cast<WNDPROC>(original_handler));
|
| - native_control->container_->prop_.reset();
|
| - }
|
| -
|
| - return CallWindowProc(reinterpret_cast<WNDPROC>(original_handler), window,
|
| - message, w_param, l_param);
|
| -}
|
| -
|
| -} // namespace views
|
|
|