home *** CD-ROM | disk | FTP | other *** search
- // KeyPush.lib - Windows routines to control, or mimic, the pushing of
- // 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.
- //
- //------------------------------- KeyStroke() -------------------------------
- // KeyStroke([Holdkey1,HoldKey2,HoldKey3...]Character)
- // KeyStroke([Holdkey1,HoldKey2,HoldKey3...]VirtualKeyCode)
- // KeyStroke([Holdkey1,HoldKey2,HoldKey3...]KeyString)
- // - Press and release a key or keys. If HoldKeys are given then will 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.
- // Examples: To press the 'S' key: KeyStroke('S');
- // To type a sentence: KeyStroke("On top of Old Smokey!");
- // To type Alt-F1: KeyStroke(VK_ALT,VK_F1);
- // To simulate Ctl-Alt-R: KeyStroke(VK_CONTROL,VK_ALT,'R');
- //
- //------------------------------- VKeyDown() -------------------------------
- // VKeyDown(KeyCode)
- // - Press virtual key for Window.
- // Key is not released.
- // Example: KeyDown(VK_SHIFT)
- //
- //------------------------------- VKeyUp() -------------------------------
- // VKeyUp(KeyCode)
- // - Release key for focus Window.
- // Example: KeyUp(VK_SHIFT)
- //
- //------------------------------- SpeedKeys() -------------------------------
- // SpeedKeys(AsciiString[,DelayBetweenKeys])
- // Speed keys sends only WM_CHAR messages to an application and is much
- // faster thatn 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. If DelayBetweenKeys
- // parameter is given then this is how many milliseconds to wait between
- // each keystroke.
- //
- //----------------------------- FocusWindow -------------------------------
- // FocusWindow
- // This integer controls the value return by GetFocus(). If it is zero
- // Then GetFocus() will query Windows for whatever Window has the
- // current focus, else GetFocus() return FocusWindow.
- //
- //------------------------------ GetFocus() -------------------------------
- // GetFocus()
- // Return the window handle that keystrokes are to be sent to. If
- // FocusWindow is non-zero then this returns FocusWindow, else this
- // queries Windows for the handle of the window with the current focus.
-
-
- FocusWindow = 0; // If this is 0, then will send messages to whatever window
- // has the focus. If this is not-zero then will send
- // the FocuseWindow window handle.
-
- #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
-
-
- KeyStroke(Key1,Key2,Key3/*etc...*/)
- {
- _argCount = va_arg();
- // if more than one parameter, then hold down all but the last one
- for ( k = 1; k < _argCount; k++ )
- VKeyDown(va_arg(k-1));
-
- _key = va_arg(_argCount-1);
- // Treat differently depending on whether Virtual Key Code, char, or string
- if ( CMM_BYTE == DataType(_key) ) {
- if ( 1 == DataDimension(_key) ) {
- // send entire string one character at a time
- for ( k = 0; _key[k]; k++ )
- CharacterStroke(_key[k]);
- } else {
- // send a single character out the port
- CharacterStroke(_key);
- }
- } else {
- // simply a virtual key code
- VKeyDown(_key);
- VKeyUp(_key);
- }
-
- // if more than one parameter, then reverse release all but the last one
- for ( k = 1; k < _argCount; k++ )
- VKeyUp(va_arg(_argCount-k-1));
- }
-
- VKeyDown(KeyCode)
- {
- // Save the current state of the 256-byte keyboard buffer
- _keyBuffer = GetKeyboardState();
-
- // build hi word of lParam for the WM_KEYDOWN or WM_SYSKEYDOWN message
- // 1: Get Scan Code for this virtual key
- _HiWord = MapVirtualKey(KeyCode,0);
- // 2: Set bit for if this is an extended key
- if ( (VK_PRIOR <= KeyCode && KeyCode <= VK_HELP)
- || (VK_F1 <= KeyCode && KeyCode <= VK_F16) )
- _HiWord |= 0x100;
- // 3: If ALT key is down but not the control key, then set that bit
- // and change message to WM_SYSKEYDOWN
- if ( (KeyCode == VK_ALT || (GetKeyState(VK_ALT) & 0x8000) )
- && !(GetKeyState(VK_CONTROL) & 0x8000) )
- _HiWord |= 0x2000, _message = WM_SYSKEYDOWN;
- else
- _message = WM_KEYDOWN;
-
- // save in _keyBuffer that this key is now down
- _keyBuffer[KeyCode] = (_KeyBuffer[KeyCode] ^ 0x01) | 0x80;
- SetKeyboardState(_keyBuffer);
-
- // send message to window that this key is being pressed
- PostMessage(GetFocus(),_message,KeyCode,1,_HiWord);
- }
-
-
- VKeyUp(KeyCode)
- {
- // Save the current state of the 256-byte keyboard buffer
- _keyBuffer = GetKeyboardState();
-
- // build hi word of lParam for the WM_KEYUP or WM_SYSKEYUP message
- // 1: Get Scan Code for this virtual key
- _HiWord = MapVirtualKey(KeyCode,0);
- // 2: Set bit for if this is an extended key
- if ( (VK_PRIOR <= KeyCode && KeyCode <= VK_HELP)
- || (VK_F1 <= KeyCode && KeyCode <= VK_F16) )
- _HiWord |= 0x100;
- // 3: If ALT key is down but not the control key, then set that bit
- // and change message to WM_SYSKEYDOWN
- if ( (KeyCode == VK_ALT || (GetKeyState(VK_ALT) & 0x8000) )
- && !(GetKeyState(VK_CONTROL) & 0x8000) )
- _HiWord |= 0x2000, _message = WM_SYSKEYUP;
- else
- _message = WM_KEYUP;
- // 4: set hi 2 bits that key WAS down
- _HiWord |= 0xC000;
-
- // save in _keyBuffer that this key is now up
- _keyBuffer[KeyCode] &= 0x7F;
- SetKeyboardState(_keyBuffer);
-
- // send message to window that this key is being pressed
- PostMessage(GetFocus(),_message,KeyCode,1,_HiWord);
- }
-
- SpeedKeys(AsciiString,DelayBetweenKeys)
- {
- _focus = GetFocus();
- for ( c = AsciiString; c[0]; c++ ) {
- PostMessage(_focus,WM_CHAR,c[0],1,0);
- // DelayBetweenKeys is optional. If not supplied then no delay
- if ( 1 < va_arg() )
- suspend(DelayBetweenKeys);
- }
- }
-
-
- /***********************************************************
- *** PRIVATE UTILITIES USED BY THE ABOVE PUBLIC ROUTINES ***
- ***********************************************************/
-
- CharacterStroke(c) // press this character. This is only tricky in that
- { // must check SHIFT state for alphabetic characters
- // Get virtual codes for this character
- _vkeystate = DynamicLink("KEYBOARD","VKKEYSCAN",SWORD16,PASCAL,c)
- if ( -1 != _vkeystate ) {
- vkey = _vkeystate & 0xFF;
- switch( _vkeystate >> 8 ) {
- case 0: // no shift state
- case 1: // shift state
- if ( (0 != (GetKeyState(VK_SHIFT) & 0x80)) ^
- (0 != (GetKeyState(VK_CAPITAL) & 0x01)) ^
- (0 != (_vkeystate & 0x100)) ) {
- // need to toggle the shift key to change case of this character
- if ( GetKeyState(VK_SHIFT) & 0x80 )
- VKeyUp(VK_SHIFT), KeyStroke(vkey), VKeyDown(VK_SHIFT);
- else
- KeyStroke(VK_SHIFT,vkey);
- } else
- KeyStroke(vkey);
- break;
- case 2: // control character
- KeyStroke(VK_CONTROL,vkey);
- break;
- case 6: // control + alt
- KeyStroke(VK_CONTROL,VK_ALT,vkey);
- break;
- case 7: // SHIFT+CONTROL+ALT
- KeyStroke(VK_SHIFT,VK_CONTROL,VK_ALT,vkey);
- break;
- default: // unknown
- break;
- }
- }
- }
-
- GetKeyboardState() // return 256 byte buffer for current keyboard state
- {
- _keyBuf[255] = '\0'; // initialize a 256-byte array
- DynamicLink("USER","GETKEYBOARDSTATE",SWORD16,PASCAL,_keyBuf);
- return(_KeyBuf);
- }
-
- SetKeyboardState(_keyBuf) // set the 256 byte buffer for current keyboard state
- {
- DynamicLink("USER","SETKEYBOARDSTATE",SWORD16,PASCAL,_keyBuf);
- }
-
- GetKeyState(VKey)
- {
- return( DynamicLink("USER","GETKEYSTATE",SWORD16,PASCAL,VKey) );
- }
-
- MapVirtualKey(wCode,wMapType)
- {
- return( DynamicLink("KEYBOARD","MAPVIRTUALKEY",UWORD16,PASCAL,wCode,wMapType) );
- }
-
- GetFocus() // return handle of Window with the focus
- {
- return( FocusWindow
- ? FocusWindow
- : DynamicLink("USER","GETFOCUS",UWORD16,PASCAL) );
- }
-