summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-21 19:24:44 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-21 19:24:44 +0000
commit4f2c7acdd25fb0eb251c0309921b77feb90998f6 (patch)
treeaa8c0b86d142b17a96637b03340b61a737ce73a9 /ui
parent819c94b891cf5ca5250cd89c7870dc15eaa36d2f (diff)
downloadchromium_src-4f2c7acdd25fb0eb251c0309921b77feb90998f6.zip
chromium_src-4f2c7acdd25fb0eb251c0309921b77feb90998f6.tar.gz
chromium_src-4f2c7acdd25fb0eb251c0309921b77feb90998f6.tar.bz2
Move more message handlers from NWW to HWNDMessageHandler.
http://crbug.com/142962 TBR=sky@chromium.org Review URL: https://chromiumcodereview.appspot.com/10832419 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152607 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/views/widget/native_widget_win.cc328
-rw-r--r--ui/views/widget/native_widget_win.h14
-rw-r--r--ui/views/win/hwnd_message_handler.cc239
-rw-r--r--ui/views/win/hwnd_message_handler.h17
-rw-r--r--ui/views/win/hwnd_message_handler_delegate.h31
5 files changed, 400 insertions, 229 deletions
diff --git a/ui/views/widget/native_widget_win.cc b/ui/views/widget/native_widget_win.cc
index 15e8d2c..be19bd1 100644
--- a/ui/views/widget/native_widget_win.cc
+++ b/ui/views/widget/native_widget_win.cc
@@ -238,30 +238,12 @@ BOOL CALLBACK SendDwmCompositionChanged(HWND window, LPARAM param) {
return TRUE;
}
-// Tells the window its frame (non-client area) has changed.
-void SendFrameChanged(HWND window) {
- SetWindowPos(window, NULL, 0, 0, 0, 0,
- SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS |
- SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION |
- SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER);
-}
-
// Enables or disables the menu item for the specified command and menu.
void EnableMenuItem(HMENU menu, UINT command, bool enabled) {
UINT flags = MF_BYCOMMAND | (enabled ? MF_ENABLED : MF_DISABLED | MF_GRAYED);
EnableMenuItem(menu, command, flags);
}
-BOOL CALLBACK EnumChildWindowsForRedraw(HWND hwnd, LPARAM lparam) {
- DWORD process_id;
- GetWindowThreadProcessId(hwnd, &process_id);
- int flags = RDW_INVALIDATE | RDW_NOCHILDREN | RDW_FRAME;
- if (process_id == GetCurrentProcessId())
- flags |= RDW_UPDATENOW;
- RedrawWindow(hwnd, NULL, NULL, flags);
- return TRUE;
-}
-
// See comments in OnNCPaint() for details of this struct.
struct ClipState {
// The window being painted.
@@ -314,10 +296,6 @@ bool GetMonitorAndRects(const RECT& rect,
// Links the HWND to its NativeWidget.
const char* const kNativeWidgetKey = "__VIEWS_NATIVE_WIDGET__";
-// A custom MSAA object id used to determine if a screen reader is actively
-// listening for MSAA events.
-const int kCustomObjectID = 1;
-
const int kDragFrameWindowAlpha = 200;
struct FindOwnedWindowsData {
@@ -568,7 +546,7 @@ void NativeWidgetWin::FrameTypeChanged() {
// Send a frame change notification, since the non-client metrics have
// changed.
- SendFrameChanged(GetNativeView());
+ message_handler_->SendFrameChanged();
// Update the non-client view with the correct frame view for the active frame
// type.
@@ -940,7 +918,7 @@ void NativeWidgetWin::ShowWithWindowState(ui::WindowShowState show_state) {
}
bool NativeWidgetWin::IsVisible() const {
- return !!::IsWindowVisible(hwnd());
+ return message_handler_->IsVisible();
}
void NativeWidgetWin::Activate() {
@@ -958,7 +936,7 @@ void NativeWidgetWin::Deactivate() {
}
bool NativeWidgetWin::IsActive() const {
- return GetActiveWindow() == hwnd();
+ return message_handler_->IsActive();
}
void NativeWidgetWin::SetAlwaysOnTop(bool on_top) {
@@ -1292,70 +1270,7 @@ void NativeWidgetWin::OnCommand(UINT notification_code,
}
LRESULT NativeWidgetWin::OnCreate(CREATESTRUCT* create_struct) {
- SetNativeWindowProperty(kNativeWidgetKey, this);
- CHECK_EQ(this, GetNativeWidgetForNativeView(hwnd()));
-
- use_layered_buffer_ = !!(window_ex_style() & WS_EX_LAYERED);
-
- // Attempt to detect screen readers by sending an event with our custom id.
- if (!IsAccessibleWidget())
- NotifyWinEvent(EVENT_SYSTEM_ALERT, hwnd(), kCustomObjectID, CHILDID_SELF);
-
- props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(hwnd()));
-
- drop_target_ = new DropTargetWin(
- static_cast<internal::RootView*>(GetWidget()->GetRootView()));
-
- // We need to add ourselves as a message loop observer so that we can repaint
- // aggressively if the contents of our window become invalid. Unfortunately
- // WM_PAINT messages are starved and we get flickery redrawing when resizing
- // if we do not do this.
- MessageLoopForUI::current()->AddObserver(this);
-
- // Windows special DWM window frame requires a special tooltip manager so
- // that window controls in Chrome windows don't flicker when you move your
- // mouse over them. See comment in aero_tooltip_manager.h.
- Widget* widget = GetWidget()->GetTopLevelWidget();
- if (widget && widget->ShouldUseNativeFrame()) {
- tooltip_manager_.reset(new AeroTooltipManager(GetWidget()));
- } else {
- tooltip_manager_.reset(new TooltipManagerWin(GetWidget()));
- }
- if (!tooltip_manager_->Init()) {
- // There was a problem creating the TooltipManager. Common error is 127.
- // See 82193 for details.
- LOG_GETLASTERROR(WARNING) << "tooltip creation failed, disabling tooltips";
- tooltip_manager_.reset();
- }
-
- // This message initializes the window so that focus border are shown for
- // windows.
- SendMessage(
- hwnd(), WM_CHANGEUISTATE, MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS), 0);
-
- // Bug 964884: detach the IME attached to this window.
- // We should attach IMEs only when we need to input CJK strings.
- ImmAssociateContextEx(hwnd(), NULL, 0);
-
- if (message_handler_->remove_standard_frame()) {
- SetWindowLong(GWL_STYLE, GetWindowLong(GWL_STYLE) & ~WS_CAPTION);
- SendFrameChanged(GetNativeView());
- }
-
- // We need to allow the delegate to size its contents since the window may not
- // receive a size notification when its initial bounds are specified at window
- // creation time.
- ClientAreaSizeChanged();
-
- delegate_->OnNativeWidgetCreated();
-
- // Get access to a modifiable copy of the system menu.
- GetSystemMenu(hwnd(), false);
-
- if (base::win::GetVersion() >= base::win::VERSION_WIN7)
- RegisterTouchWindow(hwnd(), 0);
-
- return 0;
+ return message_handler_->OnCreate(create_struct);
}
void NativeWidgetWin::OnDestroy() {
@@ -1369,8 +1284,7 @@ void NativeWidgetWin::OnDisplayChange(UINT bits_per_pixel, CSize screen_size) {
LRESULT NativeWidgetWin::OnDwmCompositionChanged(UINT msg,
WPARAM w_param,
LPARAM l_param) {
- message_handler_->OnDwmCompositionChanged(msg, w_param, l_param);
- return 0;
+ return message_handler_->OnDwmCompositionChanged(msg, w_param, l_param);
}
void NativeWidgetWin::OnEndSession(BOOL ending, UINT logoff) {
@@ -1393,65 +1307,20 @@ void NativeWidgetWin::OnExitSizeMove() {
message_handler_->OnExitSizeMove();
}
-LRESULT NativeWidgetWin::OnGetObject(UINT uMsg,
+LRESULT NativeWidgetWin::OnGetObject(UINT message,
WPARAM w_param,
LPARAM l_param) {
- LRESULT reference_result = static_cast<LRESULT>(0L);
-
- // Accessibility readers will send an OBJID_CLIENT message
- if (OBJID_CLIENT == l_param) {
- // Retrieve MSAA dispatch object for the root view.
- base::win::ScopedComPtr<IAccessible> root(
- GetWidget()->GetRootView()->GetNativeViewAccessible());
-
- // Create a reference that MSAA will marshall to the client.
- reference_result = LresultFromObject(IID_IAccessible, w_param,
- static_cast<IAccessible*>(root.Detach()));
- }
-
- if (kCustomObjectID == l_param) {
- // An MSAA client requestes our custom id. Assume that we have detected an
- // active windows screen reader.
- OnScreenReaderDetected();
-
- // Return with failure.
- return static_cast<LRESULT>(0L);
- }
-
- return reference_result;
+ return message_handler_->OnGetObject(message, w_param, l_param);
}
void NativeWidgetWin::OnGetMinMaxInfo(MINMAXINFO* minmax_info) {
- gfx::Size min_window_size(delegate_->GetMinimumSize());
- gfx::Size max_window_size(delegate_->GetMaximumSize());
- // Add the native frame border size to the minimum and maximum size if the
- // view reports its size as the client size.
- if (WidgetSizeIsClientSize()) {
- CRect client_rect, window_rect;
- GetClientRect(&client_rect);
- GetWindowRect(&window_rect);
- window_rect -= client_rect;
- min_window_size.Enlarge(window_rect.Width(), window_rect.Height());
- if (!max_window_size.IsEmpty())
- max_window_size.Enlarge(window_rect.Width(), window_rect.Height());
- }
- minmax_info->ptMinTrackSize.x = min_window_size.width();
- minmax_info->ptMinTrackSize.y = min_window_size.height();
- if (max_window_size.width() || max_window_size.height()) {
- if (!max_window_size.width())
- max_window_size.set_width(GetSystemMetrics(SM_CXMAXTRACK));
- if (!max_window_size.height())
- max_window_size.set_height(GetSystemMetrics(SM_CYMAXTRACK));
- minmax_info->ptMaxTrackSize.x = max_window_size.width();
- minmax_info->ptMaxTrackSize.y = max_window_size.height();
- }
- SetMsgHandled(FALSE);
+ message_handler_->OnGetMinMaxInfo(minmax_info);
}
void NativeWidgetWin::OnHScroll(int scroll_type,
short position,
HWND scrollbar) {
- SetMsgHandled(FALSE);
+ message_handler_->OnHScroll(scroll_type, position, scrollbar);
}
LRESULT NativeWidgetWin::OnImeMessages(UINT message,
@@ -1488,14 +1357,7 @@ void NativeWidgetWin::OnKillFocus(HWND focused_window) {
LRESULT NativeWidgetWin::OnMouseActivate(UINT message,
WPARAM w_param,
LPARAM l_param) {
- // TODO(beng): resolve this with the GetWindowLong() check on the subsequent
- // line.
- if (GetWidget()->non_client_view())
- return delegate_->CanActivate() ? MA_ACTIVATE : MA_NOACTIVATEANDEAT;
- if (GetWindowLong(GWL_EXSTYLE) & WS_EX_NOACTIVATE)
- return MA_NOACTIVATE;
- SetMsgHandled(FALSE);
- return MA_ACTIVATE;
+ return message_handler_->OnMouseActivate(message, w_param, l_param);
}
LRESULT NativeWidgetWin::OnMouseRange(UINT message,
@@ -1598,50 +1460,7 @@ void NativeWidgetWin::OnMoving(UINT param, const LPRECT new_bounds) {
}
LRESULT NativeWidgetWin::OnNCActivate(BOOL active) {
- if (delegate_->CanActivate())
- delegate_->OnNativeWidgetActivationChanged(!!active);
-
- if (!GetWidget()->non_client_view()) {
- SetMsgHandled(FALSE);
- return 0;
- }
-
- if (!delegate_->CanActivate())
- return TRUE;
-
- // The frame may need to redraw as a result of the activation change.
- // We can get WM_NCACTIVATE before we're actually visible. If we're not
- // visible, no need to paint.
- if (IsVisible())
- GetWidget()->non_client_view()->SchedulePaint();
-
- if (!GetWidget()->ShouldUseNativeFrame()) {
- // TODO(beng, et al): Hack to redraw this window and child windows
- // synchronously upon activation. Not all child windows are redrawing
- // themselves leading to issues like http://crbug.com/74604
- // We redraw out-of-process HWNDs asynchronously to avoid hanging the
- // whole app if a child HWND belonging to a hung plugin is encountered.
- RedrawWindow(GetNativeView(), NULL, NULL,
- RDW_NOCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW);
- EnumChildWindows(GetNativeView(), EnumChildWindowsForRedraw, NULL);
- }
-
- // If we're active again, we should be allowed to render as inactive, so
- // tell the non-client view.
- bool inactive_rendering_disabled = delegate_->IsInactiveRenderingDisabled();
- if (IsActive())
- delegate_->EnableInactiveRendering();
-
- // Avoid DefWindowProc non-client rendering over our custom frame on newer
- // Windows versions only (breaks taskbar activation indication on XP/Vista).
- if (!GetWidget()->ShouldUseNativeFrame() &&
- base::win::GetVersion() > base::win::VERSION_VISTA) {
- SetMsgHandled(TRUE);
- return TRUE;
- }
-
- return DefWindowProcWithRedrawLock(
- WM_NCACTIVATE, inactive_rendering_disabled || active, 0);
+ return message_handler_->OnNCActivate(active);
}
LRESULT NativeWidgetWin::OnNCCalcSize(BOOL mode, LPARAM l_param) {
@@ -1827,17 +1646,7 @@ LRESULT NativeWidgetWin::OnNCUAHDrawFrame(UINT msg,
}
LRESULT NativeWidgetWin::OnNotify(int w_param, NMHDR* l_param) {
- // We can be sent this message before the tooltip manager is created, if a
- // subclass overrides OnCreate and creates some kind of Windows control there
- // that sends WM_NOTIFY messages.
- if (tooltip_manager_.get()) {
- bool handled;
- LRESULT result = tooltip_manager_->OnNotify(w_param, l_param, &handled);
- SetMsgHandled(handled);
- return result;
- }
- SetMsgHandled(FALSE);
- return 0;
+ return message_handler_->OnNotify(w_param, l_param);
}
void NativeWidgetWin::OnPaint(HDC dc) {
@@ -1867,8 +1676,7 @@ LRESULT NativeWidgetWin::OnPowerBroadcast(DWORD power_event, DWORD data) {
LRESULT NativeWidgetWin::OnReflectedMessage(UINT msg,
WPARAM w_param,
LPARAM l_param) {
- SetMsgHandled(FALSE);
- return 0;
+ return message_handler_->OnReflectedMessage(msg, w_param, l_param);
}
LRESULT NativeWidgetWin::OnSetCursor(UINT message,
@@ -1890,19 +1698,7 @@ LRESULT NativeWidgetWin::OnSetText(const wchar_t* text) {
}
void NativeWidgetWin::OnSettingChange(UINT flags, const wchar_t* section) {
- if (!GetParent() && (flags == SPI_SETWORKAREA) &&
- !GetWidget()->widget_delegate()->WillProcessWorkAreaChange()) {
- // Fire a dummy SetWindowPos() call, so we'll trip the code in
- // OnWindowPosChanging() below that notices work area changes.
- ::SetWindowPos(GetNativeView(), 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
- SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
- SetMsgHandled(TRUE);
- } else {
- // TODO(beng): move to Widget.
- if (flags == SPI_SETWORKAREA)
- GetWidget()->widget_delegate()->OnWorkAreaChanged();
- SetMsgHandled(FALSE);
- }
+ message_handler_->OnSettingChange(flags, section);
}
void NativeWidgetWin::OnSize(UINT param, const CSize& size) {
@@ -2192,6 +1988,18 @@ bool NativeWidgetWin::IsUsingCustomFrame() const {
return !GetWidget()->ShouldUseNativeFrame();
}
+void NativeWidgetWin::SchedulePaint() {
+ GetWidget()->GetRootView()->SchedulePaint();
+}
+
+void NativeWidgetWin::EnableInactiveRendering() {
+ delegate_->EnableInactiveRendering();
+}
+
+bool NativeWidgetWin::IsInactiveRenderingDisabled() {
+ return delegate_->IsInactiveRenderingDisabled();
+}
+
bool NativeWidgetWin::CanResize() const {
return GetWidget()->widget_delegate()->CanResize();
}
@@ -2204,6 +2012,10 @@ bool NativeWidgetWin::CanActivate() const {
return delegate_->CanActivate();
}
+bool NativeWidgetWin::WillProcessWorkAreaChange() const {
+ return GetWidget()->widget_delegate()->WillProcessWorkAreaChange();
+}
+
int NativeWidgetWin::GetNonClientComponent(const gfx::Point& point) const {
return delegate_->GetNonClientComponent(point);
}
@@ -2212,16 +2024,30 @@ void NativeWidgetWin::GetWindowMask(const gfx::Size& size, gfx::Path* path) {
GetWidget()->non_client_view()->GetWindowMask(size, path);
}
+void NativeWidgetWin::GetMinMaxSize(gfx::Size* min_size,
+ gfx::Size* max_size) const {
+ *min_size = delegate_->GetMinimumSize();
+ *max_size = delegate_->GetMaximumSize();
+}
+
InputMethod* NativeWidgetWin::GetInputMethod() {
return GetWidget()->GetInputMethodDirect();
}
+gfx::NativeViewAccessible NativeWidgetWin::GetNativeViewAccessible() {
+ return GetWidget()->GetRootView()->GetNativeViewAccessible();
+}
+
void NativeWidgetWin::HandleAppDeactivated() {
// Another application was activated, we should reset any state that
// disables inactive rendering now.
delegate_->EnableInactiveRendering();
}
+void NativeWidgetWin::HandleActivationChanged(bool active) {
+ delegate_->OnNativeWidgetActivationChanged(active);
+}
+
bool NativeWidgetWin::HandleAppCommand(short command) {
// We treat APPCOMMAND ids as an extension of our command namespace, and just
// let the delegate figure out what to do...
@@ -2241,6 +2067,49 @@ bool NativeWidgetWin::HandleCommand(int command) {
return GetWidget()->widget_delegate()->ExecuteWindowsCommand(command);
}
+void NativeWidgetWin::HandleCreate() {
+ // TODO(beng): much of this could/should maybe move to HWNDMessageHandler.
+
+ SetNativeWindowProperty(kNativeWidgetKey, this);
+ CHECK_EQ(this, GetNativeWidgetForNativeView(hwnd()));
+
+ use_layered_buffer_ = !!(window_ex_style() & WS_EX_LAYERED);
+
+ props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(hwnd()));
+
+ drop_target_ = new DropTargetWin(
+ static_cast<internal::RootView*>(GetWidget()->GetRootView()));
+
+ // We need to add ourselves as a message loop observer so that we can repaint
+ // aggressively if the contents of our window become invalid. Unfortunately
+ // WM_PAINT messages are starved and we get flickery redrawing when resizing
+ // if we do not do this.
+ MessageLoopForUI::current()->AddObserver(this);
+
+ // Windows special DWM window frame requires a special tooltip manager so
+ // that window controls in Chrome windows don't flicker when you move your
+ // mouse over them. See comment in aero_tooltip_manager.h.
+ Widget* widget = GetWidget()->GetTopLevelWidget();
+ if (widget && widget->ShouldUseNativeFrame()) {
+ tooltip_manager_.reset(new AeroTooltipManager(GetWidget()));
+ } else {
+ tooltip_manager_.reset(new TooltipManagerWin(GetWidget()));
+ }
+ if (!tooltip_manager_->Init()) {
+ // There was a problem creating the TooltipManager. Common error is 127.
+ // See 82193 for details.
+ LOG_GETLASTERROR(WARNING) << "tooltip creation failed, disabling tooltips";
+ tooltip_manager_.reset();
+ }
+
+ // We need to allow the delegate to size its contents since the window may not
+ // receive a size notification when its initial bounds are specified at window
+ // creation time.
+ ClientAreaSizeChanged();
+
+ delegate_->OnNativeWidgetCreated();
+}
+
void NativeWidgetWin::HandleDestroy() {
delegate_->OnNativeWidgetDestroying();
if (drop_target_.get()) {
@@ -2275,6 +2144,10 @@ void NativeWidgetWin::HandleMove() {
delegate_->OnNativeWidgetMove();
}
+void NativeWidgetWin::HandleWorkAreaChanged() {
+ GetWidget()->widget_delegate()->OnWorkAreaChanged();
+}
+
void NativeWidgetWin::HandleNativeFocus(HWND last_focused_window) {
delegate_->OnNativeFocus(last_focused_window);
}
@@ -2283,6 +2156,25 @@ void NativeWidgetWin::HandleNativeBlur(HWND focused_window) {
delegate_->OnNativeBlur(focused_window);
}
+void NativeWidgetWin::HandleScreenReaderDetected() {
+ // TODO(beng): just consolidate this with OnScreenReaderDetected.
+ OnScreenReaderDetected();
+}
+
+bool NativeWidgetWin::HandleTooltipNotify(int w_param,
+ NMHDR* l_param,
+ LRESULT* l_result) {
+ // We can be sent this message before the tooltip manager is created, if a
+ // subclass overrides OnCreate and creates some kind of Windows control there
+ // that sends WM_NOTIFY messages.
+ if (tooltip_manager_.get()) {
+ bool handled;
+ *l_result = tooltip_manager_->OnNotify(w_param, l_param, &handled);
+ return handled;
+ }
+ return false;
+}
+
NativeWidgetWin* NativeWidgetWin::AsNativeWidgetWin() {
return this;
}
diff --git a/ui/views/widget/native_widget_win.h b/ui/views/widget/native_widget_win.h
index 7106448..26c8fbe 100644
--- a/ui/views/widget/native_widget_win.h
+++ b/ui/views/widget/native_widget_win.h
@@ -494,25 +494,39 @@ class VIEWS_EXPORT NativeWidgetWin : public ui::WindowImpl,
// Overridden from HWNDMessageHandlerDelegate:
virtual bool IsWidgetWindow() const OVERRIDE;
virtual bool IsUsingCustomFrame() const OVERRIDE;
+ virtual void SchedulePaint() OVERRIDE;
+ virtual void EnableInactiveRendering() OVERRIDE;
+ virtual bool IsInactiveRenderingDisabled() OVERRIDE;
virtual bool CanResize() const OVERRIDE;
virtual bool CanMaximize() const OVERRIDE;
virtual bool CanActivate() const OVERRIDE;
+ virtual bool WillProcessWorkAreaChange() const OVERRIDE;
virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE;
virtual void GetWindowMask(const gfx::Size& size, gfx::Path* path) OVERRIDE;
+ virtual void GetMinMaxSize(gfx::Size* min_size,
+ gfx::Size* max_size) const OVERRIDE;
+ virtual gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE;
virtual InputMethod* GetInputMethod() OVERRIDE;
virtual void HandleAppDeactivated() OVERRIDE;
+ virtual void HandleActivationChanged(bool active) OVERRIDE;
virtual bool HandleAppCommand(short command) OVERRIDE;
virtual void HandleCaptureLost() OVERRIDE;
virtual void HandleClose() OVERRIDE;
virtual bool HandleCommand(int command) OVERRIDE;
+ virtual void HandleCreate() OVERRIDE;
virtual void HandleDestroy() OVERRIDE;
virtual void HandleDisplayChange() OVERRIDE;
virtual void HandleGlassModeChange() OVERRIDE;
virtual void HandleBeginWMSizeMove() OVERRIDE;
virtual void HandleEndWMSizeMove() OVERRIDE;
virtual void HandleMove() OVERRIDE;
+ virtual void HandleWorkAreaChanged() OVERRIDE;
virtual void HandleNativeFocus(HWND last_focused_window) OVERRIDE;
virtual void HandleNativeBlur(HWND focused_window) OVERRIDE;
+ virtual void HandleScreenReaderDetected() OVERRIDE;
+ virtual bool HandleTooltipNotify(int w_param,
+ NMHDR* l_param,
+ LRESULT* l_result) OVERRIDE;
virtual NativeWidgetWin* AsNativeWidgetWin() OVERRIDE;
// Called after the WM_ACTIVATE message has been processed by the default
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index 780025c..ea54edc 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -7,6 +7,7 @@
#include <dwmapi.h>
#include "base/system_monitor/system_monitor.h"
+#include "base/win/windows_version.h"
#include "ui/gfx/path.h"
#include "ui/base/native_theme/native_theme_win.h"
#include "ui/views/ime/input_method_win.h"
@@ -14,6 +15,24 @@
#include "ui/views/win/hwnd_message_handler_delegate.h"
namespace views {
+namespace {
+
+// Called from OnNCActivate.
+BOOL CALLBACK EnumChildWindowsForRedraw(HWND hwnd, LPARAM lparam) {
+ DWORD process_id;
+ GetWindowThreadProcessId(hwnd, &process_id);
+ int flags = RDW_INVALIDATE | RDW_NOCHILDREN | RDW_FRAME;
+ if (process_id == GetCurrentProcessId())
+ flags |= RDW_UPDATENOW;
+ RedrawWindow(hwnd, NULL, NULL, flags);
+ return TRUE;
+}
+
+// A custom MSAA object id used to determine if a screen reader is actively
+// listening for MSAA events.
+const int kCustomObjectID = 1;
+
+} // namespace
////////////////////////////////////////////////////////////////////////////////
// HWNDMessageHandler, public:
@@ -26,6 +45,21 @@ HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate)
HWNDMessageHandler::~HWNDMessageHandler() {
}
+bool HWNDMessageHandler::IsActive() const {
+ return GetActiveWindow() == hwnd();
+}
+
+bool HWNDMessageHandler::IsVisible() const {
+ return !!::IsWindowVisible(hwnd());
+}
+
+void HWNDMessageHandler::SendFrameChanged() {
+ SetWindowPos(hwnd(), NULL, 0, 0, 0, 0,
+ SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS |
+ SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREPOSITION |
+ SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER);
+}
+
void HWNDMessageHandler::OnActivate(UINT action, BOOL minimized, HWND window) {
SetMsgHandled(FALSE);
}
@@ -35,12 +69,8 @@ void HWNDMessageHandler::OnActivateApp(BOOL active, DWORD thread_id) {
thread_id != GetCurrentThreadId()) {
delegate_->HandleAppDeactivated();
// Also update the native frame if it is rendering the non-client area.
- if (!remove_standard_frame_ &&
- !delegate_->IsUsingCustomFrame() &&
- delegate_->AsNativeWidgetWin()) {
- delegate_->AsNativeWidgetWin()->DefWindowProcWithRedrawLock(
- WM_NCACTIVATE, FALSE, 0);
- }
+ if (!remove_standard_frame_ && !delegate_->IsUsingCustomFrame())
+ DefWindowProcWithRedrawLock(WM_NCACTIVATE, FALSE, 0);
}
}
@@ -77,6 +107,39 @@ void HWNDMessageHandler::OnCommand(UINT notification_code,
SetMsgHandled(FALSE);
}
+LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) {
+ // Attempt to detect screen readers by sending an event with our custom id.
+ NotifyWinEvent(EVENT_SYSTEM_ALERT, hwnd(), kCustomObjectID, CHILDID_SELF);
+
+ // This message initializes the window so that focus border are shown for
+ // windows.
+ SendMessage(hwnd(),
+ WM_CHANGEUISTATE,
+ MAKELPARAM(UIS_CLEAR, UISF_HIDEFOCUS),
+ 0);
+
+ // Bug 964884: detach the IME attached to this window.
+ // We should attach IMEs only when we need to input CJK strings.
+ ImmAssociateContextEx(hwnd(), NULL, 0);
+
+ if (remove_standard_frame_) {
+ SetWindowLong(hwnd(), GWL_STYLE,
+ GetWindowLong(hwnd(), GWL_STYLE) & ~WS_CAPTION);
+ SendFrameChanged();
+ }
+
+ // Get access to a modifiable copy of the system menu.
+ GetSystemMenu(hwnd(), false);
+
+ if (base::win::GetVersion() >= base::win::VERSION_WIN7)
+ RegisterTouchWindow(hwnd(), 0);
+
+ delegate_->HandleCreate();
+
+ // TODO(beng): move more of NWW::OnCreate here.
+ return 0;
+}
+
void HWNDMessageHandler::OnDestroy() {
delegate_->HandleDestroy();
}
@@ -86,14 +149,15 @@ void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel,
delegate_->HandleDisplayChange();
}
-void HWNDMessageHandler::OnDwmCompositionChanged(UINT msg,
- WPARAM w_param,
- LPARAM l_param) {
+LRESULT HWNDMessageHandler::OnDwmCompositionChanged(UINT msg,
+ WPARAM w_param,
+ LPARAM l_param) {
if (!delegate_->IsWidgetWindow()) {
SetMsgHandled(FALSE);
- return;
+ return 0;
}
delegate_->HandleGlassModeChange();
+ return 0;
}
void HWNDMessageHandler::OnEndSession(BOOL ending, UINT logoff) {
@@ -119,6 +183,69 @@ void HWNDMessageHandler::OnExitSizeMove() {
SetMsgHandled(FALSE);
}
+void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) {
+ gfx::Size min_window_size;
+ gfx::Size max_window_size;
+ delegate_->GetMinMaxSize(&min_window_size, &max_window_size);
+
+ // Add the native frame border size to the minimum and maximum size if the
+ // view reports its size as the client size.
+ if (delegate_->AsNativeWidgetWin()->WidgetSizeIsClientSize()) {
+ CRect client_rect, window_rect;
+ GetClientRect(hwnd(), &client_rect);
+ GetWindowRect(hwnd(), &window_rect);
+ window_rect -= client_rect;
+ min_window_size.Enlarge(window_rect.Width(), window_rect.Height());
+ if (!max_window_size.IsEmpty())
+ max_window_size.Enlarge(window_rect.Width(), window_rect.Height());
+ }
+ minmax_info->ptMinTrackSize.x = min_window_size.width();
+ minmax_info->ptMinTrackSize.y = min_window_size.height();
+ if (max_window_size.width() || max_window_size.height()) {
+ if (!max_window_size.width())
+ max_window_size.set_width(GetSystemMetrics(SM_CXMAXTRACK));
+ if (!max_window_size.height())
+ max_window_size.set_height(GetSystemMetrics(SM_CYMAXTRACK));
+ minmax_info->ptMaxTrackSize.x = max_window_size.width();
+ minmax_info->ptMaxTrackSize.y = max_window_size.height();
+ }
+ SetMsgHandled(FALSE);
+}
+
+LRESULT HWNDMessageHandler::OnGetObject(UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ LRESULT reference_result = static_cast<LRESULT>(0L);
+
+ // Accessibility readers will send an OBJID_CLIENT message
+ if (OBJID_CLIENT == l_param) {
+ // Retrieve MSAA dispatch object for the root view.
+ base::win::ScopedComPtr<IAccessible> root(
+ delegate_->GetNativeViewAccessible());
+
+ // Create a reference that MSAA will marshall to the client.
+ reference_result = LresultFromObject(IID_IAccessible, w_param,
+ static_cast<IAccessible*>(root.Detach()));
+ }
+
+ if (kCustomObjectID == l_param) {
+ // An MSAA client requested our custom id. Assume that we have detected an
+ // active windows screen reader.
+ delegate_->HandleScreenReaderDetected();
+
+ // Return with failure.
+ return static_cast<LRESULT>(0L);
+ }
+
+ return reference_result;
+}
+
+void HWNDMessageHandler::OnHScroll(int scroll_type,
+ short position,
+ HWND scrollbar) {
+ SetMsgHandled(FALSE);
+}
+
LRESULT HWNDMessageHandler::OnImeMessages(UINT message,
WPARAM w_param,
LPARAM l_param) {
@@ -184,6 +311,19 @@ void HWNDMessageHandler::OnKillFocus(HWND focused_window) {
SetMsgHandled(FALSE);
}
+LRESULT HWNDMessageHandler::OnMouseActivate(UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ // TODO(beng): resolve this with the GetWindowLong() check on the subsequent
+ // line.
+ if (delegate_->IsWidgetWindow())
+ return delegate_->CanActivate() ? MA_ACTIVATE : MA_NOACTIVATEANDEAT;
+ if (GetWindowLong(hwnd(), GWL_EXSTYLE) & WS_EX_NOACTIVATE)
+ return MA_NOACTIVATE;
+ SetMsgHandled(FALSE);
+ return MA_ACTIVATE;
+}
+
void HWNDMessageHandler::OnMove(const CPoint& point) {
delegate_->HandleMove();
SetMsgHandled(FALSE);
@@ -193,6 +333,53 @@ void HWNDMessageHandler::OnMoving(UINT param, const RECT* new_bounds) {
delegate_->HandleMove();
}
+LRESULT HWNDMessageHandler::OnNCActivate(BOOL active) {
+ if (delegate_->CanActivate())
+ delegate_->HandleActivationChanged(!!active);
+
+ if (!delegate_->IsWidgetWindow()) {
+ SetMsgHandled(FALSE);
+ return 0;
+ }
+
+ if (!delegate_->CanActivate())
+ return TRUE;
+
+ // The frame may need to redraw as a result of the activation change.
+ // We can get WM_NCACTIVATE before we're actually visible. If we're not
+ // visible, no need to paint.
+ if (IsVisible())
+ delegate_->SchedulePaint();
+
+ if (delegate_->IsUsingCustomFrame()) {
+ // TODO(beng, et al): Hack to redraw this window and child windows
+ // synchronously upon activation. Not all child windows are redrawing
+ // themselves leading to issues like http://crbug.com/74604
+ // We redraw out-of-process HWNDs asynchronously to avoid hanging the
+ // whole app if a child HWND belonging to a hung plugin is encountered.
+ RedrawWindow(hwnd(), NULL, NULL,
+ RDW_NOCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW);
+ EnumChildWindows(hwnd(), EnumChildWindowsForRedraw, NULL);
+ }
+
+ // If we're active again, we should be allowed to render as inactive, so
+ // tell the non-client view.
+ bool inactive_rendering_disabled = delegate_->IsInactiveRenderingDisabled();
+ if (IsActive())
+ delegate_->EnableInactiveRendering();
+
+ // Avoid DefWindowProc non-client rendering over our custom frame on newer
+ // Windows versions only (breaks taskbar activation indication on XP/Vista).
+ if (delegate_->IsUsingCustomFrame() &&
+ base::win::GetVersion() > base::win::VERSION_VISTA) {
+ SetMsgHandled(TRUE);
+ return TRUE;
+ }
+
+ return DefWindowProcWithRedrawLock(
+ WM_NCACTIVATE, inactive_rendering_disabled || active, 0);
+}
+
LRESULT HWNDMessageHandler::OnNCHitTest(const CPoint& point) {
if (!delegate_->IsWidgetWindow()) {
SetMsgHandled(FALSE);
@@ -241,6 +428,12 @@ LRESULT HWNDMessageHandler::OnNCUAHDrawFrame(UINT message,
return 0;
}
+LRESULT HWNDMessageHandler::OnNotify(int w_param, NMHDR* l_param) {
+ LRESULT l_result = 0;
+ SetMsgHandled(delegate_->HandleTooltipNotify(w_param, l_param, &l_result));
+ return l_result;
+}
+
LRESULT HWNDMessageHandler::OnPowerBroadcast(DWORD power_event, DWORD data) {
base::SystemMonitor* monitor = base::SystemMonitor::Get();
if (monitor)
@@ -249,6 +442,13 @@ LRESULT HWNDMessageHandler::OnPowerBroadcast(DWORD power_event, DWORD data) {
return 0;
}
+LRESULT HWNDMessageHandler::OnReflectedMessage(UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ SetMsgHandled(FALSE);
+ return 0;
+}
+
LRESULT HWNDMessageHandler::OnSetCursor(UINT message,
WPARAM w_param,
LPARAM l_param) {
@@ -280,6 +480,21 @@ LRESULT HWNDMessageHandler::OnSetText(const wchar_t* text) {
reinterpret_cast<LPARAM>(text));
}
+void HWNDMessageHandler::OnSettingChange(UINT flags, const wchar_t* section) {
+ if (!GetParent(hwnd()) && (flags == SPI_SETWORKAREA) &&
+ !delegate_->WillProcessWorkAreaChange()) {
+ // Fire a dummy SetWindowPos() call, so we'll trip the code in
+ // OnWindowPosChanging() below that notices work area changes.
+ ::SetWindowPos(hwnd(), 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
+ SetMsgHandled(TRUE);
+ } else {
+ if (flags == SPI_SETWORKAREA)
+ delegate_->HandleWorkAreaChanged();
+ SetMsgHandled(FALSE);
+ }
+}
+
void HWNDMessageHandler::OnSize(UINT param, const CSize& size) {
RedrawWindow(hwnd(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
// ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've
@@ -346,6 +561,10 @@ HWND HWNDMessageHandler::hwnd() {
return delegate_->AsNativeWidgetWin()->hwnd();
}
+HWND HWNDMessageHandler::hwnd() const {
+ return delegate_->AsNativeWidgetWin()->hwnd();
+}
+
LRESULT HWNDMessageHandler::DefWindowProcWithRedrawLock(UINT message,
WPARAM w_param,
LPARAM l_param) {
diff --git a/ui/views/win/hwnd_message_handler.h b/ui/views/win/hwnd_message_handler.h
index cd1a7a7..d24195a 100644
--- a/ui/views/win/hwnd_message_handler.h
+++ b/ui/views/win/hwnd_message_handler.h
@@ -28,6 +28,12 @@ class VIEWS_EXPORT HWNDMessageHandler {
explicit HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate);
~HWNDMessageHandler();
+ bool IsActive() const;
+ bool IsVisible() const;
+
+ // Tells the HWND its client area has changed.
+ void SendFrameChanged();
+
// Message Handlers.
void OnActivate(UINT action, BOOL minimized, HWND window);
// TODO(beng): Once this object becomes the WindowImpl, these methods can
@@ -40,31 +46,39 @@ class VIEWS_EXPORT HWNDMessageHandler {
void OnCaptureChanged(HWND window);
void OnClose();
void OnCommand(UINT notification_code, int command, HWND window);
+ LRESULT OnCreate(CREATESTRUCT* create_struct);
void OnDestroy();
void OnDisplayChange(UINT bits_per_pixel, const CSize& screen_size);
- void OnDwmCompositionChanged(UINT msg, WPARAM w_param, LPARAM l_param);
+ LRESULT OnDwmCompositionChanged(UINT msg, WPARAM w_param, LPARAM l_param);
void OnEndSession(BOOL ending, UINT logoff);
void OnEnterSizeMove();
LRESULT OnEraseBkgnd(HDC dc);
void OnExitMenuLoop(BOOL is_track_popup_menu);
void OnExitSizeMove();
+ void OnHScroll(int scroll_type, short position, HWND scrollbar);
+ void OnGetMinMaxInfo(MINMAXINFO* minmax_info);
+ LRESULT OnGetObject(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnImeMessages(UINT message, WPARAM w_param, LPARAM l_param);
void OnInitMenu(HMENU menu);
void OnInitMenuPopup();
void OnInputLangChange(DWORD character_set, HKL input_language_id);
LRESULT OnKeyEvent(UINT message, WPARAM w_param, LPARAM l_param);
void OnKillFocus(HWND focused_window);
+ LRESULT OnMouseActivate(UINT message, WPARAM w_param, LPARAM l_param);
void OnMove(const CPoint& point);
void OnMoving(UINT param, const RECT* new_bounds);
+ LRESULT OnNCActivate(BOOL active);
LRESULT OnNCHitTest(const CPoint& point);
LRESULT OnNCUAHDrawCaption(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnNCUAHDrawFrame(UINT message, WPARAM w_param, LPARAM l_param);
+ LRESULT OnNotify(int w_param, NMHDR* l_param);
LRESULT OnPowerBroadcast(DWORD power_event, DWORD data);
LRESULT OnReflectedMessage(UINT message, WPARAM w_param, LPARAM l_param);
LRESULT OnSetCursor(UINT message, WPARAM w_param, LPARAM l_param);
void OnSetFocus(HWND last_focused_window);
LRESULT OnSetIcon(UINT size_type, HICON new_icon);
LRESULT OnSetText(const wchar_t* text);
+ void OnSettingChange(UINT flags, const wchar_t* section);
void OnSize(UINT param, const CSize& size);
void OnThemeChanged();
void OnVScroll(int scroll_type, short position, HWND scrollbar);
@@ -84,6 +98,7 @@ class VIEWS_EXPORT HWNDMessageHandler {
// TODO(beng): This won't be a style violation once this object becomes the
// WindowImpl.
HWND hwnd();
+ HWND hwnd() const;
// TODO(beng): Remove once this class becomes the WindowImpl.
LRESULT DefWindowProcWithRedrawLock(UINT message,
diff --git a/ui/views/win/hwnd_message_handler_delegate.h b/ui/views/win/hwnd_message_handler_delegate.h
index 61fb894..944d2ab 100644
--- a/ui/views/win/hwnd_message_handler_delegate.h
+++ b/ui/views/win/hwnd_message_handler_delegate.h
@@ -28,21 +28,38 @@ class VIEWS_EXPORT HWNDMessageHandlerDelegate {
// to avoid confusion.
virtual bool IsUsingCustomFrame() const = 0;
+ virtual void SchedulePaint() = 0;
+ virtual void EnableInactiveRendering() = 0;
+ virtual bool IsInactiveRenderingDisabled() = 0;
+
virtual bool CanResize() const = 0;
virtual bool CanMaximize() const = 0;
virtual bool CanActivate() const = 0;
+ virtual bool WillProcessWorkAreaChange() const = 0;
+
virtual int GetNonClientComponent(const gfx::Point& point) const = 0;
virtual void GetWindowMask(const gfx::Size& size, gfx::Path* mask) = 0;
+ // Returns the minimum and maximum size the window can be resized to by the
+ // user.
+ virtual void GetMinMaxSize(gfx::Size* min_size,
+ gfx::Size* max_size) const = 0;
+
virtual InputMethod* GetInputMethod() = 0;
+ virtual gfx::NativeViewAccessible GetNativeViewAccessible() = 0;
+
// TODO(beng): Investigate migrating these methods to On* prefixes once
// HWNDMessageHandler is the WindowImpl.
// Called when another app was activated.
virtual void HandleAppDeactivated() = 0;
+ // Called when the window was activated or deactivated. |active| reflects the
+ // new state.
+ virtual void HandleActivationChanged(bool active) = 0;
+
// Called when a well known "app command" from the system was performed.
// Returns true if the command was handled.
virtual bool HandleAppCommand(short command) = 0;
@@ -57,6 +74,9 @@ class VIEWS_EXPORT HWNDMessageHandlerDelegate {
// true if the command was handled.
virtual bool HandleCommand(int command) = 0;
+ // Called when the HWND is created.
+ virtual void HandleCreate() = 0;
+
// Called when the HWND is destroyed.
virtual void HandleDestroy() = 0;
@@ -74,12 +94,23 @@ class VIEWS_EXPORT HWNDMessageHandlerDelegate {
// Called when the window's position changed.
virtual void HandleMove() = 0;
+ // Called when the system's work area has changed.
+ virtual void HandleWorkAreaChanged() = 0;
+
// Called when focus shifted to this HWND from |last_focused_window|.
virtual void HandleNativeFocus(HWND last_focused_window) = 0;
// Called when focus shifted from the HWND to a different window.
virtual void HandleNativeBlur(HWND focused_window) = 0;
+ // Called when we have detected a screen reader.
+ virtual void HandleScreenReaderDetected() = 0;
+
+ // Called to forward a WM_NOTIFY message to the tooltip manager.
+ virtual bool HandleTooltipNotify(int w_param,
+ NMHDR* l_param,
+ LRESULT* l_result) = 0;
+
// This is provided for methods that need to call private methods on NWW.
// TODO(beng): should be removed once HWNDMessageHandler is the WindowImpl.
virtual NativeWidgetWin* AsNativeWidgetWin() = 0;