Page 1 of 1

SendKeys Procedure

Posted: Sun Aug 03, 2003 10:47 pm
by ebs
Here is a procedure similar to Visual Basic's SendKeys(). It will send a specified string to the foreground application as if the keys had been pressed on the keyboard. It should work for all ASCII characters, including those that don't have a #VK_xxx constant value, like punctuation characters.

Code: Select all

; send the specified key
Procedure SendKey(Key.s)
  ; get virtual key code and shift state
  VK.w = VkKeyScan_(Asc(Key))
  If VK = -1
    ProcedureReturn
  EndIf
  
  ; get scan code if an extended key
  If MapVirtualKey_(VK, 2) = 0
    Extended.l = #KEYEVENTF_EXTENDEDKEY
    ; get scan code
    Scan.l = MapVirtualKey_(VK, 0)
  Else
    Extended = 0 
    Scan = 0
  EndIf
  
  ; press shift/ctrl/alt if needed
  Shift.l = VK & $100
  Ctrl.l = VK & $200
  Alt.l = VK & $400
  If Shift
    keybd_event_(#VK_SHIFT, 0, 0, 0)
  EndIf
  If Ctrl
    keybd_event_(#VK_CONTROL, 0, 0, 0)
  EndIf
  If Alt
    keybd_event_(#VK_MENU, 0, 0, 0)
  EndIf
  
  ; press and release key
  VK & $ff
  keybd_event_(VK, Scan, Extended, 0)
  keybd_event_(VK, Scan, #KEYEVENTF_KEYUP | Extended, 0)
  
  ; release shift/ctrl/alt if pressed
  If Shift
    keybd_event_(#VK_SHIFT, 0, #KEYEVENTF_KEYUP, 0)
  EndIf
  If Ctrl
    keybd_event_(#VK_CONTROL, 0, #KEYEVENTF_KEYUP, 0)
  EndIf
  If Alt
    keybd_event_(#VK_MENU, 0, #KEYEVENTF_KEYUP, 0)
  EndIf
EndProcedure

; send string to foreground application  
Procedure SendKeys(String.s)
  For Letter.l = 1 To Len(String)
    SendKey(Mid(String, Letter, 1))
  Next
EndProcedure

; test
For n.l = 1 To 10
  Delay(2000)
  SendKeys("Hello There!" + Chr(13))
Next
To test the code, open any text editor. Start the program and quickly switch back to the text editor. You should see the 10 lines of text.

Re: SendKeys Procedure

Posted: Wed Aug 06, 2003 1:38 am
by PB
Nice code, ebs -- much shorter than my earlier tip. My tip also allows
sending of keys like F1, Pause, PageUp, and so on. Check it out:

viewtopic.php?t=3766

Posted: Wed Aug 06, 2003 1:27 pm
by ebs
My tip also allows sending of keys like F1, Pause, PageUp, and so on.
That was going to be my next step! :D
Now I can just "borrow" your code.

Thanks for your help,
Eric

Posted: Tue Mar 31, 2009 2:07 pm
by Michael Vogel
Great Code - because it works with ALL characters (german umlauts and such funny stuff)! :)

BUT...
...does anyone know to disable the real keyboard while sending these infos?

I would need this, because it could happen, that the user will press a key while a string will be sent out and this can lead to unwanted effects

For example, holding down the shift-key will show something like "HeLLO TherE!" instead of "Hello There!" :cry:

Michael

Posted: Tue Mar 31, 2009 2:21 pm
by marroh

Code: Select all

BlockInput_(#True)
...
...
...
BlockInput_(#False)
NT-Systems only, as i know.

Posted: Tue Mar 31, 2009 3:05 pm
by Michael Vogel
marroh wrote:

Code: Select all

BlockInput_(#True)
 :
BlockInput_(#False)
NT-Systems only, as i know.
Thanks, marroh - I checked it using Windows XP...

(+) 'shift' and 'caps lock' seems to be blocked/ignored here :D
(–) 'alt' is not blocked :cry:
(–) 'ctrl' is not blocked :cry:

Michael

Posted: Tue Mar 31, 2009 4:44 pm
by dioxin
For multiple keys use SendInput:

http://msdn.microsoft.com/en-us/library ... S.85).aspx
The SendInput function inserts the events in the INPUT structures serially into the keyboard or mouse input stream. These events are not interspersed with other keyboard or mouse input events inserted either by the user (with the keyboard or mouse) or by calls to keybd_event, mouse_event, or other calls to SendInput.

Re: SendKeys Procedure

Posted: Wed Mar 31, 2021 11:03 pm
by marcos.exe
Hi!
I don't know if only I missed it, or I didn't use it properly!

The right and left cursor arrows do not work.
The right and left that is in place is the numeric keypad.
Is it possible to make the arrows work normally?

NOTE: My windows are in Brazilian Portuguese, as well as my keyboard. I don't know if this has anything to do with it!

Translated by google.

Re: SendKeys Procedure

Posted: Wed Jan 10, 2024 8:16 pm
by Kwai chang caine
I use this short and nice code of EBS for sending string 8)
http://www.purebasic.fr/english/viewtop ... 1486#31486

Code: Select all

Procedure SendKeys(String.s)
  
 For Letter.l = 1 To Len(String)
  
  Delay(10)
  Key.s = Mid(String, Letter, 1)
  
  ; get virtual key code and shift state 
  VK.w = VkKeyScan_(Asc(Key))
  
  If VK = -1 
   ProcedureReturn 
  EndIf 
  
  ; get scan code if an extended key 
  If MapVirtualKey_(VK, 2) = 0 
   Extended.l = #KEYEVENTF_EXTENDEDKEY 
   ; get scan code 
   Scan.l = MapVirtualKey_(VK, 0) 
  Else 
   Extended = 0 
   Scan = 0 
  EndIf 
  
  ; press shift/ctrl/alt if needed 
  Shift.l = VK & $100 
  Ctrl.l = VK & $200 
  Alt.l = VK & $400
  
  If Shift 
   keybd_event_(#VK_SHIFT, 0, 0, 0) 
  EndIf
  
  If Ctrl 
   keybd_event_(#VK_CONTROL, 0, 0, 0) 
  EndIf
  
  If Alt 
   keybd_event_(#VK_MENU, 0, 0, 0) 
  EndIf 
  
  ; press and release key 
  VK & $ff 
  keybd_event_(VK, Scan, Extended, 0) 
  keybd_event_(VK, Scan, #KEYEVENTF_KEYUP | Extended, 0)
  Delay(10)
  
  ; release shift/ctrl/alt if pressed 
  If Shift 
   keybd_event_(#VK_SHIFT, 0, #KEYEVENTF_KEYUP, 0) 
  EndIf
  
  If Ctrl 
   keybd_event_(#VK_CONTROL, 0, #KEYEVENTF_KEYUP, 0) 
  EndIf
  
  If Alt 
   keybd_event_(#VK_MENU, 0, #KEYEVENTF_KEYUP, 0) 
  EndIf
  
 Next
 
EndProcedure
But i see the "~" character is not writing :shock:
After searching, I believe have found the problem :oops:
The MapVirtualKey_() return zero then that VK = 1586 :shock:
VK.w = VkKeyScan_(Asc("~"))
Debug MapVirtualKey_(VK, 0)
Someone know why ?
Have a good day

Re: SendKeys Procedure

Posted: Wed Jan 10, 2024 9:19 pm
by idle
run this without debugger

Code: Select all

#INPUT_KEYBOARD = 1
#KEYEVENTF_UNICODE = 4 
#KEYEVENTF_KEYUP = 2 

Global Dim InputData.INPUT(0)

Procedure SendKeyInput(key.s)
  
  Protected *p.unicode   
    
  ReDim InputData.INPUT(((Len(key)*2)-1))
  
  *p = @key 
  While *p\u <> 0 
    InputData(a)\type = #INPUT_KEYBOARD
    InputData(a)\ki\wScan = *p\u  
    InputData(a)\ki\dwFlags = #KEYEVENTF_UNICODE
    a+1
    InputData(a)\type = #INPUT_KEYBOARD
    InputData(a)\ki\wScan = *p\u  
    InputData(a)\ki\dwFlags = #KEYEVENTF_UNICODE | #KEYEVENTF_KEYUP;
    a+1 
    *p+2 
  Wend   
  
  BlockInput_(1)
  aret = SendInput_(a,@inputdata(0),SizeOf(INPUT))
  BlockInput_(0) 
  If aret  
    Debug aret  
  EndIf    
    
EndProcedure  

GetForegroundWindow_() 
key.s = "Hello~!@#$%^&*()" 
sendkeyInput(key)

;put cursor here 


Re: SendKeys Procedure

Posted: Wed Jan 10, 2024 11:31 pm
by Quin
Just tested, and this works flawlessly, thanks loads!
idle wrote: Wed Jan 10, 2024 9:19 pm run this without debugger

Code: Select all

#INPUT_KEYBOARD = 1
#KEYEVENTF_UNICODE = 4 
#KEYEVENTF_KEYUP = 2 

Global Dim InputData.INPUT(0)

Procedure SendKeyInput(key.s)
  
  Protected *p.unicode   
    
  ReDim InputData.INPUT(((Len(key)*2)-1))
  
  *p = @key 
  While *p\u <> 0 
    InputData(a)\type = #INPUT_KEYBOARD
    InputData(a)\ki\wScan = *p\u  
    InputData(a)\ki\dwFlags = #KEYEVENTF_UNICODE
    a+1
    InputData(a)\type = #INPUT_KEYBOARD
    InputData(a)\ki\wScan = *p\u  
    InputData(a)\ki\dwFlags = #KEYEVENTF_UNICODE | #KEYEVENTF_KEYUP;
    a+1 
    *p+2 
  Wend   
  
  BlockInput_(1)
  aret = SendInput_(a,@inputdata(0),SizeOf(INPUT))
  BlockInput_(0) 
  If aret  
    Debug aret  
  EndIf    
    
EndProcedure  

GetForegroundWindow_() 
key.s = "Hello~!@#$%^&*()" 
sendkeyInput(key)

;put cursor here 


Re: SendKeys Procedure

Posted: Fri Jan 12, 2024 9:29 pm
by Kwai chang caine
Hello my friend IDLE :D

Little.... powerfull.... best working...In one word (very difficult to do for KCC :mrgreen:)

PERFECT !!!!!

I have replacing the EBS procedure by yours immediately in my program :wink:
Thanks a lot and have a very good day 8)
Your fan
KCC