home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource1 / cenvew / keypush.lib < prev    next >
Encoding:
Text File  |  1993-10-24  |  10.7 KB  |  294 lines

  1. // KeyPush.lib - Windows routines to control, or mimic, the pushing of
  2. //               keys on the keyboard.  This is one method of controlling
  3. //               windows applications.  The functions in this library work
  4. //               by sending keyboard messages to the focus window as if
  5. //               the key messages were actually being sent by Windows.
  6. //
  7. //------------------------------- KeyStroke() -------------------------------
  8. //  KeyStroke([Holdkey1,HoldKey2,HoldKey3...]Character)
  9. //  KeyStroke([Holdkey1,HoldKey2,HoldKey3...]VirtualKeyCode)
  10. //  KeyStroke([Holdkey1,HoldKey2,HoldKey3...]KeyString)
  11. //   - Press and release a key or keys.  If HoldKeys are given then will mimic
  12. //     that these keys are pressed before KeyCode or KeyString, and then
  13. //     will press and release KeyCode or KeyString, and then will release
  14. //     HoldKeys in reverse order.
  15. //   Examples: To press the 'S' key: KeyStroke('S');
  16. //     To type a sentence: KeyStroke("On top of Old Smokey!");
  17. //     To type Alt-F1: KeyStroke(VK_ALT,VK_F1);
  18. //     To simulate Ctl-Alt-R: KeyStroke(VK_CONTROL,VK_ALT,'R');
  19. //
  20. //------------------------------- VKeyDown() -------------------------------
  21. //  VKeyDown(KeyCode)
  22. //   - Press virtual key for Window.
  23. //     Key is not released.
  24. //   Example: KeyDown(VK_SHIFT)
  25. //
  26. //------------------------------- VKeyUp() -------------------------------
  27. //  VKeyUp(KeyCode)
  28. //   - Release key for focus Window.
  29. //   Example: KeyUp(VK_SHIFT)
  30. //
  31. //------------------------------- SpeedKeys() -------------------------------
  32. //  SpeedKeys(AsciiString[,DelayBetweenKeys])
  33. //     Speed keys sends only WM_CHAR messages to an application and is much
  34. //     faster thatn KeyStroke(), but should only be used for regular ascii
  35. //     strings passed to applications that don't need to for each specific
  36. //     keystroke.  So, if KeyStroke() is too slow and you're entering a
  37. //     stretch of plain text, then use this function. If DelayBetweenKeys
  38. //     parameter is given then this is how many milliseconds to wait between
  39. //     each keystroke.
  40. //
  41. //----------------------------- FocusWindow -------------------------------
  42. //  FocusWindow
  43. //     This integer controls the value return by GetFocus().  If it is zero
  44. //     Then GetFocus() will query Windows for whatever Window has the
  45. //     current focus, else GetFocus() return FocusWindow.
  46. //
  47. //------------------------------ GetFocus() -------------------------------
  48. //  GetFocus()
  49. //     Return the window handle that keystrokes are to be sent to.  If
  50. //     FocusWindow is non-zero then this returns FocusWindow, else this
  51. //     queries Windows for the handle of the window with the current focus.
  52.  
  53.  
  54. FocusWindow = 0; // If this is 0, then will send messages to whatever window
  55.                  // has the focus.  If this is not-zero then will send
  56.                  // the FocuseWindow window handle.
  57.  
  58. #define VK_LBUTTON          0x01
  59. #define VK_RBUTTON          0x02
  60. #define VK_CANCEL           0x03
  61. #define VK_MBUTTON          0x04
  62. #define VK_BACK             0x08
  63. #define VK_TAB              0x09
  64. #define VK_CLEAR            0x0C
  65. #define VK_RETURN           0x0D
  66. #define VK_SHIFT            0x10
  67. #define VK_CONTROL          0x11
  68. #define VK_MENU             0x12
  69. #define VK_ALT              VK_MENU
  70. #define VK_PAUSE            0x13
  71. #define VK_CAPITAL          0x14
  72. #define VK_ESCAPE           0x1B
  73. #define VK_SPACE            0x20
  74. #define VK_PRIOR            0x21
  75. #define VK_NEXT             0x22
  76. #define VK_END              0x23
  77. #define VK_HOME             0x24
  78. #define VK_LEFT             0x25
  79. #define VK_UP               0x26
  80. #define VK_RIGHT            0x27
  81. #define VK_DOWN             0x28
  82. #define VK_SELECT           0x29
  83. #define VK_PRINT            0x2A
  84. #define VK_EXECUTE          0x2B
  85. #define VK_SNAPSHOT         0x2C
  86. #define VK_INSERT           0x2D
  87. #define VK_DELETE           0x2E
  88. #define VK_HELP             0x2F
  89. /* VK_A thru VK_Z are the same as their ASCII equivalents: 'A' thru 'Z' */
  90. /* VK_0 thru VK_9 are the same as their ASCII equivalents: '0' thru '9' */
  91. #define VK_NUMPAD0          0x60
  92. #define VK_NUMPAD1          0x61
  93. #define VK_NUMPAD2          0x62
  94. #define VK_NUMPAD3          0x63
  95. #define VK_NUMPAD4          0x64
  96. #define VK_NUMPAD5          0x65
  97. #define VK_NUMPAD6          0x66
  98. #define VK_NUMPAD7          0x67
  99. #define VK_NUMPAD8          0x68
  100. #define VK_NUMPAD9          0x69
  101. #define VK_MULTIPLY         0x6A
  102. #define VK_ADD              0x6B
  103. #define VK_SEPARATOR        0x6C
  104. #define VK_SUBTRACT         0x6D
  105. #define VK_DECIMAL          0x6E
  106. #define VK_DIVIDE           0x6F
  107. #define VK_F1               0x70
  108. #define VK_F2               0x71
  109. #define VK_F3               0x72
  110. #define VK_F4               0x73
  111. #define VK_F5               0x74
  112. #define VK_F6               0x75
  113. #define VK_F7               0x76
  114. #define VK_F8               0x77
  115. #define VK_F9               0x78
  116. #define VK_F10              0x79
  117. #define VK_F11              0x7A
  118. #define VK_F12              0x7B
  119. #define VK_F13              0x7C
  120. #define VK_F14              0x7D
  121. #define VK_F15              0x7E
  122. #define VK_F16              0x7F
  123. #define VK_NUMLOCK          0x90
  124.  
  125.  
  126. KeyStroke(Key1,Key2,Key3/*etc...*/)
  127. {
  128.    _argCount = va_arg();
  129.    // if more than one parameter, then hold down all but the last one
  130.    for ( k = 1; k < _argCount; k++ )
  131.       VKeyDown(va_arg(k-1));
  132.  
  133.    _key = va_arg(_argCount-1);
  134.    // Treat differently depending on whether Virtual Key Code, char, or string
  135.    if ( CMM_BYTE == DataType(_key) ) {
  136.       if ( 1 == DataDimension(_key) ) {
  137.          // send entire string one character at a time
  138.          for ( k = 0; _key[k]; k++ )
  139.             CharacterStroke(_key[k]);
  140.       } else {
  141.          // send a single character out the port
  142.          CharacterStroke(_key);
  143.       }
  144.    } else {
  145.       // simply a virtual key code
  146.       VKeyDown(_key);
  147.       VKeyUp(_key);
  148.    }
  149.  
  150.    // if more than one parameter, then reverse release all but the last one
  151.    for ( k = 1; k < _argCount; k++ )
  152.       VKeyUp(va_arg(_argCount-k-1));
  153. }
  154.  
  155. VKeyDown(KeyCode)
  156. {
  157.    // Save the current state of the 256-byte keyboard buffer
  158.    _keyBuffer = GetKeyboardState();
  159.  
  160.    // build hi word of lParam for the WM_KEYDOWN or WM_SYSKEYDOWN message
  161.    // 1: Get Scan Code for this virtual key
  162.    _HiWord = MapVirtualKey(KeyCode,0);
  163.    // 2: Set bit for if this is an extended key
  164.    if ( (VK_PRIOR <= KeyCode && KeyCode <= VK_HELP)
  165.      || (VK_F1 <= KeyCode && KeyCode <= VK_F16) )
  166.       _HiWord |= 0x100;
  167.    // 3: If ALT key is down but not the control key, then set that bit
  168.    //    and change message to WM_SYSKEYDOWN
  169.    if ( (KeyCode == VK_ALT  ||  (GetKeyState(VK_ALT) & 0x8000) )
  170.      && !(GetKeyState(VK_CONTROL) & 0x8000) )
  171.       _HiWord |= 0x2000, _message = WM_SYSKEYDOWN;
  172.    else
  173.       _message = WM_KEYDOWN;
  174.  
  175.    // save in _keyBuffer that this key is now down
  176.    _keyBuffer[KeyCode] = (_KeyBuffer[KeyCode] ^ 0x01) | 0x80;
  177.    SetKeyboardState(_keyBuffer);
  178.  
  179.    // send message to window that this key is being pressed
  180.    PostMessage(GetFocus(),_message,KeyCode,1,_HiWord);
  181. }
  182.  
  183.  
  184. VKeyUp(KeyCode)
  185. {
  186.    // Save the current state of the 256-byte keyboard buffer
  187.    _keyBuffer = GetKeyboardState();
  188.  
  189.    // build hi word of lParam for the WM_KEYUP or WM_SYSKEYUP message
  190.    // 1: Get Scan Code for this virtual key
  191.    _HiWord = MapVirtualKey(KeyCode,0);
  192.    // 2: Set bit for if this is an extended key
  193.    if ( (VK_PRIOR <= KeyCode && KeyCode <= VK_HELP)
  194.      || (VK_F1 <= KeyCode && KeyCode <= VK_F16) )
  195.       _HiWord |= 0x100;
  196.    // 3: If ALT key is down but not the control key, then set that bit
  197.    //    and change message to WM_SYSKEYDOWN
  198.    if ( (KeyCode == VK_ALT  ||  (GetKeyState(VK_ALT) & 0x8000) )
  199.      && !(GetKeyState(VK_CONTROL) & 0x8000) )
  200.       _HiWord |= 0x2000, _message = WM_SYSKEYUP;
  201.    else
  202.       _message = WM_KEYUP;
  203.    // 4: set hi 2 bits that key WAS down
  204.    _HiWord |= 0xC000;
  205.  
  206.    // save in _keyBuffer that this key is now up
  207.    _keyBuffer[KeyCode] &= 0x7F;
  208.    SetKeyboardState(_keyBuffer);
  209.  
  210.    // send message to window that this key is being pressed
  211.    PostMessage(GetFocus(),_message,KeyCode,1,_HiWord);
  212. }
  213.  
  214. SpeedKeys(AsciiString,DelayBetweenKeys)
  215. {
  216.    _focus = GetFocus();
  217.    for ( c = AsciiString; c[0]; c++ ) {
  218.       PostMessage(_focus,WM_CHAR,c[0],1,0);
  219.       // DelayBetweenKeys is optional. If not supplied then no delay
  220.       if ( 1 < va_arg() )
  221.          suspend(DelayBetweenKeys);
  222.    }
  223. }
  224.  
  225.  
  226. /***********************************************************
  227.  *** PRIVATE UTILITIES USED BY THE ABOVE PUBLIC ROUTINES ***
  228.  ***********************************************************/
  229.  
  230. CharacterStroke(c) // press this character.  This is only tricky in that
  231. {                  // must check SHIFT state for alphabetic characters
  232.    // Get virtual codes for this character
  233.    _vkeystate = DynamicLink("KEYBOARD","VKKEYSCAN",SWORD16,PASCAL,c)
  234.    if ( -1 != _vkeystate ) {
  235.       vkey = _vkeystate & 0xFF;
  236.       switch( _vkeystate >> 8 ) {
  237.          case 0:  // no shift state
  238.          case 1:  // shift state
  239.             if ( (0 != (GetKeyState(VK_SHIFT) & 0x80)) ^
  240.                  (0 != (GetKeyState(VK_CAPITAL) & 0x01)) ^
  241.                  (0 != (_vkeystate & 0x100)) ) {
  242.                // need to toggle the shift key to change case of this character
  243.                if ( GetKeyState(VK_SHIFT) & 0x80 )
  244.                   VKeyUp(VK_SHIFT), KeyStroke(vkey), VKeyDown(VK_SHIFT);
  245.                else
  246.                   KeyStroke(VK_SHIFT,vkey);
  247.             } else
  248.                KeyStroke(vkey);
  249.             break;
  250.          case 2:  // control character
  251.             KeyStroke(VK_CONTROL,vkey);
  252.             break;
  253.          case 6:  // control + alt
  254.             KeyStroke(VK_CONTROL,VK_ALT,vkey);
  255.             break;
  256.          case 7:  // SHIFT+CONTROL+ALT
  257.             KeyStroke(VK_SHIFT,VK_CONTROL,VK_ALT,vkey);
  258.             break;
  259.          default: // unknown
  260.             break;
  261.       }
  262.    }
  263. }
  264.  
  265. GetKeyboardState()   // return 256 byte buffer for current keyboard state
  266. {
  267.    _keyBuf[255] = '\0'; // initialize a 256-byte array
  268.    DynamicLink("USER","GETKEYBOARDSTATE",SWORD16,PASCAL,_keyBuf);
  269.    return(_KeyBuf);
  270. }
  271.  
  272. SetKeyboardState(_keyBuf)  // set the 256 byte buffer for current keyboard state
  273. {
  274.    DynamicLink("USER","SETKEYBOARDSTATE",SWORD16,PASCAL,_keyBuf);
  275. }
  276.  
  277. GetKeyState(VKey)
  278. {
  279.    return( DynamicLink("USER","GETKEYSTATE",SWORD16,PASCAL,VKey) );
  280. }
  281.  
  282. MapVirtualKey(wCode,wMapType)
  283. {
  284.    return( DynamicLink("KEYBOARD","MAPVIRTUALKEY",UWORD16,PASCAL,wCode,wMapType) );
  285. }
  286.  
  287. GetFocus()  // return handle of Window with the focus
  288. {
  289.    return( FocusWindow
  290.          ? FocusWindow
  291.          : DynamicLink("USER","GETFOCUS",UWORD16,PASCAL) );
  292. }
  293.  
  294.