Simulate the pressing of keyboard keys

1.  PostKeyEx32  function}  

procedure  PostKeyEx32 ( key :  Word ;  const  shift :  TShiftState ;  specialkey :  Boolean );  
{************************************************************  
* Procedure PostKeyEx32  
*  
* Parameters:  
*  key    : virtual keycode of the key to send. For printable  
*           keys this is simply the ANSI code (Ord(character)).  
*  shift  : state of the modifier keys. This is a set, so you  
*           can set several of these keys (shift, control, alt,  
*           mouse buttons) in tandem. The TShiftState type is  
*           declared in the Classes Unit.  
*  specialkey: normally this should be False. Set it to True to  
*           specify a key on the numeric keypad, for example.  
* Description:  
*  Uses keybd_event to manufacture a series of key events matching  
*  the passed parameters. The events go to the control with focus.  
*  Note that for characters key is always the upper-case version of  
*  the character. Sending without any modifier keys will result in  
*  a lower-case character, sending it with [ssShift] will result  
*  in an upper-case character!  
// Code by P. Below  
************************************************************}  
type  
   TShiftKeyInfo  =  record  
     shift :  Byte ;  
     vkey :  Byte ;  
   end ;  
   byteset  =  set  of  0..7 ;  
const  
   shiftkeys :  array  [ 1..3 ]  of  TShiftKeyInfo  =  
     (( shift :  Ord ( ssCtrl );  vkey :  VK_CONTROL ),  
     ( shift :  Ord ( ssShift );  vkey :  VK_SHIFT ),  
     ( shift :  Ord ( ssAlt );  vkey :  VK_MENU ));  
var  
   flag :  DWORD ;  
   bShift :  ByteSet  absolute  shift ;  
   i :  Integer ;  
begin  
   for  i  :=  1  to  3  do  
   begin  
     if  shiftkeys [ i ]. shift  in  bShift  then  
       keybd_event ( shiftkeys [ i ]. vkey ,  MapVirtualKey ( shiftkeys [ i ]. vkey ,  0 ),  0 ,  0 );  
   end ;  { For }  
   if  specialkey  then  
     flag  :=  KEYEVENTF_EXTENDEDKEY  
   else  
     flag  :=  0 ;  

   keybd_event ( key ,  MapvirtualKey ( key ,  0 ),  flag ,  0 );  
   flag  :=  flag  or  KEYEVENTF_KEYUP ;  
   keybd_event ( key ,  MapvirtualKey ( key ,  0 ),  flag ,  0 );  

   for  i  :=  3  downto  1  do  
   begin  
     if  shiftkeys [ i ]. shift  in  bShift  then  
       keybd_event ( shiftkeys [ i ]. vkey ,  MapVirtualKey ( shiftkeys [ i ]. vkey ,  0 ),  
         KEYEVENTF_KEYUP ,  0 );  
   end ;  { For }  
end ;  { PostKeyEx32 }  


// Example:  

procedure  TForm1 . Button1Click ( Sender :  TObject );  
begin  
   //Pressing the Left Windows Key  
   PostKeyEx32 ( VK_LWIN ,  [],  False );  

   //Pressing the letter D  
   PostKeyEx32 ( Ord ( 'D' ),  [],  False );  

   //Pressing Ctrl-Alt-C  
   PostKeyEx32 ( Ord ( 'C' ),  [ ssctrl ,  ssAlt ],  False );  
end ;  


{************************************************************}  
{2. With keybd_event API}  

procedure  TForm1 . Button1Click ( Sender :  TObject );  
begin  
   {or you can also try this simple example to send any  
   amount of keystrokes at the same time. }  

   {Pressing the A Key and showing it in the Edit1.Text}  

   Edit1 . SetFocus ;  
   keybd_event ( VK_SHIFT ,  0 ,  0 ,  0 );  
   keybd_event ( Ord ( 'A' ),  0 ,  0 ,  0 );  
   keybd_event ( VK_SHIFT ,  0 ,  KEYEVENTF_KEYUP ,  0 );  

   {Presses the Left Window Key and starts the Run}  
   keybd_event ( VK_LWIN ,  0 ,  0 ,  0 );  
   keybd_event ( Ord ( 'R' ),  0 ,  0 ,  0 );  
   keybd_event ( VK_LWIN ,  0 ,  KEYEVENTF_KEYUP ,  0 );  
end ;  


{***********************************************************}  
{3. With keybd_event API}  

procedure  PostKeyExHWND ( hWindow :  HWnd ;  key :  Word ;  const  shift :  TShiftState ;  
   specialkey :  Boolean );  
{************************************************************  
 * Procedure PostKeyEx  
 *  
 * Parameters:  
 *  hWindow: target window to be send the keystroke  
 *  key    : virtual keycode of the key to send. For printable  
 *           keys this is simply the ANSI code (Ord(character)).  
 *  shift  : state of the modifier keys. This is a set, so you  
 *           can set several of these keys (shift, control, alt,  
 *           mouse buttons) in tandem. The TShiftState type is  
 *           declared in the Classes Unit.  
 *  specialkey: normally this should be False. Set it to True to  
 *           specify a key on the numeric keypad, for example.  
 *           If this parameter is true, bit 24 of the lparam for  
 *           the posted WM_KEY* messages will be set.  
 * Description:  
 *  This procedure sets up Windows key state array to correctly  
 *  reflect the requested pattern of modifier keys and then posts  
 *  a WM_KEYDOWN/WM_KEYUP message pair to the target window. Then  
 *  Application.ProcessMessages is called to process the messages  
 *  before the keyboard state is restored.  
 * Error Conditions:  
 *  May fail due to lack of memory for the two key state buffers.  
 *  Will raise an exception in this case.  
 * NOTE:  
 *  Setting the keyboard state will not work across applications  
 *  running in different memory spaces on Win32 unless AttachThreadInput  
 *  is used to connect to the target thread first.  
 *Created: 02/21/96 16:39:00 by P. Below  
 ************************************************************}  
type  
   TBuffers  =  array  [ 0..1 ]  of  TKeyboardState ;  
var  
   pKeyBuffers :  ^ TBuffers ;  
   lParam :  LongInt ;  
begin  
   (* check if the target window exists *)  
   if  IsWindow ( hWindow )  then  
   begin  
     (* set local variables to default values *)  
     pKeyBuffers  :=  nil ;  
     lParam  :=  MakeLong ( 0 ,  MapVirtualKey ( key ,  0 ));  

     (* modify lparam if special key requested *)  
     if  specialkey  then  
       lParam  :=  lParam  or  $1000000 ;  

     (* allocate space for the key state buffers *)  
     New ( pKeyBuffers );  
     try  
       (* Fill buffer 1 with current state so we can later restore it.  
         Null out buffer 0 to get a "no key pressed" state. *)  
       GetKeyboardState ( pKeyBuffers ^[ 1 ]);  
       FillChar ( pKeyBuffers ^[ 0 ],  SizeOf ( TKeyboardState ),  0 );  

       (* set the requested modifier keys to "down" state in the buffer*)  
       if  ssShift  in  shift  then  
         pKeyBuffers ^[ 0 ][ VK_SHIFT ]  :=  $80 ;  
       if  ssAlt  in  shift  then  
       begin  
         (* Alt needs special treatment since a bit in lparam needs also be set *)  
         pKeyBuffers ^[ 0 ][ VK_MENU ]  :=  $80 ;  
         lParam  :=  lParam  or  $20000000 ;  
       end ;  
       if  ssCtrl  in  shift  then  
         pKeyBuffers ^[ 0 ][ VK_CONTROL ]  :=  $80 ;  
       if  ssLeft  in  shift  then  
         pKeyBuffers ^[ 0 ][ VK_LBUTTON ]  :=  $80 ;  
       if  ssRight  in  shift  then  
         pKeyBuffers ^[ 0 ][ VK_RBUTTON ]  :=  $80 ;  
       if  ssMiddle  in  shift  then  
         pKeyBuffers ^[ 0 ][ VK_MBUTTON ]  :=  $80 ;  

       (* make out new key state array the active key state map *)  
       SetKeyboardState ( pKeyBuffers ^[ 0 ]);  
       (* post the key messages *)  
       if  ssAlt  in  Shift  then  
       begin  
         PostMessage ( hWindow ,  WM_SYSKEYDOWN ,  key ,  lParam );  
         PostMessage ( hWindow ,  WM_SYSKEYUP ,  key ,  lParam  or  $C0000000 );  
       end  
       else  
       begin  
         PostMessage ( hWindow ,  WM_KEYDOWN ,  key ,  lParam );  
         PostMessage ( hWindow ,  WM_KEYUP ,  key ,  lParam  or  $C0000000 );  
       end ;  
       (* process the messages *)  
       Application . ProcessMessages ;  

       (* restore the old key state map *)  
       SetKeyboardState ( pKeyBuffers ^[ 1 ]);  
     finally  
       (* free the memory for the key state buffers *)  
       if  pKeyBuffers  <>  nil  then  
         Dispose ( pKeyBuffers );  
     end ;  { If }  
   end ;  
end ;  { PostKeyEx }  

// Example:  

procedure  TForm1 . Button1Click ( Sender :  TObject );  
var  
   targetWnd :  HWND ;  
begin  
   targetWnd  :=  FindWindow ( 'notepad' ,  nil )  
     if  targetWnd  <>  0  then  
     begin  
       PostKeyExHWND ( targetWnd ,  Ord ( 'I' ),  [ ssAlt ],  False );  
   end ;  
end ;  

{***********************************************************}  
{3. With SendInput API}  

// Example: Send text  
procedure  TForm1 . Button1Click ( Sender :  TObject );  
const  
    Str :  string  =  'writing writing writing' ;  
var  
   Inp :  TInput ;  
   I :  Integer ;  
begin  
   Edit1 . SetFocus ;  

   for  I  :=  1  to  Length ( Str )  do  
   begin  
     // press  
     Inp . Itype  :=  INPUT_KEYBOARD ;  
     Inp . ki . wVk  :=  Ord ( UpCase ( Str [ i ]));  
     Inp . ki . dwFlags  :=  0 ;  
     SendInput ( 1 ,  Inp ,  SizeOf ( Inp ));  

     // release  
     Inp . Itype  :=  INPUT_KEYBOARD ;  
     Inp . ki . wVk  :=  Ord ( UpCase ( Str [ i ]));  
     Inp . ki . dwFlags  :=  KEYEVENTF_KEYUP ;  
     SendInput ( 1 ,  Inp ,  SizeOf ( Inp ));  

     Application . ProcessMessages ;  
     Sleep ( 80 );  
   end ;  
end ;  

// Example: Simulate Alt+Tab  
procedure  SendAltTab ;  
var  
   KeyInputs :  array  of  TInput ;  
   KeyInputCount :  Integer ;  

   procedure  KeybdInput ( VKey :  Byte ;  Flags :  DWORD );  
   begin  
     Inc ( KeyInputCount );  
     SetLength ( KeyInputs ,  KeyInputCount );  
     KeyInputs [ KeyInputCount  -  1 ]. Itype  :=  INPUT_KEYBOARD ;  
     with   KeyInputs [ KeyInputCount  -  1 ]. ki  do  
     begin  
       wVk  :=  VKey ;  
       wScan  :=  MapVirtualKey ( wVk ,  0 );  
       dwFlags  :=  KEYEVENTF_EXTENDEDKEY ;  
       dwFlags  :=  Flags  or  dwFlags ;  
       time  :=  0 ;  
       dwExtraInfo  :=  0 ;  
     end ;  
   end ;  
begin  
   KeybdInput ( VK_MENU ,  0 );                 // Alt  
   KeybdInput ( VK_TAB ,  0 );                  // Tab  
   KeybdInput ( VK_TAB ,  KEYEVENTF_KEYUP );    // Tab  
   KeybdInput ( VK_MENU ,  KEYEVENTF_KEYUP );  // Alt  
   SendInput ( KeyInputCount ,  KeyInputs [ 0 ],  SizeOf ( KeyInputs [ 0 ]));  
end ;  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值