home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_C
/
CENVIW9.ZIP
/
KEYPUSH.LIB
< prev
next >
Wrap
Text File
|
1994-03-08
|
15KB
|
407 lines
// KeyPush.lib - Windows routines to control, or mimic, the pushing of
// ver.1 keys on the keyboard. This is one method of controlling
// windows applications. The functions in this library work
// by sending keyboard messages to the focus window as if
// the key messages were actually being sent by Windows.
//
//**** KeyPushFocusID(): Select focus window specification for this library
// SYNTAX: int KeyPushFocusID(NULL) // this is the default
// int KeyPushFocusID(string TopLevelTitle)
// int KeyPushFocusID(int TopLevelHandle)
// int KeyPushFocusID(int FocusWindowHandle)
// WHERE: NULL: if NULL or 0 then will always send to the currently active focus window
// TopLevelTitle: ascii string - will send to focus window of this top-level window
// TopLevelHandle: handle for top-level window - will send to focus window of this top-level window
// FocusWindowHandle: will send directly to this window handle
// RETURN: Return window that would get focus NOW according to this setting, which
// may be NULL if this setting wouldn't work
// NOTE: For TopLevelTitle and TopLevelHandle methods, these library routines
// may need to temporarily alter the activation of different windows, which
// will look messy if the window you're sending to is not currently the
// active window. In these situations, or if you're sending lots of
// KeyPushxxx messages, you may want to make the application active
// first or get the FocusWindowHandle if the window won't change.
// If this function is never called then defaults to NULL: active focus window.
//
//
//**** KeyStroke(): Press and release a key or combination of keys
// SYNTAX: int KeyStroke([Holdkey1,HoldKey2,HoldKey3...,]byte Character)
// int KeyStroke([Holdkey1,HoldKey2,HoldKey3...,]int VirtualKeyCode)
// int KeyStroke([Holdkey1,HoldKey2,HoldKey3...,]string KeyString)
// WHERE: Holdkey...: mimic that these keys are pressed before KeyCode or KeyString, and then
// will press and release KeyCode or KeyString, and then will release
// HoldKeys in reverse order.
// Character: ascii character to send
// VirtualKeyCode: one of the VK_ key codes (see below)
// KeyString: Ascii string to send
// RETURN: Return handle keys were sent to; 0 if no handle found
// EXAMPLES: To press the 'S' key: KeyStroke('S');
// To type a sentence: KeyStroke("On top of Old Smokey!\r");
// To type Alt-F1: KeyStroke(VK_ALT,VK_F1);
// To simulate Ctl-Alt-R: KeyStroke(VK_CONTROL,VK_ALT,'R');
//
//
//**** SpeedKeys(): Send character messages
// SYNTAX: int SpeedKeys(string AsciiString[,DelayBetweenKeys])
// int SpeedKeys(byte Character[,DelayBetweenKeys])
// WHERE: AsciiString: string of characters to send
// Character: single character to send
// DelayBetweenKeys: Approximate time, in milliseconds, to wait after
// sending each key message
// NOTE: Speed keys sends only WM_CHAR messages to an application and is much
// faster than KeyStroke(), but should only be used for regular ascii
// strings passed to applications that don't need to for each specific
// keystroke. So, if KeyStroke() is too slow and you're entering a
// stretch of plain text, then use this function.
//
//
//**** VKeyDown(): Press down a key (no release yet)
// SYNTAX: int VKeyDown(int KeyCode)
// WHERE: KeyCode: Virtual VK_ key or character key
// RETURN: Return handle keys were sent to; 0 if no handle found
//
//
//**** VKeyUP(): Release a key (that has been pressed down)
// SYNTAX: int VKeyUP(int KeyCode)
// WHERE: KeyCode: Virtual VK_ key or character key
// RETURN: Return handle keys were sent to; 0 if no handle found
//
//
//***** GetFocus(): Get window with the input focus
// SYNTAX: int GetFocus()
// RETURN: Return handle of window that owns keyboard focus
// NOTE: This will return the handle of window that actually has Windows
// keyboard focus, not necessarily that window that was described
// in the call to KeyPushFocusID()
//
//
#define VK_LBUTTON 0x01
#define VK_RBUTTON 0x02
#define VK_CANCEL 0x03
#define VK_MBUTTON 0x04
#define VK_BACK 0x08
#define VK_TAB 0x09
#define VK_CLEAR 0x0C
#define VK_RETURN 0x0D
#define VK_SHIFT 0x10
#define VK_CONTROL 0x11
#define VK_MENU 0x12
#define VK_ALT VK_MENU
#define VK_PAUSE 0x13
#define VK_CAPITAL 0x14
#define VK_ESCAPE 0x1B
#define VK_SPACE 0x20
#define VK_PRIOR 0x21
#define VK_NEXT 0x22
#define VK_END 0x23
#define VK_HOME 0x24
#define VK_LEFT 0x25
#define VK_UP 0x26
#define VK_RIGHT 0x27
#define VK_DOWN 0x28
#define VK_SELECT 0x29
#define VK_PRINT 0x2A
#define VK_EXECUTE 0x2B
#define VK_SNAPSHOT 0x2C
#define VK_INSERT 0x2D
#define VK_DELETE 0x2E
#define VK_HELP 0x2F
/* VK_A thru VK_Z are the same as their ASCII equivalents: 'A' thru 'Z' */
/* VK_0 thru VK_9 are the same as their ASCII equivalents: '0' thru '9' */
#define VK_NUMPAD0 0x60
#define VK_NUMPAD1 0x61
#define VK_NUMPAD2 0x62
#define VK_NUMPAD3 0x63
#define VK_NUMPAD4 0x64
#define VK_NUMPAD5 0x65
#define VK_NUMPAD6 0x66
#define VK_NUMPAD7 0x67
#define VK_NUMPAD8 0x68
#define VK_NUMPAD9 0x69
#define VK_MULTIPLY 0x6A
#define VK_ADD 0x6B
#define VK_SEPARATOR 0x6C
#define VK_SUBTRACT 0x6D
#define VK_DECIMAL 0x6E
#define VK_DIVIDE 0x6F
#define VK_F1 0x70
#define VK_F2 0x71
#define VK_F3 0x72
#define VK_F4 0x73
#define VK_F5 0x74
#define VK_F6 0x75
#define VK_F7 0x76
#define VK_F8 0x77
#define VK_F9 0x78
#define VK_F10 0x79
#define VK_F11 0x7A
#define VK_F12 0x7B
#define VK_F13 0x7C
#define VK_F14 0x7D
#define VK_F15 0x7E
#define VK_F16 0x7F
#define VK_NUMLOCK 0x90
#include <Message.lib>
#include <WinTools.lib>
KeyPushFocusID(pFocusID)
{
if ( !pFocusID ) {
gFocusID = 0;
} else if ( 0 != DataDimension(pFocusID) ) {
// find window based on string
if ( !(gFocusID = GetWindowHandle(pFocusID)) )
return 0;
} else {
gFocusID = pFocusID;
}
// gFocusID parameter is set. Return window handle as regular KeyPush calls would
KeyPushInitialize();
KeyPushTerminate();
return gKPFocusWindow;
}
KeyStroke(pKey1,pKey2,pKey3/*etc...*/)
{
if ( KeyPushInitialize() ) {
lArgCount = va_arg();
// if more than one parameter, then hold down all but the last one
for ( lHoldKey = 1; lHoldKey < lArgCount; lHoldKey++ )
VKeyDown(va_arg(lHoldKey-1));
// keystroke on remaining key
lKey = va_arg(lArgCount-1);
// Treat differently depending on whether Virtual Key Code, char, or string
if ( CMM_BYTE == DataType(lKey) ) {
if ( 1 == DataDimension(lKey) ) {
// send entire string one character at a time
for ( li = 0; lKey[li]; li++ )
CharacterStroke(lKey[li]);
} else {
// send a single character out the port
CharacterStroke(lKey);
}
} else {
// simply a virtual key code
VKeyDown(lKey);
VKeyUp(lKey);
}
// release all the keys that were held down
for ( lHoldKey = 1; lHoldKey < lArgCount; lHoldKey++ )
VKeyUp(va_arg(lHoldKey-1));
}
KeyPushTerminate();
return gKPFocusWindow;
}
VKeyDown(pKeyCode)
{
if ( KeyPushInitialize() ) {
// Save the current state of the 256-byte keyboard buffer
lKeyBuffer = GetKeyboardState();
// build hi word of lParam for the WM_KEYDOWN or WM_SYSKEYDOWN message
// 1: Get Scan Code for this virtual key
lHiWord = MapVirtualKey(pKeyCode,0);
// 2: Set bit for if this is an extended key
if ( (VK_PRIOR <= pKeyCode && pKeyCode <= VK_HELP)
|| (VK_F1 <= pKeyCode && pKeyCode <= VK_F16) )
lHiWord |= 0x100;
// 3: If ALT key is down but not the control key, then set that bit
// and change message to WM_SYSKEYDOWN
if ( (pKeyCode == VK_ALT || (GetKeyState(VK_ALT) & 0x80) )
&& !(GetKeyState(VK_CONTROL) & 0x80) )
lHiWord |= 0x2000, lMsg = WM_SYSKEYDOWN;
else
lMsg = WM_KEYDOWN;
// save in lKeyBuffer that this key is now down
lKeyBuffer[pKeyCode] = (lKeyBuffer[pKeyCode] ^ 0x01) | 0x80;
SetKeyboardState(lKeyBuffer);
// send message to window that this key is being pressed
PostMessage(gKPFocusWindow,lMsg,pKeyCode,1,lHiWord);
}
KeyPushTerminate();
return gKPFocusWindow;
}
VKeyUp(pKeyCode)
{
if ( KeyPushInitialize() ) {
// Save the current state of the 256-byte keyboard buffer
lKeyBuffer = GetKeyboardState();
// build hi word of lParam for the WM_KEYUP or WM_SYSKEYUP message
// 1: Get Scan Code for this virtual key
lHiWord = MapVirtualKey(pKeyCode,0);
// 2: Set bit for if this is an extended key
if ( (VK_PRIOR <= pKeyCode && pKeyCode <= VK_HELP)
|| (VK_F1 <= pKeyCode && pKeyCode <= VK_F16) )
lHiWord |= 0x100;
// 3: If ALT key is down but not the control key, then set that bit
// and change message to WM_SYSKEYDOWN
if ( (pKeyCode == VK_ALT || (GetKeyState(VK_ALT) & 0x80) )
&& !(GetKeyState(VK_CONTROL) & 0x80) )
lHiWord |= 0x2000, lMsg = WM_SYSKEYUP;
else
lMsg = WM_KEYUP;
// 4: set hi 2 bits that key WAS down
lHiWord |= 0xC000;
// save in lKeyBuffer that this key is now up
lKeyBuffer[pKeyCode] &= 0x7F;
SetKeyboardState(lKeyBuffer);
// send message to window that this key is being pressed
PostMessage(gKPFocusWindow,lMsg,pKeyCode,1,lHiWord);
}
KeyPushTerminate();
return gKPFocusWindow;
}
SpeedKeys(pAsciiString,pDelayBetweenKeys)
{
if ( KeyPushInitialize() ) {
// if just one character then only send that
if ( 1 == DataDimension(pAsciiString) ) { lChar = pAsciiString; }
else { lChar[1] = '\0'; lChar[0] = pAsciiString; }
for ( ; lChar[0]; lChar++ ) {
PostMessage(gKPFocusWindow,WM_CHAR,lChar[0],1,0);
// DelayBetweenKeys is optional. If not supplied then no delay
if ( 1 < va_arg() )
suspend(pDelayBetweenKeys);
}
}
KeyPushTerminate();
return gKPFocusWindow;
}
/***********************************************************
*** PRIVATE UTILITIES USED BY THE ABOVE PUBLIC ROUTINES ***
***********************************************************/
gFocusID = 0;
gKeyPushInitializeDepth = 0; // keep track how many times recursively called
gKPFocusWindow; // KeyPushInitialize sets to window
gKPSaveActiveWindow = 0;
KeyPushInitialize()
{
// keep track of how many times called. get actual ID to send to on first
// level, on recursive calls revert to first return. If need to activate
// window then do so. Return FALSE for failure, else non-false is TRUE
if ( 0 == gKeyPushInitializeDepth++ ) {
gKPSaveActiveWindow = 0; // assume don't need to change focus
if ( !gFocusID ) {
// take whatever is the focus window
gKPFocusWindow = GetFocus();
} else if ( !IsWindow(gFocusID) ) {
gKPFocusWindow = 0; // gFocusID is not valid
} else if ( GetParent(gFocusID) ) {
gKPFocusWindow = gFocusID; // this isn't parent, so is actual window to send to
} else {
// this is a top level window, and so it must be active and then
// take its focus window
if ( gFocusID != (lActive=GetActiveWindow()) ) {
// this isn't active, and so must make it active
gKPSaveActiveWindow = lActive;
SetActiveWindow(gFocusID);
}
gKPFocusWindow = GetFocus();
}
}
return gKPFocusWindow;
}
KeyPushTerminate()
{
// undo what KeyPushInitialize did. restore active window if KeyPushInitialize()
// activated it. Must call same number of times as KeyPushInitialize.
if ( 0 == --gKeyPushInitializeDepth ) {
if ( gKPSaveActiveWindow ) {
SetActiveWindow(gKPSaveActiveWindow);
}
}
}
CharacterStroke(pChar) // press this character. This is only tricky in that
{ // must check SHIFT state for alphabetic characters
// Get virtual codes for this character
lVKeyState = DynamicLink("KEYBOARD","VKKEYSCAN",SWORD16,PASCAL,pChar)
if ( -1 != lVKeyState ) {
lVKey = lVKeyState & 0xFF;
switch( lVKeyState >> 8 ) {
case 0: // no shift state
case 1: // shift state
if ( (0 != (GetKeyState(VK_SHIFT) & 0x80)) ^
(0 != (GetKeyState(VK_CAPITAL) & 0x01)) ^
(0 != (lVKeyState & 0x100)) ) {
// need to toggle the shift key to change case of this character
if ( GetKeyState(VK_SHIFT) & 0x80 )
VKeyUp(VK_SHIFT), KeyStroke(lVKey), VKeyDown(VK_SHIFT);
else
KeyStroke(VK_SHIFT,lVKey);
} else
KeyStroke(lVKey);
break;
case 2: // control character
KeyStroke(VK_CONTROL,lVKey);
break;
case 6: // control + alt
KeyStroke(VK_CONTROL,VK_ALT,lVKey);
break;
case 7: // SHIFT+CONTROL+ALT
KeyStroke(VK_SHIFT,VK_CONTROL,VK_ALT,lVKey);
break;
default: // unknown
break;
}
}
}
GetKeyboardState() // return 256 byte buffer for current keyboard state
{
lKeyBuf[255] = '\0'; // initialize a 256-byte array
DynamicLink("USER","GETKEYBOARDSTATE",SWORD16,PASCAL,lKeyBuf);
return lKeyBuf;
}
SetKeyboardState(pKeyBuf) // set the 256 byte buffer for current keyboard state
{
DynamicLink("USER","SETKEYBOARDSTATE",SWORD16,PASCAL,pKeyBuf);
}
GetKeyState(pVKey)
{
return( DynamicLink("USER","GETKEYSTATE",SWORD16,PASCAL,pVKey) );
}
MapVirtualKey(pCode,pMapType)
{
return( DynamicLink("KEYBOARD","MAPVIRTUALKEY",UWORD16,PASCAL,pCode,pMapType) );
}
GetParent(pHwnd)
{
return DynamicLink("USER","GETPARENT",UWORD16,PASCAL,pHwnd);
}