license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 1 | // Copyright (c) 2006-2008 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. |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 4 | |
| 5 | #ifndef BASE_EVENT_RECORDER_H_ |
| 6 | #define BASE_EVENT_RECORDER_H_ |
| 7 | |
| 8 | #include <string> |
| 9 | #include <windows.h> |
| 10 | #include "base/basictypes.h" |
| 11 | |
| 12 | namespace base { |
| 13 | |
| 14 | // A class for recording and playing back keyboard and mouse input events. |
| 15 | // |
| 16 | // Note - if you record events, and the playback with the windows in |
| 17 | // different sizes or positions, the playback will fail. When |
| 18 | // recording and playing, you should move the relevant windows |
| 19 | // to constant sizes and locations. |
| 20 | // TODO(mbelshe) For now this is a singleton. I believe that this class |
| 21 | // could be easily modified to: |
| 22 | // support two simultaneous recorders |
| 23 | // be playing back events while already recording events. |
| 24 | // Why? Imagine if the product had a "record a macro" feature. |
| 25 | // You might be recording globally, while recording or playing back |
| 26 | // a macro. I don't think two playbacks make sense. |
| 27 | class EventRecorder { |
| 28 | public: |
| 29 | // Get the singleton EventRecorder. |
| 30 | // We can only handle one recorder/player at a time. |
| 31 | static EventRecorder* current() { |
| 32 | if (!current_) |
| 33 | current_ = new EventRecorder(); |
| 34 | return current_; |
| 35 | } |
| 36 | |
| 37 | // Starts recording events. |
| 38 | // Will clobber the file if it already exists. |
| 39 | // Returns true on success, or false if an error occurred. |
[email protected] | c7f4b627 | 2008-09-30 20:50:51 | [diff] [blame^] | 40 | bool StartRecording(const std::wstring& filename); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 41 | |
| 42 | // Stops recording. |
| 43 | void StopRecording(); |
| 44 | |
| 45 | // Is the EventRecorder currently recording. |
| 46 | bool is_recording() const { return is_recording_; } |
| 47 | |
| 48 | // Plays events previously recorded. |
| 49 | // Returns true on success, or false if an error occurred. |
[email protected] | c7f4b627 | 2008-09-30 20:50:51 | [diff] [blame^] | 50 | bool StartPlayback(const std::wstring& filename); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 51 | |
| 52 | // Stops playback. |
| 53 | void StopPlayback(); |
| 54 | |
| 55 | // Is the EventRecorder currently playing. |
| 56 | bool is_playing() const { return is_playing_; } |
| 57 | |
| 58 | // C-style callbacks for the EventRecorder. |
| 59 | // Used for internal purposes only. |
| 60 | LRESULT RecordWndProc(int nCode, WPARAM wParam, LPARAM lParam); |
| 61 | LRESULT PlaybackWndProc(int nCode, WPARAM wParam, LPARAM lParam); |
| 62 | |
| 63 | private: |
| 64 | // Create a new EventRecorder. Events are saved to the file filename. |
| 65 | // If the file already exists, it will be deleted before recording |
| 66 | // starts. |
| 67 | explicit EventRecorder() |
| 68 | : is_recording_(false), |
| 69 | is_playing_(false), |
| 70 | journal_hook_(NULL), |
[email protected] | c7f4b627 | 2008-09-30 20:50:51 | [diff] [blame^] | 71 | file_(NULL), |
| 72 | playback_first_msg_time_(0), |
| 73 | playback_start_time_(0) { |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 74 | } |
| 75 | ~EventRecorder(); |
| 76 | |
| 77 | static EventRecorder* current_; // Our singleton. |
| 78 | |
| 79 | bool is_recording_; |
| 80 | bool is_playing_; |
| 81 | HHOOK journal_hook_; |
| 82 | FILE* file_; |
| 83 | EVENTMSG playback_msg_; |
| 84 | int playback_first_msg_time_; |
| 85 | int playback_start_time_; |
| 86 | |
| 87 | DISALLOW_EVIL_CONSTRUCTORS(EventRecorder); |
| 88 | }; |
| 89 | |
| 90 | } // namespace base |
| 91 | |
| 92 | #endif // BASE_EVENT_RECORDER_H_ |