1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/base/win/hwnd_subclass.h" 6 7 #include "base/basictypes.h" 8 #include "testing/gtest/include/gtest/gtest.h" 9 #include "ui/gfx/win/window_impl.h" 10 11 namespace ui { 12 13 namespace { 14 15 class TestWindow : public gfx::WindowImpl { 16 public: 17 TestWindow() : saw_message(false) {} 18 virtual ~TestWindow() {} 19 20 bool saw_message; 21 22 private: 23 // Overridden from gfx::WindowImpl: 24 virtual BOOL ProcessWindowMessage(HWND window, 25 UINT message, 26 WPARAM w_param, 27 LPARAM l_param, 28 LRESULT& result, 29 DWORD msg_map_id) OVERRIDE { 30 if (message == WM_NCHITTEST) 31 saw_message = true; 32 33 return FALSE; // Results in DefWindowProc(). 34 } 35 36 DISALLOW_COPY_AND_ASSIGN(TestWindow); 37 }; 38 39 class TestMessageFilter : public HWNDMessageFilter { 40 public: 41 TestMessageFilter() : consume_messages(false), saw_message(false) {} 42 virtual ~TestMessageFilter() {} 43 44 // Setting to true causes the filter subclass to stop messages from reaching 45 // the subclassed window procedure. 46 bool consume_messages; 47 48 // True if the message filter saw the message. 49 bool saw_message; 50 51 private: 52 // Overridden from HWNDMessageFilter: 53 virtual bool FilterMessage(HWND hwnd, 54 UINT message, 55 WPARAM w_param, 56 LPARAM l_param, 57 LRESULT* l_result) OVERRIDE { 58 if (message == WM_NCHITTEST) { 59 saw_message = true; 60 return consume_messages; 61 } 62 return false; 63 } 64 65 DISALLOW_COPY_AND_ASSIGN(TestMessageFilter); 66 }; 67 68 } // namespace 69 70 TEST(HWNDSubclassTest, Filtering) { 71 TestWindow window; 72 window.Init(NULL, gfx::Rect(0, 0, 100, 100)); 73 EXPECT_TRUE(window.hwnd() != NULL); 74 75 { 76 TestMessageFilter mf; 77 HWNDSubclass::AddFilterToTarget(window.hwnd(), &mf); 78 79 // We are not filtering, so both the filter and the window should receive 80 // this message: 81 ::SendMessage(window.hwnd(), WM_NCHITTEST, 0, 0); 82 83 EXPECT_TRUE(mf.saw_message); 84 EXPECT_TRUE(window.saw_message); 85 86 mf.saw_message = false; 87 window.saw_message = false; 88 89 mf.consume_messages = true; 90 91 // We are now filtering, so only the filter should see this message: 92 ::SendMessage(window.hwnd(), WM_NCHITTEST, 0, 0); 93 94 EXPECT_TRUE(mf.saw_message); 95 EXPECT_FALSE(window.saw_message); 96 } 97 } 98 99 TEST(HWNDSubclassTest, FilteringMultipleFilters) { 100 TestWindow window; 101 window.Init(NULL, gfx::Rect(0, 0, 100, 100)); 102 EXPECT_TRUE(window.hwnd() != NULL); 103 104 { 105 TestMessageFilter mf1; 106 TestMessageFilter mf2; 107 HWNDSubclass::AddFilterToTarget(window.hwnd(), &mf1); 108 HWNDSubclass::AddFilterToTarget(window.hwnd(), &mf2); 109 110 // We are not filtering, so both the filter and the window should receive 111 // this message: 112 ::SendMessage(window.hwnd(), WM_NCHITTEST, 0, 0); 113 114 EXPECT_TRUE(mf1.saw_message); 115 EXPECT_TRUE(mf2.saw_message); 116 EXPECT_TRUE(window.saw_message); 117 118 mf1.saw_message = false; 119 mf2.saw_message = false; 120 window.saw_message = false; 121 122 mf1.consume_messages = true; 123 124 // We are now filtering, so only the filter |mf1| should see this message: 125 ::SendMessage(window.hwnd(), WM_NCHITTEST, 0, 0); 126 127 EXPECT_TRUE(mf1.saw_message); 128 EXPECT_FALSE(mf2.saw_message); 129 EXPECT_FALSE(window.saw_message); 130 } 131 } 132 133 TEST(HWNDSubclassTest, RemoveFilter) { 134 TestWindow window; 135 window.Init(NULL, gfx::Rect(0, 0, 100, 100)); 136 EXPECT_TRUE(window.hwnd() != NULL); 137 138 { 139 TestMessageFilter mf1; 140 TestMessageFilter mf2; 141 HWNDSubclass::AddFilterToTarget(window.hwnd(), &mf1); 142 HWNDSubclass::AddFilterToTarget(window.hwnd(), &mf2); 143 144 ::SendMessage(window.hwnd(), WM_NCHITTEST, 0, 0); 145 EXPECT_TRUE(mf1.saw_message); 146 EXPECT_TRUE(mf2.saw_message); 147 EXPECT_TRUE(window.saw_message); 148 149 mf1.saw_message = false; 150 mf2.saw_message = false; 151 window.saw_message = false; 152 153 // Remove a filter and try sending message again. 154 HWNDSubclass::RemoveFilterFromAllTargets(&mf1); 155 ::SendMessage(window.hwnd(), WM_NCHITTEST, 0, 0); 156 EXPECT_FALSE(mf1.saw_message); 157 EXPECT_TRUE(mf2.saw_message); 158 EXPECT_TRUE(window.saw_message); 159 } 160 } 161 162 } // namespace ui 163