11.04.2014 Views

Advanced MFC Programming

Advanced MFC Programming

Advanced MFC Programming

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Chapter 13. Adding Special Features to Application<br />

Events recording can be implemented by journal record hook, events playback can be implemented by<br />

journal playback hook. Both of the hooks are system wide, and the hook procedures can reside in either a<br />

DLL or EXE file. The installation of the two hooks is the same with that of keyboard hook, except that we<br />

need to use WH_JOURNALRECORD or WH_JOURNALPLAYBACK parameter when calling function<br />

::SetWindowHookEx(…). Similarly, we need to provide a hook procedure for each installed hook. Usually<br />

the names of journal hook procedures are JournalPlaybackProc(…) and JournalRecordProc(…)<br />

respectively. Like procedure KeyboardProc(…), both functions have three parameters, however, their<br />

meanings are different here:<br />

LRESULT CALLBACK JournalPlaybackProc(int code, WPARAM wParam, LPARAM lParam);<br />

LRESULT CALLBACK JournalRecordProc(int code, WPARAM wParam, LPARAM lParam);<br />

For journal record procedure, we need to record event only when parameter code is HC_ACTION. At this<br />

time, the event message is stored in an EVENTMSG type object, whose address can be obtained from<br />

parameter lParam. Structure EVENTMSG stores hardware message sent to the system message queue, along<br />

with time stamp indicating when the message was posted. We can use the information contained in this<br />

structure to implement playback.<br />

Analyzing Events<br />

Another thing we need to pay attention to is that we need to provide a way of letting the user stop<br />

recording and rendering playback at any time. By default, Windows allows journal hook to be stopped by<br />

any of the following key stroking: CTRL+ESC, ALT+ESC and CTRL+ALT+DEL. Besides the default<br />

feature, it is desirable to provide a build-in function for stopping the journal hook. We can predefine a key<br />

for this purpose. The key pressing events can be trapped by analyzing EVENTMSG type object, which has the<br />

following format:<br />

typedef struct tagEVENTMSG{<br />

UINT message;<br />

UINT paramL;<br />

UINT paramH;<br />

DWORD time;<br />

HWND hwnd;<br />

}EVENTMSG;<br />

Member message specifies event type. In order to trap keystroke, we need to respond to WM_KEYDOWN<br />

activities. In this case, the virtual key code is stored in the lower byte of member paramL.<br />

Sample 13.11\Hook demonstrates journal record and playback hook implementation. Like previous<br />

section, here hook functions are also implemented in the DLL. For this sample, 13.11\Hook is based on<br />

13.10\Hook, and 13.11\HookLib is based on 13.10\HookLib.<br />

For events other than specified key stroke, we need to allocate enough buffers for storing an EVENTMSG<br />

type object and bind them together using linked list. To implement this, we can define a new structure of<br />

our own:<br />

typedef struct tagEVENTNODE<br />

{<br />

EVENTMSG Event;<br />

struct tagEVENTNODE *lpNextEvent;<br />

}EVENTNODE, *LPEVENTNODE;<br />

Pointer lpNextEvent will point to the next EVENTMSG structure. This will form a singly linked list.<br />

The following code fragment shows how events are recorded in journal record hook procedure. Like<br />

other types of hooks, we need to call CallNextHookEx() to pass the event to other hooks if parameter code<br />

is less than 0:<br />

LRESULT CALLBACK JournalRecordProc(int code, WPARAM wParam, LPARAM lParam)<br />

{<br />

LPEVENTNODE lpEventNode;<br />

LPEVENTMSG lpEvent;<br />

420

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!