summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/all.gyp2
-rw-r--r--ui/base/clipboard/clipboard_unittest.cc2
-rw-r--r--ui/base/win/hwnd_subclass.cc64
-rw-r--r--ui/base/win/hwnd_subclass.h58
-rw-r--r--ui/base/win/hwnd_subclass_unittest.cc101
-rw-r--r--ui/gfx/blit.cc4
-rw-r--r--ui/ui.gyp2
-rw-r--r--ui/ui_unittests.gypi3
8 files changed, 232 insertions, 4 deletions
diff --git a/build/all.gyp b/build/all.gyp
index 49ea1d7..e7470e5 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -566,6 +566,7 @@
'../chrome/chrome.gyp:ui_tests',
'../ui/aura/aura.gyp:*',
'../ui/gfx/compositor/compositor.gyp:*',
+ '../ui/ui.gyp:gfx_unittests',
'../ui/views/views.gyp:views',
'../ui/views/views.gyp:views_unittests',
'../webkit/webkit.gyp:pull_in_webkit_unit_tests',
@@ -598,7 +599,6 @@
'../ipc/ipc.gyp:ipc_tests',
'../sql/sql.gyp:sql_unittests',
'../sync/sync.gyp:sync_unit_tests',
- '../ui/ui.gyp:gfx_unittests',
],
}],
['OS=="mac"', {
diff --git a/ui/base/clipboard/clipboard_unittest.cc b/ui/base/clipboard/clipboard_unittest.cc
index a39d27d..f01a89e 100644
--- a/ui/base/clipboard/clipboard_unittest.cc
+++ b/ui/base/clipboard/clipboard_unittest.cc
@@ -387,7 +387,7 @@ TEST_F(ClipboardTest, SharedBitmapTest) {
// The following test somehow fails on GTK. The image when read back from the
// clipboard has the alpha channel set to 0xFF for some reason. The other
// channels stay intact. So I am turning this on only for aura.
-#if defined(USE_AURA)
+#if defined(USE_AURA) && !defined(OS_WIN)
TEST_F(ClipboardTest, MultipleBitmapReadWriteTest) {
Clipboard clipboard;
diff --git a/ui/base/win/hwnd_subclass.cc b/ui/base/win/hwnd_subclass.cc
new file mode 100644
index 0000000..89a8224
--- /dev/null
+++ b/ui/base/win/hwnd_subclass.cc
@@ -0,0 +1,64 @@
+// Copyright (c) 2012 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/base/win/hwnd_subclass.h"
+
+#include "base/logging.h"
+#include "ui/base/win/hwnd_util.h"
+
+namespace {
+const char kHWNDSubclassKey[] = "__UI_BASE_WIN_HWND_SUBCLASS_PROC__";
+
+LRESULT CALLBACK WndProc(HWND hwnd,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ ui::HWNDSubclass* wrapped_wnd_proc =
+ reinterpret_cast<ui::HWNDSubclass*>(
+ ui::ViewProp::GetValue(hwnd, kHWNDSubclassKey));
+ return wrapped_wnd_proc ? wrapped_wnd_proc->OnWndProc(hwnd,
+ message,
+ w_param,
+ l_param)
+ : DefWindowProc(hwnd, message, w_param, l_param);
+}
+
+WNDPROC GetCurrentWndProc(HWND target) {
+ return reinterpret_cast<WNDPROC>(GetWindowLong(target, GWL_WNDPROC));
+}
+
+} // namespace
+
+namespace ui {
+
+HWNDSubclass::HWNDSubclass(HWND target)
+ : target_(target),
+ original_wnd_proc_(GetCurrentWndProc(target)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(prop_(target, kHWNDSubclassKey, this)) {
+ ui::SetWindowProc(target_, &WndProc);
+}
+
+HWNDSubclass::~HWNDSubclass() {
+}
+
+void HWNDSubclass::SetFilter(HWNDMessageFilter* filter) {
+ filter_.reset(filter);
+}
+
+LRESULT HWNDSubclass::OnWndProc(HWND hwnd,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ if (filter_.get()) {
+ LRESULT l_result = 0;
+ if (filter_->FilterMessage(hwnd, message, w_param, l_param, &l_result))
+ return l_result;
+ }
+
+ // In most cases, |original_wnd_proc_| will take care of calling
+ // DefWindowProc.
+ return CallWindowProc(original_wnd_proc_, hwnd, message, w_param, l_param);
+}
+
+} // namespace ui
diff --git a/ui/base/win/hwnd_subclass.h b/ui/base/win/hwnd_subclass.h
new file mode 100644
index 0000000..d967c88
--- /dev/null
+++ b/ui/base/win/hwnd_subclass.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2012 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 UI_BASE_WIN_HWND_SUBCLASS_H_
+#define UI_BASE_WIN_HWND_SUBCLASS_H_
+#pragma once
+
+#include <windows.h>
+
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/base/ui_export.h"
+#include "ui/base/view_prop.h"
+
+namespace ui {
+
+// Classes implementing this interface get the opportunity to handle and consume
+// messages before they are sent to their target HWND.
+class UI_EXPORT HWNDMessageFilter {
+ public:
+ virtual ~HWNDMessageFilter() {}
+
+ // A derived class overrides this method to perform filtering of the messages
+ // before the |original_wnd_proc_| sees them. Return true to consume the
+ // message and prevent |original_wnd_proc_| from seeing them at all, false to
+ // allow it to process them.
+ virtual bool FilterMessage(HWND hwnd,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param,
+ LRESULT* l_result) = 0;
+};
+
+// An object that instance-subclasses a window. If the window has already been
+// instance-subclassed, that subclassing is lost.
+class UI_EXPORT HWNDSubclass {
+ public:
+ explicit HWNDSubclass(HWND target);
+ ~HWNDSubclass();
+
+ // HWNDSubclass takes ownership of the filter.
+ void SetFilter(HWNDMessageFilter* filter);
+
+ LRESULT OnWndProc(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param);
+
+ private:
+ HWND target_;
+ scoped_ptr<HWNDMessageFilter> filter_;
+ WNDPROC original_wnd_proc_;
+ ui::ViewProp prop_;
+
+ DISALLOW_COPY_AND_ASSIGN(HWNDSubclass);
+};
+
+} // namespace ui
+
+#endif // UI_BASE_WIN_HWND_SUBCLASS_H_
diff --git a/ui/base/win/hwnd_subclass_unittest.cc b/ui/base/win/hwnd_subclass_unittest.cc
new file mode 100644
index 0000000..bb48f10
--- /dev/null
+++ b/ui/base/win/hwnd_subclass_unittest.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2012 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 "base/basictypes.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/win/window_impl.h"
+#include "ui/base/win/hwnd_subclass.h"
+
+namespace ui {
+
+typedef testing::Test HWNDSubclassTest;
+
+namespace {
+
+class TestWindow : public ui::WindowImpl {
+ public:
+ TestWindow() : saw_message(false) {}
+ virtual ~TestWindow() {}
+
+ bool saw_message;
+
+ private:
+ // Overridden from ui::WindowImpl:
+ virtual BOOL ProcessWindowMessage(HWND window,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param,
+ LRESULT& result,
+ DWORD msg_map_id) OVERRIDE {
+ if (message == WM_NCHITTEST)
+ saw_message = true;
+
+ return FALSE; // Results in DefWindowProc().
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(TestWindow);
+};
+
+class TestMessageFilter : public HWNDMessageFilter {
+ public:
+ TestMessageFilter() : consume_messages(false), saw_message(false) {}
+ virtual ~TestMessageFilter() {}
+
+ // Setting to true causes the filter subclass to stop messages from reaching
+ // the subclassed window procedure.
+ bool consume_messages;
+
+ // True if the message filter saw the message.
+ bool saw_message;
+
+ private:
+ // Overridden from HWNDMessageFilter:
+ virtual bool FilterMessage(HWND hwnd,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param,
+ LRESULT* l_result) OVERRIDE {
+ if (message == WM_NCHITTEST) {
+ saw_message = true;
+ return consume_messages;
+ }
+ return false;
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(TestMessageFilter);
+};
+
+} // namespace
+
+TEST_F(HWNDSubclassTest, Filtering) {
+ TestWindow window;
+ window.Init(NULL, gfx::Rect(0, 0, 100, 100));
+ EXPECT_TRUE(window.hwnd() != NULL);
+
+ {
+ TestMessageFilter* mf = new TestMessageFilter;
+ HWNDSubclass subclass(window.hwnd());
+ subclass.SetFilter(mf);
+
+ // We are not filtering, so both the filter and the window should receive
+ // this message:
+ ::SendMessage(window.hwnd(), WM_NCHITTEST, 0, 0);
+
+ EXPECT_TRUE(mf->saw_message);
+ EXPECT_TRUE(window.saw_message);
+
+ mf->saw_message = false;
+ window.saw_message = false;
+
+ mf->consume_messages = true;
+
+ // We are now filtering, so only the filter should see this message:
+ ::SendMessage(window.hwnd(), WM_NCHITTEST, 0, 0);
+
+ EXPECT_TRUE(mf->saw_message);
+ EXPECT_FALSE(window.saw_message);
+ }
+}
+
+} // namespace ui
diff --git a/ui/gfx/blit.cc b/ui/gfx/blit.cc
index 3a30dfb..5ee6470 100644
--- a/ui/gfx/blit.cc
+++ b/ui/gfx/blit.cc
@@ -126,7 +126,7 @@ void BlitCanvasToCanvas(SkCanvas *dst_canvas,
skia::EndPlatformPaint(dst_canvas);
}
-#if defined(OS_WIN)
+#if defined(OS_WIN) && !defined(USE_AURA)
void ScrollCanvas(SkCanvas* canvas,
const gfx::Rect& clip,
@@ -141,7 +141,7 @@ void ScrollCanvas(SkCanvas* canvas,
ScrollDC(hdc, amount.x(), amount.y(), NULL, &r, NULL, &damaged_rect);
}
-#elif defined(OS_POSIX)
+#elif defined(OS_POSIX) || defined(USE_AURA)
// Cairo has no nice scroll function so we do our own. On Mac it's possible to
// use platform scroll code, but it's complex so we just use the same path
// here. Either way it will be software-only, so it shouldn't matter much.
diff --git a/ui/ui.gyp b/ui/ui.gyp
index 18f1213..a3b7728 100644
--- a/ui/ui.gyp
+++ b/ui/ui.gyp
@@ -256,6 +256,8 @@
'base/win/foreground_helper.h',
'base/win/hwnd_util.cc',
'base/win/hwnd_util.h',
+ 'base/win/hwnd_subclass.cc',
+ 'base/win/hwnd_subclass.h',
'base/win/ime_input.cc',
'base/win/ime_input.h',
'base/win/message_box_win.cc',
diff --git a/ui/ui_unittests.gypi b/ui/ui_unittests.gypi
index 7ba4a7d..b294337 100644
--- a/ui/ui_unittests.gypi
+++ b/ui/ui_unittests.gypi
@@ -112,6 +112,7 @@
# TODO(brettw) re-enable this when the dependencies on WindowImpl are fixed!
'gfx/icon_util_unittest.cc',
'gfx/native_theme_win_unittest.cc',
+ 'base/win/hwnd_subclass_unittest.cc',
],
'include_dirs': [
'../..',
@@ -193,6 +194,8 @@
['use_aura==1', {
'sources!': [
'gfx/screen_unittest.cc',
+ 'gfx/native_theme_win_unittest.cc',
+ 'base/dragdrop/os_exchange_data_win_unittest.cc',
],
}],
['use_aura==1 or toolkit_views==1', {