#ifndef KM_RW_CWFI
#define KM_RW_CWFI
//HOOK DECLARATIONS:
//Hook processing functions are global:
LRESULT CALLBACK KMRW_GetMsgProc(int
code,WPARAM wparam,LPARAM lparam);
LRESULT CALLBACK KMRW_LLKBHookProc(int
code,WPARAM wparam,LPARAM lparam);
LRESULT CALLBACK KMRW_JournalRecordProc(int
code,WPARAM wparam,LPARAM lparam);
LRESULT CALLBACK KMRW_JournalPlaybackProc(int
code,WPARAM wparam,LPARAM lparam);
// Framework interface class:
//All hook handles are wrapped in this class.
class CWFI {
public:
CKMRWDlg * pWnd;
void InitParent(CKMRWDlg * a_pWnd) {pWnd=a_pWnd;
HookupMsgProc(); HookupLLKB();}
HHOOK MsgProcHookHandle;
HHOOK LLKBHookHandle;
HHOOK RecHookHandle;
HHOOK PlayHookHandle;
//This makes it easier for outside code to
install and remove hooks.
void HookupLLKB(){ LLKBHookHandle=SetWindowsHookEx(WH_KEYBOARD_LL,::KMRW_LLKBHookProc,AfxGetApp()->m_hInstance,0);
}
void UnhookLLKB(){
UnhookWindowsHookEx(LLKBHookHandle); }
void HookupMsgProc(){ MsgProcHookHandle=SetWindowsHookEx(WH_GETMESSAGE,::KMRW_GetMsgProc,AfxGetApp()->m_hInstance,0);
}
void UnhookMsgProc(){
UnhookWindowsHookEx(MsgProcHookHandle); }
void HookupRecord(){ RecHookHandle=SetWindowsHookEx(WH_JOURNALRECORD,::KMRW_JournalRecordProc,AfxGetApp()->m_hInstance,0);
}
void UnhookRecord(){
UnhookWindowsHookEx(RecHookHandle); }
void HookupPlay(){ PlayHookHandle=SetWindowsHookEx(WH_JOURNALPLAYBACK,::KMRW_JournalPlaybackProc,AfxGetApp()->m_hInstance,0);
}
void UnhookPlay(){
UnhookWindowsHookEx(PlayHookHandle); }
CWFI() : pWnd(0) {}
~CWFI() {UnhookRecord(); UnhookPlay(); UnhookMsgProc(); UnhookLLKB();}
}cwfi; // (GLOBAL OBJECT)
//HOOK DEFINITIONS:
//-------------------------------------------------------------------------------------------------------------------
LRESULT CALLBACK KMRW_JournalRecordProc(int
code,WPARAM wparam,LPARAM lparam){
// Recording hook processing:
// This is what they tell us to do:
if(code<0) return
::CallNextHookEx(cwfi.RecHookHandle,code,wparam,lparam);
// Delegates to CKMRWDlg member function,
which would extract and record the message:
if(cwfi.pWnd) cwfi.pWnd->ProcessRecordHook(code,wparam,lparam);
//Then let it go down the chain:
return ::CallNextHookEx(cwfi.RecHookHandle,code,wparam,lparam);
}
//-------------------------------------------------------------------------------------------------------------------
LRESULT CALLBACK KMRW_JournalPlaybackProc(int
code,WPARAM wparam,LPARAM lparam){
// Playback hook processing:
// Delegates to CKMRWDlg member function, which would implant
previously recorded message:
if(cwfi.pWnd)
return cwfi.pWnd->ProcessPlayHook(code,wparam,lparam);
return 0;
}
//-------------------------------------------------------------------------------------------------------------------
LRESULT CALLBACK KMRW_GetMsgProc(int code,WPARAM wparam,LPARAM
lparam){
// The only reason this hook is used is to
detect WM_CANCELJOURNAL message,
// which is sent by the system when Ctrl+Alt+Del or similar is done.
It allows
// to find out that it happened and update UI accordingly.
if (code <0)
return
CallNextHookEx(cwfi.MsgProcHookHandle,code,wparam,lparam);
if (code==HC_ACTION)
{
MSG * pMsg=(MSG*)lparam;
if(pMsg->message==WM_CANCELJOURNAL)
// interrupted by system
cwfi.pWnd->InterruptionHandler(0);
return 0;
}
return ::CallNextHookEx(cwfi.MsgProcHookHandle,code,wparam,lparam);
}
//-------------------------------------------------------------------------------------------------------------------
LRESULT CALLBACK KMRW_LLKBHookProc(int
code,WPARAM wparam,LPARAM lparam){
//Low-Level keyboard processing:
//It is for the user to be able to interrupt playback or recording.
//Catch only <Ctrl+Break> here,
//for everything else call CallNextHookEx()
//To avoid double processing, interrupt only when key is down:
if(wparam==WM_KEYDOWN){
if( ((KBDLLHOOKSTRUCT *)lparam)->vkCode==VK_CANCEL
) {cwfi.pWnd->InterruptionHandler(1); return
1;}
}
return ::CallNextHookEx(cwfi.LLKBHookHandle,code,wparam,lparam);
}
//-------------------------------------------------------------------------------------------------------------------
#endif