summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-04 20:44:51 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-04 20:44:51 +0000
commitcd56238a0514a66c4ecdd9ef9c49a49198656914 (patch)
treeed4257477acdac715e26edb5cf21726ae15b8d81
parentf9889ed8c9fc841f29a99c813205ce37b1c08ffb (diff)
downloadchromium_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.cc25
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.h20
-rw-r--r--views/controls/native_control_win.cc15
-rw-r--r--views/controls/native_control_win.h18
-rw-r--r--views/views.gyp4
-rw-r--r--views/widget/child_window_message_processor.cc27
-rw-r--r--views/widget/child_window_message_processor.h50
-rw-r--r--views/widget/widget_win.cc43
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.