| View previous topic :: View next topic |
| Author |
Message |
jrmarquart Valued Newbie
Joined: 12 Jun 2004 Posts: 28 Location: Boise, ID
|
Posted: Wed Apr 06, 2005 2:49 am Post subject: Window Send (Simulating a Key being Held Down) |
|
|
Does anyone know if it is possible to simulate a normal key being held down with the Window Send command?
Something like @ctrl() except it can be used for normal keys not just the Ctrl, Shift, and Alt modifier keys. If not and this capability could be added to VDS 6 (if it is even possible) it would be greatly appreciated.
I do know how to simulate this using the libraries GetAsyncKeyState and keybd_event, but adding this functionality to the Window Send command would be really beneficial.
What I'm trying to accomplish is sending macros to games that use DirectInput which have a tendency to block the keybd_event library. |
|
| Back to top |
|
 |
jules Professional Member


Joined: 14 Sep 2001 Posts: 1043 Location: Cumbria, UK
|
Posted: Wed Apr 06, 2005 8:14 am Post subject: |
|
|
VDS also uses keybd_event. _________________ The Tech Pro
www.tech-pro.net |
|
| Back to top |
|
 |
FreezingFire Admin Team

Joined: 23 Jun 2002 Posts: 3508
|
Posted: Thu Apr 07, 2005 12:06 am Post subject: |
|
|
I've also wondered how to hook/send keystrokes such as "CTRL+A+E"  _________________ FreezingFire
VDSWORLD.com
Site Admin Team |
|
| Back to top |
|
 |
jrmarquart Valued Newbie
Joined: 12 Jun 2004 Posts: 28 Location: Boise, ID
|
Posted: Thu Apr 07, 2005 3:56 am Post subject: |
|
|
Jules it is interesting that the Window Send command uses the keybd_event library. I am hoping the problem then that I am encountering is due to my lack of knowledge regarding how the keybd_event library works.
To further explain let me give you an example of the type of problem I am encountering.
The following code works for 3 out of 6 games (where the 3 games that it does not work in probably use some form of DirectInput). I apologize for the extra variables it was just easier for me to cut and paste this from my main program code. For the purpose of this example though it should be easy to see what I am trying to accomplish. Keep in mind though that when a console game window is open in the game then this code does work for all 6 games. It does not work though when playing in the actual active game window for 3 out of the 6 games.
| Code: |
Rem Purpose: When the X key is pressed simulate the Shift key being pressed down.
%%fromkey1 = 58
Rem Where 58 is the virtual keycode for the X key
%%tokey1 = 10
Rem Where 10 is the virtual keycode for the Shift key
LOADLIB USER32
%%fromkey1key = @lib(user32,GetAsyncKeyState,int:,$%%fromkey1)
%%tokey1key = @lib(user32,GetAsyncKeyState,int:,$%%tokey1)
%%fromkey1key = 0
%%tokey1key = 0
:start
wait .01
if @unequal(%%fromkey1,0)
%%fromkey1key = @lib(user32,GetAsyncKeyState,int:,$%%fromkey1)
%%tokey1key = @lib(user32,GetAsyncKeyState,int:,$%%tokey1)
if @unequal(%%depressed1,1)
if @unequal(%%fromkey1key,0)
if @equal(%%Rapidfire1,1)
gosub rapidfire1
else
gosub remap1
end
else
%%tokey1key = @lib(user32,keybd_event,nil:,int:$%%tokey1,0,$2,0)
end
end
if @equal(%%depressed1,1)
if @unequal(%%fromkey1key,0)
if @unequal(%%tokey1key,1)
gosub depressed1
end
%%fromkey1key = 0
%%tokey1key = 0
else
%%fromkey1key = @lib(user32,keybd_event,nil:,int:$%%fromkey1,0,$2,0)
end
end
end
end
goto start
:Remap1
%%fromkey1key = 0
%I = @winactive(I)
%T = @wintext(%I)
if @winexists(%T)
%%tokey1key = @lib(user32,keybd_event,nil:,int:$%%tokey1,0,0,0)
end
exit
|
The following code below works for 6 out of 6 games where I am using the Window Send command instead of how I implemented the keybd_event library from above. Keep in mind though that for the 3 games that use DirectInput - ONLY the modifier keys are recognized in the actual game window. Normal keys are not recognized when using the Window Send command.
| Code: |
Rem Purpose: When the V key is pressed simulate the Shift key being pressed down. The extra keys in the Shift function are used to hold the Shift key down longer.
%%hotkey1 = 56
Rem Where 56 is the virtual keycode for the V key
LOADLIB USER32
%%hotkey1key = @lib(user32,GetAsyncKeyState,int:,$%%hotkey1))
%%hotkey1key = 0
:start
wait .01
if @unequal(%%hotkey1,0)
if @unequal(%%modifier1,0)
%%hotkey1key = @lib(user32,GetAsyncKeyState,int:,$%%hotkey1)
%%modifier1key = @lib(user32,GetAsyncKeyState,int:,$%%modifier1)
if @unequal(%%modifier1key,0)
if @unequal(%%hotkey1key,0)
gosub macro1
end
%%modifier1key = 0
%%hotkey1key = 0
end
end
end
goto start
:Macro1
%%output1 = @Shift(aaaaaaaaaa)
Rem Where the (aaaaaaaaaa) just allows the Shift key to be held down for a second or two.
%%modifier1key = 0
%%hotkey1key = 0
%I = @winactive(I)
%T = @wintext(%I)
if @winexists(%T)
option skdelay,%%delay1
window send,%I,%%output1
end
exit
|
So to summarize the modifier keys when used with the Window Send command are being recognized in any game whether it uses DirectInput or not. Is the Window Send command using the keybd_event library for modifier keys being handled somehow differently then when normal keys are being sent to a window? I just don't understand why I cannot get modifier keys to be recognized correctly in certain games with the way I am implementing the keybd_event library yet when I use the Window Send command it always works?
Thank you for your time and help if you have any suggestions. |
|
| Back to top |
|
 |
jules Professional Member


Joined: 14 Sep 2001 Posts: 1043 Location: Cumbria, UK
|
Posted: Thu Apr 07, 2005 11:01 am Post subject: |
|
|
| FreezingFire wrote: | I've also wondered how to hook/send keystrokes such as "CTRL+A+E"  |
What's wrong with @ctrl(AE)? _________________ The Tech Pro
www.tech-pro.net |
|
| Back to top |
|
 |
jules Professional Member


Joined: 14 Sep 2001 Posts: 1043 Location: Cumbria, UK
|
Posted: Thu Apr 07, 2005 11:20 am Post subject: |
|
|
| jrmarquart wrote: | | Jules it is interesting that the Window Send command uses the keybd_event library. I am hoping the problem then that I am encountering is due to my lack of knowledge regarding how the keybd_event library works. |
The code VDS uses was written years ago and I can't explain how it works. I can say, though, that it contains calls to MapVirtualKey and VkKeyScan as part of the process of generating the key codes to scan, which your examples don't. Therefore the codes you are sending may not be valid.
I don't know what Direct Input is, but I recall that using VDS to send keystrokes to some DOS programs don't always work because the keystrokes generated this way don't appear if the program uses BIOS functions or reads the keyboard hardware to determine what is happening, which some DOS programs do. Perhaps Direct Input is doing something similar. The simulated keystrokes only appear when the program gets keyboard input using operating system (DOS/Windows) functions. _________________ The Tech Pro
www.tech-pro.net |
|
| Back to top |
|
 |
jrmarquart Valued Newbie
Joined: 12 Jun 2004 Posts: 28 Location: Boise, ID
|
Posted: Fri Apr 08, 2005 12:28 am Post subject: |
|
|
| Thanks Jules for your help. I will update this thread if I ever find out a way to resolving the problem I am having. As far as DirectInput is concerned I don't know a whole lot about it myself other than that I believe it is a DirectX technology used with computer games for handling keyboard input functions. Supposedly it works better than using the keybd_event library that is why a lot of computer games are starting to use it. The fascinating thing about the Window Send command when using the modifier keys is it works in games using DirectInput for the active game window. I don't know of any other macro program that is able to do this. In fact the only solution I have ever heard of is someone creating a keyboard device driver that actually intercepts DirectInput calls (and doesn't work consistently). Other than tackling this problem at the hardware level I think you would have to write a device driver specifically for each game you want to intercept keyboard input that uses DirectInput, yet somehow the Window Send command is working (possibly from calls to the MapVirtualKey and VkKeyScan as you suggested). Do you know if this code for the Window Send command will be used in VDS 6? |
|
| Back to top |
|
 |
jrmarquart Valued Newbie
Joined: 12 Jun 2004 Posts: 28 Location: Boise, ID
|
Posted: Fri Apr 08, 2005 2:15 am Post subject: |
|
|
I found a message thread with a user that appears to be having exactly the same problem I am having with the DirectInput issue. The only problem is the solution was presented in the Delphi language which I'm not familiar with. Any Delphi wizards out there that can convert the following to VDS code using the keybd_event library (if possible)?
| Code: |
keybd_event(VkKeyScan('C'), MapVirtualKey(VkKeyScan('C'), 0), 0, 0);
Rem sets the C key down using VkKeyScan and MapVirtualKey
keybd_event(VkKeyScan('C'), MapVirtualKey(VkKeyScan('C'), 0), KEYEVENTF_KEYUP, 0);
Rem sets the C key up using VkKeyScan and MapVirtualKey
|
I apologize if this post has moved beyond the scope of the vdsworld.com forum, but any help would be greatly appreciated. |
|
| Back to top |
|
 |
ShinobiSoft Professional Member


Joined: 06 Nov 2002 Posts: 790 Location: Knoxville, Tn
|
Posted: Fri Apr 08, 2005 3:01 am Post subject: |
|
|
| jrmarquart wrote: | I found a message thread with a user that appears to be having exactly the same problem I am having with the DirectInput issue. The only problem is the solution was presented in the Delphi language which I'm not familiar with. Any Delphi wizards out there that can convert the following to VDS code using the keybd_event library (if possible)?
| Code: |
keybd_event(VkKeyScan('C'), MapVirtualKey(VkKeyScan('C'), 0), 0, 0);
Rem sets the C key down using VkKeyScan and MapVirtualKey
keybd_event(VkKeyScan('C'), MapVirtualKey(VkKeyScan('C'), 0), KEYEVENTF_KEYUP, 0);
Rem sets the C key up using VkKeyScan and MapVirtualKey
|
I apologize if this post has moved beyond the scope of the vdsworld.com forum, but any help would be greatly appreciated. |
Your posted code is 'C' not Delphi. The calls are exactly the same for the
API calls you will need to make using VDS 5. You will need to break the
function calls down into individual calls and store some results in variables. _________________ Bill Weckel
ShinobiSoft Software
"The way is known to all, but not all know it." |
|
| Back to top |
|
 |
jrmarquart Valued Newbie
Joined: 12 Jun 2004 Posts: 28 Location: Boise, ID
|
Posted: Sat Apr 09, 2005 1:54 am Post subject: |
|
|
Opps I just copied the code from a Delphi forum so I assumed it was Delphi - my mistake. Anyway I am really new to this API programming and just used Codescripts examples on how to use the keybd_event library. I am basically a newbie when it comes to programming.
| Quote: | | You will need to break the function calls down into individual calls and store some results in variables. |
Would it be to much to ask if an example can be given on how to do this using keybd_event? It's really not because I am just to lazy to do it myself I did look at the help file in VDS for @lib, but I don't understand how this can be done.  |
|
| Back to top |
|
 |
ShinobiSoft Professional Member


Joined: 06 Nov 2002 Posts: 790 Location: Knoxville, Tn
|
Posted: Sat Apr 09, 2005 2:50 am Post subject: |
|
|
I'm not sure if this code is correct, as I don't have a need for VDS 5.
Maybe one of the other VDS 5 programmers can verify the correctness of
the following code. Hopefully this helps.
| Code: |
rem This is how the API functions are defined
VOID keybd_event(BYTE vKey, BYTE bScan, DWORD dwFlags, DWORD dwExtra);
SHORT VkKeyScanA(TCHAR c);
UINT MapVirtualKeyA(UINT uCode, UINT uMapType);
|
| Code: |
REM EXAMPLE 1::
rem Set the key down event for the 'C' key
%%vKey = @lib(USER32, VkKeyScanA, INT:, INT: 'C')
%%vKeyMap = @lib(USER32, MapVirtualKeyA, INT:, INT: %%vKey, INT: 0)
%%void = @lib(USER32, keybd_event, NIL:, INT: %%vKey, INT: %%vKeyMap, INT: 0, INT: 0)
rem Set the key up event for the 'C' key
%%vKey = @lib(USER32, VkKeyScanA, INT:, INT: 'C')
%%vKeyMap = @lib(USER32, MapVirtualKeyA, INT:, INT: %%vKey, INT: 0)
rem KEYEVENTF_KEYUP is defined as 2
%%void = @lib(USER32, keybd_event, NIL:, INT: %%vKey, INT: %%vKeyMap, INT: 2, INT: 0)
REM EXAMPLE 2::
rem Set the key down event for the 'C' key
%%vKey = @lib(USER32, VkKeyScanA, INT:, C)
%%vKeyMap = @lib(USER32, MapVirtualKeyA, INT:, %%vKey, 0)
%%void = @lib(USER32, keybd_event, NIL:, %%vKey, %%vKeyMap, 0, 0)
rem Set the key up event for the 'C' key
%%vKey = @lib(USER32, VkKeyScanA, INT:, C)
%%vKeyMap = @lib(USER32, MapVirtualKeyA, INT:, %%vKey, 0)
rem KEYEVENTF_KEYUP is defined as 2
%%void = @lib(USER32, keybd_event, NIL:, %%vKey, %%vKeyMap, 2, 0)
|
_________________ Bill Weckel
ShinobiSoft Software
"The way is known to all, but not all know it." |
|
| Back to top |
|
 |
jrmarquart Valued Newbie
Joined: 12 Jun 2004 Posts: 28 Location: Boise, ID
|
Posted: Wed Apr 13, 2005 3:06 am Post subject: |
|
|
Thank you Jules and Bill for your help and pointing me in the right direction. The following code works perfectly in all games that I have tried so far that use DirectInput. I could not get the VkKeyScanA to work right, but found that I just really needed MapVirtualKeyA. Note: I have tried this with all regular keys and modifier keys, both examples work below. This is going to be much easier to implement than having to build a keyboard driver that works with DirectX and DirectInput.
| Code: |
rem EXAMPLE 1::
rem Set the key down event for the 'X' key - use virtual key code $58
LOADLIB USER32
%%vKeyMap = @lib(USER32, MapVirtualKeyA, INT:, INT: $58, INT: 0)
%%void = @lib(USER32, keybd_event, NIL:, INT: $58, INT: %%vKeyMap, INT: 0, INT: 0)
wait 1
rem Set the key up event for the 'X' key - use virtual key code $58
%%vKeyMap = @lib(USER32, MapVirtualKeyA, INT:, INT: $58, INT: 0)
%%void = @lib(USER32, keybd_event, NIL:, INT: $58, INT: %%vKeyMap, INT: 2, INT: 0)
FREELIB USER32
rem EXAMPLE 2::
rem Set the key down event for the 'X' key - use virtual key code $58
LOADLIB USER32
%%vKeyMap = @lib(USER32,MapVirtualKeyA,INT:,$58,0)
%%void = @lib(USER32,keybd_event,NIL:,INT:$58,INT:%%vKeyMap,0,0)
wait 1
rem Set the key up event for the 'X' key - use virtual key code $58
%%vKeyMap = @lib(USER32,MapVirtualKeyA,INT:,$58,0)
%%void = @lib(USER32,keybd_event,NIL:,INT:$58,INT:%%vKeyMap,2,0)
FREELIB USER32
|
 |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You can attach files in this forum You can download files in this forum
|
|