Keyboard.cpp
/*
$RCSfile: Keyboard.cpp $
$Revision: 1.3 $
$Author: doomer $
$Date: 1997/10/12 01:03:44 $
Copyright (c) 1996 John Dumais
*/
#include "KeyBoard.h"
/*
A vector is a self-expanding data structure used to hold an
unkown number of elements.
*/
static vector<short, allocator<short> > KeyStrokeVector;
/*
This DLL installs a hook function to intercept keystroke events.
The hook function is identified using a handle.
*/
static HHOOK kbdHook;
/*
The window system call this entry point when a process or thread
attaches or detaches the DLL. We use this to erase our keystroke
buffer and remove our keyboard hook when an application detaches
the DLL.
*/
BOOL WINAPI DllMain(HMODULE hModule, DWORD reason, LPVOID reserved){
BOOL returnVal=TRUE;
switch(reason){
case DLL_PROCESS_DETACH:
KeyStrokeVector.erase(KeyStrokeVector.begin(),
KeyStrokeVector.end());
if(kbdHook){
UnhookWindowsHookEx(kbdHook);
}
break;
default:
break;
}
return returnVal;
}
/*
Return the number of keystrokes we have buffered.
*/
long nKeyStrokes(){
return KeyStrokeVector.size();
}
/*
This function fills the supplied array with key codes. The
calling appication needs to allocate the array and indicate the
number of elements the array is capable of holding. This
function will indicate the number of elements inserted into the
supplied array (which can be less than or equal to the number of
elements the array is capable of holding) by changing the value
of the NArrayElements variable,
*/
long getKeyStrokes(short *keyStrokeArray, long *nArrayElements){
long returnVal=0;
long i;
long nReturned=0;
/*
An iterator is an STL construct that allows you to traverse
through a container, regardless of the data structures used
to to implement the container.
*/
vector<short, allocator<short> >::iterator j=KeyStrokeVector.begin();
vector<short, allocator<short> >::iterator last=j;
for(i=0; (i < *nArrayElements) && (j != KeyStrokeVector.end());
i++, j++){
nReturned++;
keyStrokeArray[i] = *j;
}
last += nReturned;
KeyStrokeVector.erase(KeyStrokeVector.begin(), last);
*nArrayElements=nReturned;
return returnVal;
}
/*
After you install a keyboard hook (by calling the
recordKeyStrokes function), the window system will call this
function each time you press a key while the calling application
has the keyboard focus. We check to see if the event has been
caused by a key press event. If so, we append the key code to
the end of the buffer, ten pass the event on.
*/
LRESULT CALLBACK MyKeyboardProc(int code, WPARAM wParam, LPARAM lParam){
if(code >= 0){
if(!(lParam & (1L << 31))){ /* key is being pressed */
KeyStrokeVector.push_back(wParam);
}
}
return CallNextHookEx(kbdHook, code, wParam, lParam);
}
/*
This function installs a keyboard hook, specifying that a
function named MyKeyboardProc is to be called each time a key is
pressed while the calling application has the keyboard focus.
*/
long recordKeyStrokes(){
long returnVal=0;
HMODULE hThisModule;
if(!kbdHook){
hThisModule=GetModuleHandle("KeyBoard");
if(!hThisModule){
return -1;
}
kbdHook=SetWindowsHookEx(WH_KEYBOARD, MyKeyboardProc, hThisModule,
GetCurrentThreadId());
if(!kbdHook){
returnVal = -1;
}
}
return returnVal;
}
/*
This function removes our keyboard hook and erases the contents
of our keystroke buffer.
*/
long stopRecording(){
long returnVal=0;
if(kbdHook){
if(UnhookWindowsHookEx(kbdHook)){
kbdHook=(HHOOK)0;
KeyStrokeVector.erase(KeyStrokeVector.begin(),
KeyStrokeVector.end());
}
else{
returnVal = -1;
}
}
return returnVal;
}
/*
$Log: Keyboard.cpp $
Revision 1.3 1997/10/12 01:03:44 doomer
comments.
Revision 1.2 1996/10/23 03:09:24 doomer
in recordKeyStrokes(), put in a check to prevent calling SetWindowsHookEx()
if we already have a hook installed.
Revision 1.1 1996/10/21 02:36:00 doomer
Initial revision
*/