| // 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/macros.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/gfx/win/window_impl.h" |
| |
| namespace ui { |
| |
| namespace { |
| |
| class TestWindow : public gfx::WindowImpl { |
| public: |
| TestWindow() : saw_message(false) {} |
| ~TestWindow() override {} |
| |
| bool saw_message; |
| |
| private: |
| // Overridden from gfx::WindowImpl: |
| 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) {} |
| ~TestMessageFilter() override {} |
| |
| // 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: |
| 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(HWNDSubclassTest, Filtering) { |
| TestWindow window; |
| window.Init(NULL, gfx::Rect(0, 0, 100, 100)); |
| EXPECT_TRUE(window.hwnd() != NULL); |
| |
| { |
| TestMessageFilter mf; |
| HWNDSubclass::AddFilterToTarget(window.hwnd(), &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); |
| } |
| } |
| |
| TEST(HWNDSubclassTest, FilteringMultipleFilters) { |
| TestWindow window; |
| window.Init(NULL, gfx::Rect(0, 0, 100, 100)); |
| EXPECT_TRUE(window.hwnd() != NULL); |
| |
| { |
| TestMessageFilter mf1; |
| TestMessageFilter mf2; |
| HWNDSubclass::AddFilterToTarget(window.hwnd(), &mf1); |
| HWNDSubclass::AddFilterToTarget(window.hwnd(), &mf2); |
| |
| // We are not filtering, so both the filter and the window should receive |
| // this message: |
| ::SendMessage(window.hwnd(), WM_NCHITTEST, 0, 0); |
| |
| EXPECT_TRUE(mf1.saw_message); |
| EXPECT_TRUE(mf2.saw_message); |
| EXPECT_TRUE(window.saw_message); |
| |
| mf1.saw_message = false; |
| mf2.saw_message = false; |
| window.saw_message = false; |
| |
| mf1.consume_messages = true; |
| |
| // We are now filtering, so only the filter |mf1| should see this message: |
| ::SendMessage(window.hwnd(), WM_NCHITTEST, 0, 0); |
| |
| EXPECT_TRUE(mf1.saw_message); |
| EXPECT_FALSE(mf2.saw_message); |
| EXPECT_FALSE(window.saw_message); |
| } |
| } |
| |
| TEST(HWNDSubclassTest, RemoveFilter) { |
| TestWindow window; |
| window.Init(NULL, gfx::Rect(0, 0, 100, 100)); |
| EXPECT_TRUE(window.hwnd() != NULL); |
| |
| { |
| TestMessageFilter mf1; |
| TestMessageFilter mf2; |
| HWNDSubclass::AddFilterToTarget(window.hwnd(), &mf1); |
| HWNDSubclass::AddFilterToTarget(window.hwnd(), &mf2); |
| |
| ::SendMessage(window.hwnd(), WM_NCHITTEST, 0, 0); |
| EXPECT_TRUE(mf1.saw_message); |
| EXPECT_TRUE(mf2.saw_message); |
| EXPECT_TRUE(window.saw_message); |
| |
| mf1.saw_message = false; |
| mf2.saw_message = false; |
| window.saw_message = false; |
| |
| // Remove a filter and try sending message again. |
| HWNDSubclass::RemoveFilterFromAllTargets(&mf1); |
| ::SendMessage(window.hwnd(), WM_NCHITTEST, 0, 0); |
| EXPECT_FALSE(mf1.saw_message); |
| EXPECT_TRUE(mf2.saw_message); |
| EXPECT_TRUE(window.saw_message); |
| } |
| } |
| |
| } // namespace ui |