News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

SendInput

Started by ragdog, May 01, 2011, 03:34:24 PM

Previous topic - Next topic

ragdog

Hi

I try to coding with SendInput now must i fill this struct

By compile get i this error


  INPUT struct
wVk    WORD    ?
wScan    WORD    ?
dwFlags    DWORD    ?
time    DWORD    ?
dwExtraInfo    DWORD    ?
    INPUT ends 
.data
inputx INPUT <>

.code
mov inputx.type , 1
mov inputx.wVk ,VK_CONTROL; // STRG                         <<<<<<<<<<error A2081: missing operand after unary operator
mov inputx.wScan , 0;
mov inputx.dwFlags , 0; // KEY_DOWN + VKCODE

mov inputx.type , 1
mov inputx.wVk , 0;                                                    <<<<<<<<<<<error A2081: missing operand after unary operator
mov inputx.wScan , 0x2E; // 'C'
mov inputx.dwFlags, KEYEVENTF_SCANCODE; // KEY_DOWN + SCANCODE <<<error A2206: missing operator in expression




dedndave

not sure "INPUT" is a good name for the structure type definition  :P
INPUTSTRUC struct
  wVk         WORD  ?
  wScan       WORD  ?
  dwFlags     DWORD ?
  time        DWORD ?
  dwExtraInfo DWORD ?
INPUTSTRUC ends

.data
inputx INPUTSTRUC <>

Tedd

It would help to define it correctly.. (you missed off 'type')


MOUSEINPUT struct
    _dx         LONG    ?
    _dy         LONG    ?
    mouseData   DWORD   ?
    dwFlags     DWORD   ?
    time        DWORD   ?
    dwExtraInfo PULONG  ?
MOUSEINPUT ends

KEYBDINPUT struct
    wVk         WORD    ?
    wScan       WORD    ?
    dwFlags     DWORD   ?
    time        DWORD   ?
    dwExtraInfo PULONG  ?
KEYBDINPUT ends

HARDWAREINPUT struct
    uMsg        DWORD   ?
    wParamL     WORD    ?
    wParamH     WORD    ?
HARDWAREINPUT ends

INPUT struct
    dwType      DWORD   ?
    UNION
        mi      MOUSEINPUT <>
        ki      KEYBDINPUT <>
        hi      HARDWAREINPUT <>
    ENDS
INPUT ends

;constants for dwType
INPUT_MOUSE     equ 0
INPUT_KEYBOARD  equ 1
INPUT_HARDWARE  equ 2

No snowflake in an avalanche feels responsible.

dedndave

so - INPUT is a good name   :bg
surprising it isn't defined in windows.inc
still, it does not seem like that would cause the "unary operator" error he is getting
it shouldn't crash until the INVOKE is executed - lol

qWord

Quotemov inputx.wScan , 0x2E;
this syntax is not supported by masm.
-> 2Eh
FPU in a trice: SmplMath
It's that simple!

Tedd

Quote from: dedndave on May 01, 2011, 04:12:14 PM
still, it does not seem like that would cause the "unary operator" error he is getting
It's a misleading parser error - the error actually comes from the line before, with an unknown symbol name ('type').

There are a few other problems, but that's the fun of blindly copy-and-pasting code :P
No snowflake in an avalanche feels responsible.

ragdog

Thanks Tedd for this structur

Now can i comile this

But why can i not send a Key Combo (CTRL+G)?


invoke SetFocus,hMain
mov inputx.dwType ,INPUT_KEYBOARD
mov inputx.ki.wVk,VK_CONTROL
mov inputx.ki.wScan , 0;
mov inputx.ki.dwFlags , 0; // KEY_DOWN + VKCODE
;
mov inputx.dwType , INPUT_KEYBOARD;
mov inputx.ki.wVk , 0;
mov inputx.ki.wScan , 047h; // 'G'
mov inputx.ki.dwFlags , KEYEVENTF_SCANCODE; // KEY_DOWN + SCANCODE
invoke SendInput,2, addr inputx, sizeof INPUT; // Sende

;// KEY_UP
mov inputx.ki.dwFlags , KEYEVENTF_KEYUP; // KEYUP + VKCODE
mov inputx.ki.dwFlags , KEYEVENTF_SCANCODE + KEYEVENTF_KEYUP; // KEYUP + SCANCODE

invoke SendInput,2, addr inputx, sizeof INPUT; // Send

MichaelW

You need an array of INPUT structures with one element for each input event.

This source uses a slightly different set of structures. It simply toggles the NumLock key each time it is run (build as a console app).

;=========================================================================
    include \masm32\include\masm32rt.inc
;=========================================================================

printf MACRO format:REQ, args:VARARG
    IFNB <args>
        invoke crt_printf, cfm$(format), args
    ELSE
        invoke crt_printf, cfm$(format)
    ENDIF
    EXITM <>
ENDM

;=========================================================================

    MOUSEINPUT STRUCT
      d_x         DWORD ?
      d_y         DWORD ?
      mouseData   DWORD ?
      dwFlags     DWORD ?
      time        DWORD ?
      dwExtraInfo DWORD ?
    MOUSEINPUT ENDS

    KEYBDINPUT STRUCT
      wVk         WORD ?
      wScan       WORD ?
      dwFlags     DWORD ?
      time        DWORD ?
      dwExtraInfo DWORD ?
    KEYBDINPUT ENDS

    INPUT STRUCT
      dwType      DWORD ?
      UNION
        mi        MOUSEINPUT <>
        ki        KEYBDINPUT <>
      ENDS
    INPUT ENDS

;=========================================================================
    .data

        ;----------------------------------------
        ; Define an array of 2 INPUT structures.
        ;----------------------------------------

        inp INPUT 2 dup(<>)

    .code
;=========================================================================
start:
;=========================================================================

    ;-------------------------------------------------------------
    ; We need the size of the INPUT structure to index the array.
    ;-------------------------------------------------------------

    N = SIZEOF INPUT
    printf( "%d\n", N )

    ;-----------------------------------------------------
    ; The array needs to specify 2 events, a press of the
    ; NumLock key and release of the NumLock key.
    ;-----------------------------------------------------

    mov inp[N*0].dwType, INPUT_KEYBOARD
    mov inp[N*0].ki.wVk, VK_NUMLOCK
    mov inp[N*0].ki.dwFlags, 0
    mov inp[N*1].dwType, INPUT_KEYBOARD
    mov inp[N*1].ki.wVk, VK_NUMLOCK
    mov inp[N*1].ki.dwFlags, KEYEVENTF_KEYUP

    invoke SendInput, 2, ADDR inp, SIZEOF INPUT
    printf( "%d\n\n", eax )

    inkey "Press any key to exit..."
    exit
;=========================================================================
end start

eschew obfuscation

dedndave

you mean it won't work by using the same structure 4 times ?
1) ctrl key down
2) g key down
3) g key up
4) ctrl key up

MichaelW

I've never tried passing a single event per call, but reusing the same structure obviously will not work for a single call passing multiple events. And I'm virtually certain that shift-key events need to be passed in the same call as the key they modify.
eschew obfuscation

dedndave

Quote...reusing the same structure obviously will not work for a single call passing multiple events

ohhhhh - i was talking about 4 calls

...i guess it's just as well to do it with an array of 4 events
but - i would use initialized data for the array
the code required to fill the structure is bigger than the structure   :P

MichaelW

Splitting my code into two calls breaks it, so it can toggle NumLock on but not off. And then the next time I try to toggle NumLock manually I have to press and release it twice.
eschew obfuscation

dedndave

ok - now, i have a question   :P

if we have a simple nested structure, we can initialize it like so
somedata somestruct <0,0,<0,0>,0,0>

but, now we have a nested structure with a union (various sizes)
;---------------------------------

MOUSEINPUT    STRUCT    ;24 bytes
  _dx         dd ?
  _dy         dd ?
  mouseData   dd ?
  dwFlags     dd ?
  time        dd ?
  dwExtraInfo dd ?
MOUSEINPUT    ENDS

KEYBDINPUT    STRUCT    ;16 bytes
  wVk         dw ?
  wScan       dw ?
  dwFlags     dd ?
  time        dd ?
  dwExtraInfo dd ?
KEYBDINPUT    ENDS

HARDWAREINPUT STRUCT    ;8 bytes
  uMsg        dd ?
  wParamL     dw ?
  wParamH     dw ?
HARDWAREINPUT ENDS

INPUT         STRUCT    ;28 bytes
  dwType      dd ?
  UNION
    mi MOUSEINPUT    <>
    ki KEYBDINPUT    <>
    hi HARDWAREINPUT <>
  ENDS
INPUT         ENDS

;---------------------------------

how do i tell the initializer i want a keyboard struct ?
like this ?
kia INPUT <INPUT_KEYBOARD,ki<VK_TAB, 0, KEYEVENTF_KEYDOWN, 0,0>>

MichaelW

The Microsoft documentation does not show any way to specify a type when initializing a union, but it does state that the type of the initializer must be the type of the first field. The way my structure was laid out the MOUSEINPUT structure was first in the union, so wVk was being initialized as a DWORD. To make the initialization work I had to place the KEYBDINPUT structure first in the union.

;=========================================================================
    include \masm32\include\masm32rt.inc
;=========================================================================

printf MACRO format:REQ, args:VARARG
    IFNB <args>
        invoke crt_printf, cfm$(format), args
    ELSE
        invoke crt_printf, cfm$(format)
    ENDIF
    EXITM <>
ENDM

;=========================================================================

    MOUSEINPUT STRUCT
      d_x         DWORD ?
      d_y         DWORD ?
      mouseData   DWORD ?
      dwFlags     DWORD ?
      time        DWORD ?
      dwExtraInfo DWORD ?
    MOUSEINPUT ENDS

    KEYBDINPUT STRUCT
      wVk         WORD ?
      wScan       WORD ?
      dwFlags     DWORD ?
      time        DWORD ?
      dwExtraInfo DWORD ?
    KEYBDINPUT ENDS

;    INPUT STRUCT
;      dwType      DWORD ?
;      UNION
;        mi        MOUSEINPUT <>
;        ki        KEYBDINPUT <>
;      ENDS
;    INPUT ENDS

    INPUT STRUCT
      dwType      DWORD ?
      UNION
        ki        KEYBDINPUT <>
        mi        MOUSEINPUT <>
      ENDS
    INPUT ENDS

;=========================================================================
    .data

        ;-------------------------------------------------------
        ; Define and initialize an array of 2 INPUT structures.
        ;-------------------------------------------------------

        inp   INPUT <INPUT_KEYBOARD,{<VK_NUMLOCK,0,0>}>
              INPUT <INPUT_KEYBOARD,{<VK_NUMLOCK,0,KEYEVENTF_KEYUP>}>

    .code
;=========================================================================
start:
;=========================================================================

    ;-------------------------------------------------------------
    ; We need the size of the INPUT structure to index the array.
    ;-------------------------------------------------------------

    N = SIZEOF INPUT
    printf( "%d\n", N )

    ;-----------------------------------------------------
    ; The array needs to specify 2 events, a press of the
    ; NumLock key and release of the NumLock key.
    ;-----------------------------------------------------

    ;mov inp[N*0].dwType, INPUT_KEYBOARD
    ;mov inp[N*0].ki.wVk, VK_NUMLOCK
    ;mov inp[N*0].ki.dwFlags, 0
    ;mov inp[N*1].dwType, INPUT_KEYBOARD
    ;mov inp[N*1].ki.wVk, VK_NUMLOCK
    ;mov inp[N*1].ki.dwFlags, KEYEVENTF_KEYUP

    invoke SendInput, 2, ADDR inp, SIZEOF INPUT
    printf( "%d\n\n", eax )

    inkey "Press any key to exit..."
    exit
;=========================================================================
end start


This has been an interesting exercise, but I think I'll stick with the longer initialization :lol

eschew obfuscation

dedndave

thanks Michael
seems a little sloppy on ms' part - lol
but - i can see where this could get confusing very fast
i think you are on to a solution that will work in this case
only the keyboard input (nested) structure starts with a word type
so, i am guessing that something like "word ptr VK_TAB" might work
that doesn't really solve the issue in other cases, though

i think a "brute force" approach might be worth a try in more complex cases
kia LABEL INPUT
dd INPUT_KEYBOARD
dw xxx
dw xxx
dd xxx
dd xxx
dd xxx
dd xxx
dd xxx

the use of "LABEL" might do the job   :P
that may allow you to access individual members in normal structure fashion