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 |