| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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 #ifndef CHROME_FRAME_TEST_WIN_EVENT_RECEIVER_H_ | |
| 6 #define CHROME_FRAME_TEST_WIN_EVENT_RECEIVER_H_ | |
| 7 | |
| 8 #include <windows.h> | |
| 9 | |
| 10 #include <string> | |
| 11 #include <vector> | |
| 12 #include <utility> | |
| 13 | |
| 14 #include "base/memory/linked_ptr.h" | |
| 15 #include "base/win/object_watcher.h" | |
| 16 | |
| 17 struct FunctionStub; | |
| 18 | |
| 19 // Listens to WinEvents from the WinEventReceiver. | |
| 20 class WinEventListener { | |
| 21 public: | |
| 22 virtual ~WinEventListener() {} | |
| 23 // Called when an event has been received. |hwnd| is the window that generated | |
| 24 // the event, or null if no window is associated with the event. | |
| 25 virtual void OnEventReceived(DWORD event, HWND hwnd, LONG object_id, | |
| 26 LONG child_id) = 0; | |
| 27 }; | |
| 28 | |
| 29 // Receives WinEvents and forwards them to its listener. The event types the | |
| 30 // listener wants to receive can be specified. | |
| 31 class WinEventReceiver { | |
| 32 public: | |
| 33 WinEventReceiver(); | |
| 34 ~WinEventReceiver(); | |
| 35 | |
| 36 // Sets the sole listener of this receiver. The listener will receive all | |
| 37 // WinEvents of the given event type. Any previous listener will be | |
| 38 // replaced. |listener| should not be NULL. | |
| 39 void SetListenerForEvent(WinEventListener* listener, DWORD event); | |
| 40 | |
| 41 // Same as above, but sets a range of events to listen for. | |
| 42 void SetListenerForEvents(WinEventListener* listener, DWORD event_min, | |
| 43 DWORD event_max); | |
| 44 | |
| 45 // Stops receiving events and forwarding them to the listener. It is | |
| 46 // permitted to call this even if the receiver has already been stopped. | |
| 47 void StopReceivingEvents(); | |
| 48 | |
| 49 private: | |
| 50 bool InitializeHook(DWORD event_min, DWORD event_max); | |
| 51 | |
| 52 static void CALLBACK WinEventHook(WinEventReceiver* me, HWINEVENTHOOK hook, | |
| 53 DWORD event, HWND hwnd, LONG object_id, LONG child_id, | |
| 54 DWORD event_thread_id, DWORD event_time); | |
| 55 | |
| 56 WinEventListener* listener_; | |
| 57 HWINEVENTHOOK hook_; | |
| 58 FunctionStub* hook_stub_; | |
| 59 }; | |
| 60 | |
| 61 // Receives notifications when a window is opened or closed. | |
| 62 class WindowObserver { | |
| 63 public: | |
| 64 virtual ~WindowObserver() {} | |
| 65 virtual void OnWindowOpen(HWND hwnd) = 0; | |
| 66 virtual void OnWindowClose(HWND hwnd) = 0; | |
| 67 }; | |
| 68 | |
| 69 // Notifies observers when windows whose captions match specified patterns | |
| 70 // open or close. When a window opens, its caption is compared to the patterns | |
| 71 // associated with each observer. Observers registered with matching patterns | |
| 72 // are notified of the window's opening and will be notified when the same | |
| 73 // window is closed (including if the owning process terminates without closing | |
| 74 // the window). | |
| 75 // | |
| 76 // Changes to a window's caption while it is open do not affect the set of | |
| 77 // observers to be notified when it closes. | |
| 78 // | |
| 79 // Observers are not notified of the closing of windows that were already open | |
| 80 // when they were registered. | |
| 81 // | |
| 82 // Observers may call AddObserver and/or RemoveObserver during notifications. | |
| 83 // | |
| 84 // Each instance of this class must only be accessed from a single thread, and | |
| 85 // that thread must be running a message loop. | |
| 86 class WindowWatchdog : public WinEventListener { | |
| 87 public: | |
| 88 WindowWatchdog(); | |
| 89 // Register |observer| to be notified when windows matching |caption_pattern| | |
| 90 // and/or |class_name_pattern| are opened or closed. A single observer may be | |
| 91 // registered multiple times. | |
| 92 // If a single window caption and/or class name matches multiple | |
| 93 // registrations of a single observer, the observer will be notified once per | |
| 94 // matching registration. | |
| 95 void AddObserver(WindowObserver* observer, | |
| 96 const std::string& caption_pattern, | |
| 97 const std::string& class_name_pattern); | |
| 98 | |
| 99 // Remove all registrations of |observer|. The |observer| will not be notified | |
| 100 // during or after this call. | |
| 101 void RemoveObserver(WindowObserver* observer); | |
| 102 | |
| 103 private: | |
| 104 class ProcessExitObserver; | |
| 105 | |
| 106 // The Delegate object is actually a ProcessExitObserver, but declaring | |
| 107 // it as such would require fully declaring the ProcessExitObserver class | |
| 108 // here in order for linked_ptr to access its destructor. | |
| 109 typedef std::pair<HWND, linked_ptr<base::win::ObjectWatcher::Delegate> > | |
| 110 OpenWindowEntry; | |
| 111 typedef std::vector<OpenWindowEntry> OpenWindowList; | |
| 112 | |
| 113 struct ObserverEntry { | |
| 114 WindowObserver* observer; | |
| 115 std::string caption_pattern; | |
| 116 std::string class_name_pattern; | |
| 117 OpenWindowList open_windows; | |
| 118 }; | |
| 119 | |
| 120 typedef std::vector<ObserverEntry> ObserverEntryList; | |
| 121 | |
| 122 // WinEventListener implementation. | |
| 123 virtual void OnEventReceived( | |
| 124 DWORD event, HWND hwnd, LONG object_id, LONG child_id); | |
| 125 | |
| 126 static std::string GetWindowCaption(HWND hwnd); | |
| 127 | |
| 128 void HandleOnOpen(HWND hwnd); | |
| 129 void HandleOnClose(HWND hwnd); | |
| 130 void OnHwndProcessExited(HWND hwnd); | |
| 131 | |
| 132 // Returns true if the caption pattern and/or the class name pattern in the | |
| 133 // observer entry structure matches the caption and/or class name passed in. | |
| 134 bool MatchingWindow(const ObserverEntry& entry, | |
| 135 const std::string& caption, | |
| 136 const std::string& class_name); | |
| 137 | |
| 138 ObserverEntryList observers_; | |
| 139 WinEventReceiver win_event_receiver_; | |
| 140 | |
| 141 DISALLOW_COPY_AND_ASSIGN(WindowWatchdog); | |
| 142 }; | |
| 143 | |
| 144 | |
| 145 | |
| 146 #endif // CHROME_FRAME_TEST_WIN_EVENT_RECEIVER_H_ | |
| OLD | NEW |