Hi guys i'm having problems getting SendInput working.
I don't quite understand how to make this struct.
INPUT struct
INPUT_KEYBOARD DW 1
union
wVk DD 41h
wScan DD 0
dwFlags DW 0
time DW 0
dwExtraInfo DW 0
ends
INPUT ends
When using my debugger i get error_invalid_parameter.
As you can see I am lost .
Btw I have to use sendinput ;)
Any help on this would be great.
Thanks.
Gavin
Since your declaring initialized data in your structure,did you make sure it is in the data section of your code? If its declared anywhere else then the compiler expects uninitialized data.
.data
MyStruct struct
nNumber dw 5
union
Member1 dd 0
Member2 dd 1
ends
ends MyStruct
or anywhere else
.data?
MyStruct struct
nNumber dw ?
union
Member1 dd ?
Member2 dd ?
ends
ends MyStruct
Hi.
I declared it in the .data section allright.
It assembles fine ,but obviously I'm doing something wrong .
Is my structure done correctly is the first thing?
typedef struct tagINPUT {
DWORD type;
union {MOUSEINPUT mi;
KEYBDINPUT ki;
HARDWAREINPUT hi;
};
}INPUT, *PINPUT;
typedef struct tagKEYBDINPUT {
WORD wVk;
WORD wScan;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT;
My structure
INPUT struct
INPUT_KEYBOARD DW 1
union
wVk DD 41h
wScan DD 0
dwFlags DW 0
time DW 0
dwExtraInfo DW 0
ends
INPUT ends
Thanks.
It looks like the first entry should be a double and you declared it as a word. You also need to convert each of the items in the union to a masm structure-
INPUTRECORD struct
type dd ?
union
mi MOUSEINPUT <>
ki KEYBDINPUT <>
hi HARDWAREINPUT <>
ends
INPUTRECORD ends
where MOUSEINPUT=
typedef struct tagMOUSEINPUT {
LONG dx;
LONG dy;
DWORD mouseData;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
}
KEYBOARDINPUT=
typedef struct tagKEYBDINPUT {
WORD wVk;
WORD wScan;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
}
HARDWAREINPUT =
typedef struct tagHARDWAREINPUT {
DWORD uMsg;
WORD wParamL;
WORD wParamH;
}
These last three also need to be translated to masm.
Hi Jimg.
INPUT struct
dtype WORD 1
union
wVk WORD ?
wScan WORD ?
dwFlags DWORD ?
time DWORD ?
dwExtraInfo DWORD ?
ends
INPUT ends
I don't quite understand what your saying.
I read about unions and structs but so far thisis the best i can do without more help.
So all i do is code this in the .data section and then i can use it from sendinput right?
Thanks for your help so far.
Gavin,
Do you have a reference version of the structure in C ? It would make it a lot easier to convert if we knew what it was supposed to do.
Not quite. First word is a dword. And in this case, since you are only doing the keyboard, you wouldn't use union. If you were going to define the mouse and hardware inputs you would use union so they would all be in the same memory location.
INPUT struct
dtype DWORD ?
wVk WORD ?
wScan WORD ?
dwFlags DWORD ?
time DWORD ?
dwExtraInfo DWORD ?
INPUT ends
I think that should answer your question, but here is a bunch more info to confuse you-
The long form, with all three kinds of input defined would be:
The documentation on the microsoft site http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/sendinput.aspsays the syntax for the SendInput API is:
QuoteSyntax
UINT SendInput(
UINT nInputs,
LPINPUT pInputs,
int cbSize
);
Parameters
nInputs
[in] Specifies the number of structures in the pInputs array.
pInputs
[in] Pointer to an array of INPUT structures. Each structure represents an event to be inserted into the keyboard or mouse input stream.
cbSize
[in] Specifies the size, in bytes, of an INPUT structure. If cbSize is not the size of an INPUT structure, the
The format of pInputs would be:
INPUTS struct ;; or any name you want. I'm gunshy of using input for a structure name.
dtype dword ?
union
mi MOUSEINPUT <>
ki KEYBDINPUT <>
hi HARDWAREINPUT <>
ends
INPUTS ends
but before that you have to define the internal structures. I don't speak C so I may have converted these incorrectly, if so, someone will speak up.
, so these come first before the INPUTS structure above-
MOUSEINPUT struc
dx LONG ?
dy LONG ?
mouseData DWORD ?
dwFlags DWORD ?
time DWORD ?
dwExtraInfo DWORD ? ;;;*** I don't know for sure what a ULONG_PTR is but I'm guessing a dword.
MOUSEINPUT ends
KEYBOARDINPUT struc
wVk WORD ?
wScan WORD ?
dwFlags DWORD ?
time DWORD ?
dwExtraInfo DWORD ?
KEYBOARDINPUT ends
HARDWAREINPUT struct
typedef struct tagHARDWAREINPUT {
uMsg DWORD ?
wParamL WORD ?
wParamH WORD ?
HARDWAREINPUT ends
Hey .
Thanks so much for your help Jimg.
I never knew word was a dword. hmm
But after you spending so time on my questions it shows i need to learn a little c ,
since asm is dependant on at least some knowledge of it.(espcially structures :)
I am not sure either what it means by a pointer to an array of input structures.
But i'm going to search around and see if i can find out for myself.
Sometimes i feel bad posting questions here.
Thanks for all your help man.
I'll post back if i can't sort this thing out as my head is wrecked :dazzled:
Thanks again i learned alot from the post ;)
Update i think most of this is correct.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
window_class db 'Valve001',0
handle dd ?
thread_id dd ?
.data?
KEYBOARDINPUT struc
dtype DWORD ?
wVk WORD ?
wScan WORD ?
dwFlags DWORD ?
time DWORD ?
dwExtraInfo DWORD ?
KEYBOARDINPUT ends
keys KEYBOARDINPUT <>
.code
start:
invoke FindWindow,
addr window_class,
NULL
mov handle,eax
invoke GetWindowThreadProcessId,
handle,
thread_id
mov thread_id,eax
invoke SetForegroundWindow,
handle
mov [keys.dtype],1
mov [keys.wVk],41h
mov [keys.wScan],41h
mov [keys.dwFlags],0
mov [keys.time],0
mov [keys.dwExtraInfo],0
invoke SendInput,
1,
ADDR keys, ;pointer to an array of input structures
SIZEOF KEYBOARDINPUT
invoke ExitProcess,NULL
end start
I'm still getting the invalid parameter after i call sendinput.
Here's an alternate method I've used successfully. I use this program every day with no problems.
.686p
.model flat, stdcall
option casemap :none ; case sensitive
.nolist
include windows.inc
inv equ Invoke
uselib MACRO libname
include libname.inc
includelib libname.lib
ENDM
uselib user32
uselib kernel32
uselib masm32
uselib debug
.listall
.data?
Phase dd ?
CurrWnd dd ?
TaskName db 100 dup (?)
.data
MedVed db 'Default Portfolio - Medved QuoteTracker',0
PortFolio db 'Portfolios and Alerts',0
.code
Program:
mov Phase,1
DoitStart:
inv FindWindow,0,0 ; get starting window
mov CurrWnd,eax
DoitLoop:
cmp eax,0
je DoitDone
inv GetWindowTextLength,CurrWnd
.if eax>0
inv GetWindowText,CurrWnd,addr TaskName,99
;PrintString TaskName
mov ecx,offset TaskName
.if Phase==1
mov edx,offset MedVed
.else
mov edx,offset PortFolio
.endif
@@:
mov al,[edx] ; compare window found against what we want
cmp al,0
je @f ; found all we wanted
cmp al,[ecx]
jne NextWindow ; not this one, go look for next window name
inc ecx
inc edx
jmp @b
@@:
.if Phase==1
inv IsIconic,CurrWnd ; if minimized
.IF eax!=0
inv OpenIcon,CurrWnd ; restore
;inv ShowWindow,CurrWnd,SW_RESTORE
.ENDIF
inv SetForegroundWindow,CurrWnd
inv keybd_event, VK_MENU, 0, 0, 0 ;Send Alt key 'down'
inv Sleep, 40
inv keybd_event, VK_P, 0, 0, 0 ;Send P key 'down'
inv Sleep, 40
inv keybd_event, VK_P, 0, KEYEVENTF_KEYUP, 0 ;Send P key 'up'
inv Sleep, 40
inv keybd_event, VK_MENU, 0, KEYEVENTF_KEYUP, 0 ;Send Alt key 'up'
inv Sleep, 40
inv keybd_event, VK_E, 0, 0, 0 ;Send E key 'down'
inv Sleep, 40
inv keybd_event, VK_E, 0, KEYEVENTF_KEYUP, 0 ;Send E key 'up'
inc Phase
jmp DoitStart
.else ; Phase 2, move the window
inv Sleep,40
inv MoveWindow, CurrWnd, 425, 0, 600, 436, TRUE
jmp DoitDone
.endif
.endif
NextWindow:
inv GetWindow,CurrWnd,GW_HWNDNEXT
mov CurrWnd,eax
jmp DoitLoop
DoitDone:
inv ExitProcess, 0
end Program
Nice program Jimg :U
But i cannot use the keybd_event as i am trying to make a bot for my game.
The game uses directinput and keybd_event won't work with that.
:'(
Ok, I converted my program to sendinput and got it working. Try this structure.
KEYBOARDINPUT struc
dtype DWORD ?
wVk WORD ?
wScan WORD ?
dwFlags DWORD ?
time DWORD ?
dwExtraInfo DWORD ?
dummy1 db 8 dup (?)
KEYBOARDINPUT ends
Apparently the extra 8 bytes that would be needed for mouseinput are required even though unused. I found also I had to do a larger delay between keystrokes using sendinput rather than keybd_event.
And after a little trial and error, the way sendinput was meant to be used, with multiple keys. This is just my previous program converted to sendinput.
; Bring up portfolio edit in Medved QuoteTracker
.686p
.model flat, stdcall
option casemap :none ; case sensitive
.nolist
include windows.inc
inv equ Invoke
uselib MACRO libname
include libname.inc
includelib libname.lib
ENDM
uselib user32
uselib kernel32
uselib masm32
uselib debug
.listall
.data?
Phase dd ?
CurrWnd dd ?
TaskName db 100 dup (?)
KEYBOARDINPUT struc
dtype DWORD ?
wVk WORD ?
wScan WORD ?
dwFlags DWORD ?
time DWORD ?
dwExtraInfo DWORD ?
dummy1 db 8 dup (?)
KEYBOARDINPUT ends
KSize equ sizeof KEYBOARDINPUT
kdata equ [edx].KEYBOARDINPUT ; how to get to data using edx as base register
Keys db 10*KSize dup (?) ; set aside enough for 10 events (280 bytes)
.data
MedVed db 'Default Portfolio - Medved QuoteTracker',0
PortFolio db 'Portfolios and Alerts',0
.code
Program:
mov Phase,1
mov edx,offset Keys
mov ecx,10 ; setup 10 keys
@@:
mov kdata.dtype,INPUT_KEYBOARD
mov kdata.wScan,0
mov kdata.dwFlags,0
mov kdata.time,0
mov kdata.dwExtraInfo,0
add edx,KSize
dec ecx
jnz @b
DoitStart:
inv FindWindow,0,0 ; get starting window
mov CurrWnd,eax
DoitLoop:
cmp eax,0
je DoitDone
inv GetWindowTextLength,CurrWnd
.if eax>0
inv GetWindowText,CurrWnd,addr TaskName,99
;PrintString TaskName
mov ecx,offset TaskName
.if Phase==1
mov edx,offset MedVed
.else
mov edx,offset PortFolio
.endif
@@:
mov al,[edx] ; compare window found against what we want
cmp al,0
je @f ; found all we wanted
cmp al,[ecx]
jne NextWindow ; not this one, go look for next window name
inc ecx
inc edx
jmp @b
@@:
.if Phase==1
inv IsIconic,CurrWnd ; if minimized
.IF eax!=0
inv OpenIcon,CurrWnd ; restore
;inv ShowWindow,CurrWnd,SW_RESTORE
.ENDIF
inv SetForegroundWindow,CurrWnd
; inv keybd_event, VK_MENU, 0, 0, 0 ;Send Alt key 'down'
; inv keybd_event, VK_P, 0, 0, 0 ;Send P key 'down'
; inv keybd_event, VK_P, 0, KEYEVENTF_KEYUP, 0 ;Send P key 'up'
; inv keybd_event, VK_MENU, 0, KEYEVENTF_KEYUP, 0 ;Send Alt key 'up'
; inv keybd_event, VK_E, 0, 0, 0 ;Send E key 'down'
; inv keybd_event, VK_E, 0, KEYEVENTF_KEYUP, 0 ;Send E key 'up'
; now setup actual keys used in this test
mov edx,offset Keys
mov kdata.wVk,VK_MENU
add edx,KSize
mov kdata.wVk,VK_P
add edx,KSize
mov kdata.wVk,VK_P
mov kdata.dwFlags,KEYEVENTF_KEYUP
add edx,KSize
mov kdata.wVk,VK_MENU
mov kdata.dwFlags,KEYEVENTF_KEYUP
add edx,KSize
mov kdata.wVk,VK_E
add edx,KSize
mov kdata.wVk,VK_E
mov kdata.dwFlags,KEYEVENTF_KEYUP
inv SendInput,6,addr Keys,sizeof KEYBOARDINPUT
inc Phase
jmp DoitStart
.else ; Phase 2, move the window
inv Sleep,40
inv MoveWindow, CurrWnd, 425, 0, 600, 436, TRUE
jmp DoitDone
.endif
.endif
NextWindow:
inv GetWindow,CurrWnd,GW_HWNDNEXT
mov CurrWnd,eax
jmp DoitLoop
DoitDone:
inv ExitProcess, 0
end Program
There is a timing problem somewhere I havn't figured out. If I doubleclick on the .exe, it doesn't work. If I make a shortcut to the .exe on the desktop and doubleclick the shortcut, it seems to work fine. Makes me a little nervous though. Perhaps I need to insert sleeps after some of the keys to give the program a chance to respond. Or perhaps, there is some way to use generate a pause by sending a keystroke or mouse move or hardware input?
Hiya Jimg.
Thanks man.
I had the same timing problems and had to use the Sleep function for the keys.
The speed of sendinput is really fast man.
I'm using mine for an online game ,so i had to use sleep after i show the window.
But thanks to you i got it going allright.
About the pause i have not used it yet but
time DWORD ? maybe could be used?
I am not sure , and your problem seems very strange.
I just tried your code and changed the window to a.txt and open a.txt and it works fine man.