diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-04 20:44:51 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-04 20:44:51 +0000 |
commit | cd56238a0514a66c4ecdd9ef9c49a49198656914 (patch) | |
tree | ed4257477acdac715e26edb5cf21726ae15b8d81 | |
parent | f9889ed8c9fc841f29a99c813205ce37b1c08ffb (diff) | |
download | chromium_src-cd56238a0514a66c4ecdd9ef9c49a49198656914.zip chromium_src-cd56238a0514a66c4ecdd9ef9c49a49198656914.tar.gz chromium_src-cd56238a0514a66c4ecdd9ef9c49a49198656914.tar.bz2 |
Adds the ability for classes other than native control to process
messages bounced to the parent and wires it up for autocompleteedit,
which I'm going to need shortly.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/4470001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65109 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit_view_win.cc | 25 | ||||
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit_view_win.h | 20 | ||||
-rw-r--r-- | views/controls/native_control_win.cc | 15 | ||||
-rw-r--r-- | views/controls/native_control_win.h | 18 | ||||
-rw-r--r-- | views/views.gyp | 4 | ||||
-rw-r--r-- | views/widget/child_window_message_processor.cc | 27 | ||||
-rw-r--r-- | views/widget/child_window_message_processor.h | 50 | ||||
-rw-r--r-- | views/widget/widget_win.cc | 43 |
8 files changed, 162 insertions, 40 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc index 328d55b..b35abc1 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc @@ -22,6 +22,7 @@ #include "app/win/drag_source.h" #include "app/win/drop_target.h" #include "app/win/iat_patch_function.h" +#include "app/win/scoped_prop.h" #include "base/auto_reset.h" #include "base/basictypes.h" #include "base/i18n/rtl.h" @@ -438,6 +439,10 @@ AutocompleteEditViewWin::AutocompleteEditViewWin( SendMessage(m_hWnd, EM_SETWORDBREAKPROC, 0, reinterpret_cast<LPARAM>(&WordBreakProc)); + // Makes it EN_SELCHANGE is sent to our parent window and back to us by way of + // ProcessWindowMessage. + SetEventMask(ENM_SELCHANGE); + // Get the metrics for the font. HDC dc = ::GetDC(NULL); SelectObject(dc, font_.GetNativeFont()); @@ -468,6 +473,9 @@ AutocompleteEditViewWin::AutocompleteEditViewWin( SetBackgroundColor(background_color_); + message_handler_prop_.reset( + views::ChildWindowMessageProcessor::Register(m_hWnd, this)); + // By default RichEdit has a drop target. Revoke it so that we can install our // own. Revoke takes care of deleting the existing one. RevokeDragDrop(m_hWnd); @@ -1056,6 +1064,19 @@ void AutocompleteEditViewWin::ExecuteCommand(int command_id) { OnAfterPossibleChange(); } +bool AutocompleteEditViewWin::ProcessMessage(UINT message, + WPARAM w_param, + LPARAM l_param, + LRESULT* result) { + if (message == WM_NOTIFY) { + NMHDR* header = reinterpret_cast<NMHDR*>(l_param); + if (header->code == EN_SELCHANGE) { + // TODO(sky): wire this up. + } + } + return false; +} + // static int CALLBACK AutocompleteEditViewWin::WordBreakProc(LPTSTR edit_text, int current_pos, @@ -1246,6 +1267,10 @@ void AutocompleteEditViewWin::OnCut() { ReplaceSel(L"", true); } +void AutocompleteEditViewWin::OnDestroy() { + message_handler_prop_.reset(); +} + LRESULT AutocompleteEditViewWin::OnGetObject(UINT uMsg, WPARAM wparam, LPARAM lparam) { diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.h b/chrome/browser/autocomplete/autocomplete_edit_view_win.h index c0abab6..fdeaca6 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.h +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.h @@ -22,8 +22,9 @@ #include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h" #include "chrome/common/page_transition_types.h" #include "gfx/font.h" -#include "webkit/glue/window_open_disposition.h" #include "views/controls/menu/menu_2.h" +#include "views/widget/child_window_message_processor.h" +#include "webkit/glue/window_open_disposition.h" class Profile; class TabContents; @@ -31,6 +32,12 @@ namespace views { class View; } +namespace app { +namespace win { +class ScopedProp; +} +} + class AutocompleteEditController; class AutocompleteEditModel; class AutocompleteEditView; @@ -46,6 +53,7 @@ class AutocompleteEditViewWin ES_NOHIDESEL> >, public CRichEditCommands<AutocompleteEditViewWin>, public menus::SimpleMenuModel::Delegate, + public views::ChildWindowMessageProcessor, public AutocompleteEditView { public: struct State { @@ -174,6 +182,7 @@ class AutocompleteEditViewWin MSG_WM_CONTEXTMENU(OnContextMenu) MSG_WM_COPY(OnCopy) MSG_WM_CUT(OnCut) + MSG_WM_DESTROY(OnDestroy) MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject) MESSAGE_HANDLER_EX(WM_IME_COMPOSITION, OnImeComposition) MESSAGE_HANDLER_EX(WM_IME_NOTIFY, OnImeNotify) @@ -212,6 +221,11 @@ class AutocompleteEditViewWin virtual std::wstring GetLabelForCommandId(int command_id) const; virtual void ExecuteCommand(int command_id); + // views::ChildWindowMessageProcessor + virtual bool ProcessMessage(UINT message, + WPARAM w_param, + LPARAM l_param, + LRESULT* result); private: enum MouseButton { kLeft = 0, @@ -267,6 +281,7 @@ class AutocompleteEditViewWin void OnContextMenu(HWND window, const CPoint& point); void OnCopy(); void OnCut(); + void OnDestroy(); LRESULT OnGetObject(UINT uMsg, WPARAM wparam, LPARAM lparam); LRESULT OnImeComposition(UINT message, WPARAM wparam, LPARAM lparam); LRESULT OnImeNotify(UINT message, WPARAM wparam, LPARAM lparam); @@ -519,6 +534,9 @@ class AutocompleteEditViewWin // Instance of accessibility information and handling. mutable ScopedComPtr<IAccessible> autocomplete_accessibility_; + // ScopedProp returned from registering as a ChildWindowMessageProcessor. + scoped_ptr<app::win::ScopedProp> message_handler_prop_; + DISALLOW_COPY_AND_ASSIGN(AutocompleteEditViewWin); }; diff --git a/views/controls/native_control_win.cc b/views/controls/native_control_win.cc index 0c6d257..c4f811c 100644 --- a/views/controls/native_control_win.cc +++ b/views/controls/native_control_win.cc @@ -14,9 +14,7 @@ namespace views { -// static -const wchar_t* NativeControlWin::kNativeControlWinKey = - L"__NATIVE_CONTROL_WIN__"; +static const wchar_t* kNativeControlWinKey = L"__NATIVE_CONTROL_WIN__"; //////////////////////////////////////////////////////////////////////////////// // NativeControlWin, public: @@ -35,8 +33,10 @@ NativeControlWin::~NativeControlWin() { } } -bool NativeControlWin::ProcessMessage(UINT message, WPARAM w_param, - LPARAM l_param, LRESULT* result) { +bool NativeControlWin::ProcessMessage(UINT message, + WPARAM w_param, + LPARAM l_param, + LRESULT* result) { switch (message) { case WM_CONTEXTMENU: ShowContextMenu(gfx::Point(GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param))); @@ -130,8 +130,9 @@ void NativeControlWin::ShowContextMenu(const gfx::Point& location) { void NativeControlWin::NativeControlCreated(HWND native_control) { // Associate this object with the control's HWND so that WidgetWin can find // this object when it receives messages from it. - prop_.reset( + props_.push_back( new app::win::ScopedProp(native_control, kNativeControlWinKey, this)); + props_.push_back(ChildWindowMessageProcessor::Register(native_control, this)); // Subclass so we get WM_KEYDOWN and WM_SETFOCUS messages. original_wndproc_ = @@ -211,7 +212,7 @@ LRESULT NativeControlWin::NativeControlWndProc(HWND window, NOTREACHED(); } } else if (message == WM_DESTROY) { - native_control->prop_.reset(); + native_control->props_.reset(); win_util::SetWindowProc(window, native_control->original_wndproc_); } diff --git a/views/controls/native_control_win.h b/views/controls/native_control_win.h index 6d0fdf0..3733a15 100644 --- a/views/controls/native_control_win.h +++ b/views/controls/native_control_win.h @@ -7,8 +7,10 @@ #pragma once #include "base/scoped_ptr.h" +#include "base/scoped_vector.h" #include "views/controls/combobox/combobox.h" #include "views/controls/native/native_view_host.h" +#include "views/widget/child_window_message_processor.h" namespace app { namespace win { @@ -19,19 +21,13 @@ class ScopedProp; namespace views { // A View that hosts a native Windows control. -class NativeControlWin : public NativeViewHost { +class NativeControlWin : public ChildWindowMessageProcessor, + public NativeViewHost { public: - static const wchar_t* kNativeControlWinKey; - NativeControlWin(); virtual ~NativeControlWin(); - // Called by the containing WidgetWin when a message is received from the HWND - // created by an object derived from NativeControlWin. Derived classes MUST - // call _this_ version of the function if they override it and do not handle - // all of the messages listed in widget_win.cc ProcessNativeControlWinMessage. - // Returns true if the message was handled, with a valid result in |result|. - // Returns false if the message was not handled. + // Overridden from ChildWindowMessageProcessor: virtual bool ProcessMessage(UINT message, WPARAM w_param, LPARAM l_param, @@ -79,6 +75,8 @@ class NativeControlWin : public NativeViewHost { DWORD GetAdditionalRTLStyle() const; private: + typedef ScopedVector<app::win::ScopedProp> ScopedProps; + // Called by the containing WidgetWin when a message of type WM_CTLCOLORBTN or // WM_CTLCOLORSTATIC is sent from the HWND created by an object dreived from // NativeControlWin. @@ -93,7 +91,7 @@ class NativeControlWin : public NativeViewHost { // The window procedure before we subclassed. WNDPROC original_wndproc_; - scoped_ptr<app::win::ScopedProp> prop_; + ScopedProps props_; DISALLOW_COPY_AND_ASSIGN(NativeControlWin); }; diff --git a/views/views.gyp b/views/views.gyp index c4878fe..b87aea3 100644 --- a/views/views.gyp +++ b/views/views.gyp @@ -282,6 +282,8 @@ 'views_delegate.h', 'widget/aero_tooltip_manager.cc', 'widget/aero_tooltip_manager.h', + 'widget/child_window_message_processor.cc', + 'widget/child_window_message_processor.h', 'widget/default_theme_provider.cc', 'widget/default_theme_provider.h', 'widget/drop_helper.cc', @@ -363,6 +365,8 @@ 'controls/tree/tree_view.cc', 'event_win.cc', 'resize_corner.cc', + 'widget/child_window_message_processor.cc', + 'widget/child_window_message_processor.h', 'widget/aero_tooltip_manager.cc', 'widget/root_view_drop_target.cc', 'window/hit_test.cc', diff --git a/views/widget/child_window_message_processor.cc b/views/widget/child_window_message_processor.cc new file mode 100644 index 0000000..a3b578e --- /dev/null +++ b/views/widget/child_window_message_processor.cc @@ -0,0 +1,27 @@ +// Copyright (c) 2010 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 "views/widget/child_window_message_processor.h" + +#include "app/win/scoped_prop.h" + +namespace views { + +static const wchar_t* kChildWindowKey = L"__CHILD_WINDOW_MESSAGE_PROCESSOR__"; + +// static +app::win::ScopedProp* ChildWindowMessageProcessor::Register( + HWND hwnd, + ChildWindowMessageProcessor* processor) { + DCHECK(processor); + return new app::win::ScopedProp(hwnd, kChildWindowKey, processor); +} + +// static +ChildWindowMessageProcessor* ChildWindowMessageProcessor::Get(HWND hwnd) { + return reinterpret_cast<ChildWindowMessageProcessor*>( + ::GetProp(hwnd, kChildWindowKey)); +} + +} // namespace diff --git a/views/widget/child_window_message_processor.h b/views/widget/child_window_message_processor.h new file mode 100644 index 0000000..7d4e63e --- /dev/null +++ b/views/widget/child_window_message_processor.h @@ -0,0 +1,50 @@ +// Copyright (c) 2010 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. + +#ifndef VIEWS_WIDGET_CHILD_WINDOW_MESSAGE_PROCESSOR_H_ +#define VIEWS_WIDGET_CHILD_WINDOW_MESSAGE_PROCESSOR_H_ +#pragma once + +#include <windows.h> + +namespace app { +namespace win { +class ScopedProp; +} +} + +namespace views { + +// Windows sends a handful of messages to the parent window rather than the +// window itself. For example, selection changes of a rich edit (EN_SELCHANGE) +// are sent to the parent, not the window. Typically such message are best +// dealt with by the window rather than the parent. WidgetWin allows for +// registering a ChildWindowMessageProcessor to handle such messages. +class ChildWindowMessageProcessor { + public: + // Registers |processor| for |hwnd|. The caller takes ownership of the + // returned object. + static app::win::ScopedProp* Register(HWND hwnd, + ChildWindowMessageProcessor* processor); + + // Returns the ChildWindowMessageProcessor for |hwnd|, NULL if there isn't + // one. + static ChildWindowMessageProcessor* Get(HWND hwnd); + + // Invoked for any messages that are sent to the parent and originated from + // the HWND this ChildWindowMessageProcessor was registered for. Returns true + // if the message was handled with a valid result in |result|. Returns false + // if the message was not handled. + virtual bool ProcessMessage(UINT message, + WPARAM w_param, + LPARAM l_param, + LRESULT* result) = 0; + + protected: + virtual ~ChildWindowMessageProcessor() {} +}; + +} // namespace views + +#endif // VIEWS_WIDGET_CHILD_WINDOW_MESSAGE_PROCESSOR_H_ diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc index bb6ca8d..77cf8c1 100644 --- a/views/widget/widget_win.cc +++ b/views/widget/widget_win.cc @@ -19,6 +19,7 @@ #include "views/focus/focus_util_win.h" #include "views/views_delegate.h" #include "views/widget/aero_tooltip_manager.h" +#include "views/widget/child_window_message_processor.h" #include "views/widget/default_theme_provider.h" #include "views/widget/drop_target_win.h" #include "views/widget/root_view.h" @@ -41,11 +42,6 @@ RootView* GetRootViewForHWND(HWND hwnd) { return reinterpret_cast<RootView*>(::GetProp(hwnd, kRootViewWindowProperty)); } -NativeControlWin* GetNativeControlWinForHWND(HWND hwnd) { - return reinterpret_cast<NativeControlWin*>( - GetProp(hwnd, NativeControlWin::kNativeControlWinKey)); -} - /////////////////////////////////////////////////////////////////////////////// // WidgetWin, public @@ -1173,7 +1169,9 @@ RootView* WidgetWin::GetFocusedViewRootView() { // Get the source HWND of the specified message. Depending on the message, the // source HWND is encoded in either the WPARAM or the LPARAM value. -HWND GetControlHWNDForMessage(UINT message, WPARAM w_param, LPARAM l_param) { +static HWND GetControlHWNDForMessage(UINT message, + WPARAM w_param, + LPARAM l_param) { // Each of the following messages can be sent by a child HWND and must be // forwarded to its associated NativeControlWin for handling. switch (message) { @@ -1196,25 +1194,26 @@ HICON WidgetWin::GetDefaultWindowIcon() const { return NULL; } -// Some messages may be sent to us by a child HWND managed by -// NativeControlWin. If this is the case, this function will forward those -// messages on to the object associated with the source HWND and return true, -// in which case the window procedure must not do any further processing of -// the message. If there is no associated NativeControlWin, the return value -// will be false and the WndProc can continue processing the message normally. -// |l_result| contains the result of the message processing by the control and -// must be returned by the WndProc if the return value is true. -bool ProcessNativeControlMessage(UINT message, - WPARAM w_param, - LPARAM l_param, - LRESULT* l_result) { +// Some messages may be sent to us by a child HWND. If this is the case, this +// function will forward those messages on to the object associated with the +// source HWND and return true, in which case the window procedure must not do +// any further processing of the message. If there is no associated +// ChildWindowMessageProcessor, the return value will be false and the WndProc +// can continue processing the message normally. |l_result| contains the result +// of the message processing by the control and must be returned by the WndProc +// if the return value is true. +static bool ProcessChildWindowMessage(UINT message, + WPARAM w_param, + LPARAM l_param, + LRESULT* l_result) { *l_result = 0; HWND control_hwnd = GetControlHWNDForMessage(message, w_param, l_param); if (IsWindow(control_hwnd)) { - NativeControlWin* wrapper = GetNativeControlWinForHWND(control_hwnd); - if (wrapper) - return wrapper->ProcessMessage(message, w_param, l_param, l_result); + ChildWindowMessageProcessor* processor = + ChildWindowMessageProcessor::Get(control_hwnd); + if (processor) + return processor->ProcessMessage(message, w_param, l_param, l_result); } return false; @@ -1227,7 +1226,7 @@ LRESULT WidgetWin::OnWndProc(UINT message, WPARAM w_param, LPARAM l_param) { // First allow messages sent by child controls to be processed directly by // their associated views. If such a view is present, it will handle the // message *instead of* this WidgetWin. - if (ProcessNativeControlMessage(message, w_param, l_param, &result)) + if (ProcessChildWindowMessage(message, w_param, l_param, &result)) return result; // Otherwise we handle everything else. |