Can't get INPUT to work using Struct Topic is solved

Ask for help, how to use AHK_H, etc.
kyuuuri
Posts: 340
Joined: 09 Jan 2016, 19:20

Can't get INPUT to work using Struct

Post by kyuuuri » 25 Apr 2020, 08:17

Hello, I'm trying to create an INPUT structure.
Related links: https://docs.microsoft.com/es-es/windows/win32/api/winuser/ns-winuser-input and https://docs.microsoft.com/es-es/windows/win32/api/winuser/ns-winuser-mouseinput

This is my code:

Code: Select all

/*
typedef struct tagINPUT {
  DWORD type;
  union {
    MOUSEINPUT    mi;
    KEYBDINPUT    ki;
    HARDWAREINPUT hi;
  } DUMMYUNIONNAME;
} INPUT, *PINPUT, *LPINPUT;
*/

/*
typedef struct tagMOUSEINPUT {
  LONG      dx;
  LONG      dy;
  DWORD     mouseData;
  DWORD     dwFlags;
  DWORD     time;
  ULONG_PTR dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT, *LPMOUSEINPUT;
*/
f1::
mouseInput := Struct("DWORD type, LONG dx, LONG dy, DWORD mouseData, DWORD dwFlags, DWORD time, ULONG_PTR dwExtraInfo")

mouseInput.type := 0
mouseInput.dx := 0
mouseInput.dy := 0
mouseInput.mouseData := 0
mouseInput.dwFlags := 0x0002
mouseInput.time := 0
mouseInput.dwExtraInfo := 0

msgbox % NumGet(mouseInput , 20, "UINT")
DllCall("SendInput", "UInt", 1, "Ptr", &mouseInput, "Int", sizeof(mouseInput))
sleep, 200
mouseInput.dwFlags := 0x0004
DllCall("SendInput", "UInt", 1, "Ptr", &mouseInput, "Int", sizeof(mouseInput))
return


f2::
structSize := A_PtrSize + 4*4 + A_PtrSize*2
VarSetCapacity( mouseinput, structSize, 0 )
NumPut( 0x0002, mouseinput, A_PtrSize + 4*3, "UInt" ) ; MOUSEEVENTF_LEFTDOWN = 0x0002
DllCall("SendInput", "UInt", 1, "Ptr", &mouseinput, "Int", structSize )
sleep 200
NumPut( 0x0004, mouseinput, A_PtrSize + 4*3, "UInt" ) ; MOUSEEVENTF_LEFTUP = 0x0004
DllCall("SendInput", "UInt", 1, "Ptr", &mouseinput, "Int", structSize )
return
The f2 option uses NumPut and works as expected. You can see that the structSize is 40 bytes (x64 bits version).
On the f1 I get only 32 bytes, 8 bytes less than the NumPut option.

Questions
  1. When I did sizeOf("LONG") it outputs 4 bytes. Isn't it supposed to be 8 bytes?
  2. Even If I change the LONG to PTR to make them be 8 bytes, I still get a different size and the NumGet still outputs a blank value, and ofc the dllcall doesn't work.
  3. What am I doing wrong?
Thanks in advance.

kyuuuri
Posts: 340
Joined: 09 Jan 2016, 19:20

Re: Can't get INPUT to work using Struct

Post by kyuuuri » 25 Apr 2020, 08:31

Tried this code as well:

Code: Select all

f1::
INPUT := "
(
	DWORD type;
    MOUSEINPUT    mi;
)"

MOUSEINPUT := "
(
	LONG      dx;
	LONG      dy;
	DWORD     mouseData;
	DWORD     dwFlags;
	DWORD     time;
	ULONG_PTR dwExtraInfo;
)"

Data := Struct(INPUT)

Data.type := 0
Data.mi.dwFlags := 0x0002

DllCall("SendInput", "UInt", 1, "Ptr", &Data, "Int", sizeof(Data))
sleep, 200
Data.mi.dwFlags := 0x0004
DllCall("SendInput", "UInt", 1, "Ptr", &Data, "Int", sizeof(Data))
return
Now the struct size is 40 which seems to be correct but the dllCall still fails and when I do msgbox % NumGet(Data, 20, "UINT") I get a blank value.

HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: Can't get INPUT to work using Struct  Topic is solved

Post by HotKeyIt » 25 Apr 2020, 09:14

The pointer of Struct is returned by using mystruct[] instead of &mystruct.
On creation all fields are set to 0 and you can also initialize the Struct directly: Struct(INPUT,,{mi:{dwFlags:0x2}})
Also no need to create Struct every time.

Code: Select all

INPUT := "
(
	DWORD type;
	MOUSEINPUT mi;
)"

MOUSEINPUT := "
(
	LONG      dx;
	LONG      dy;
	DWORD     mouseData;
	DWORD     dwFlags;
	DWORD     time;
	ULONG_PTR dwExtraInfo;
)"

f1::
if !mi
  mi := Struct(INPUT)
mi.mi.dwFlags := 0x2
DllCall("SendInput", "UInt", 1, "Ptr", mi[], "Int", sizeof(mi))
sleep 200
mi.mi.dwFlags := 0x4
DllCall("SendInput", "UInt", 1, "Ptr", mi[], "Int", sizeof(mi))
return

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Can't get INPUT to work using Struct

Post by swagfag » 25 Apr 2020, 09:44

for v2 if u implemented the addressof struct as a .Ptr property, u could pass it to DllCall as is

kyuuuri
Posts: 340
Joined: 09 Jan 2016, 19:20

Re: Can't get INPUT to work using Struct

Post by kyuuuri » 25 Apr 2020, 14:48

Hi, thank you! it's fixed that
swagfag wrote:
25 Apr 2020, 09:44
for v2 if u implemented the addressof struct as a .Ptr property, u could pass it to DllCall as is
Using v1 for now, still good info didn't know that about v2. Thank you

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Can't get INPUT to work using Struct

Post by swagfag » 25 Apr 2020, 15:03

the info doesnt apply to v2
im just telling @HotKeyIt
Last edited by swagfag on 25 Apr 2020, 15:54, edited 1 time in total.

kyuuuri
Posts: 340
Joined: 09 Jan 2016, 19:20

Re: Can't get INPUT to work using Struct

Post by kyuuuri » 25 Apr 2020, 15:03

HotKeyIt wrote:
25 Apr 2020, 09:14
The pointer of Struct is returned by using mystruct[] instead of &mystruct.
On creation all fields are set to 0 and you can also initialize the Struct directly: Struct(INPUT,,{mi:{dwFlags:0x2}})
Also no need to create Struct every time.

Code: Select all

INPUT := "
(
	DWORD type;
	MOUSEINPUT mi;
)"

MOUSEINPUT := "
(
	LONG      dx;
	LONG      dy;
	DWORD     mouseData;
	DWORD     dwFlags;
	DWORD     time;
	ULONG_PTR dwExtraInfo;
)"

f1::
if !mi
  mi := Struct(INPUT)
mi.mi.dwFlags := 0x2
DllCall("SendInput", "UInt", 1, "Ptr", mi[], "Int", sizeof(mi))
sleep 200
mi.mi.dwFlags := 0x4
DllCall("SendInput", "UInt", 1, "Ptr", mi[], "Int", sizeof(mi))
return
Oh sorry to bother you again, now I can't make this work. I double checked everything, I repeated the same steps I did for the mouse input but it doesn't work. Same error, bad parameters.

Code: Select all

MINPUT := "
(
	DWORD type;
	MOUSEINPUT mi;
)"

KINPUT := "
(
	DWORD type;
	KEYBDINPUT ki;
)"

MOUSEINPUT := "
(
	LONG      dx;
	LONG      dy;
	DWORD     mouseData;
	DWORD     dwFlags;
	DWORD     time;
	ULONG_PTR dwExtraInfo;
)"


KEYBDINPUT := "
(
	WORD      wVk;
	WORD      wScan;
	DWORD     dwFlags;
	DWORD     time;
	ULONG_PTR dwExtraInfo;
)"
f2::
if !ki
  ki := Struct(KINPUT)
ki.type := 1
ki.ki.wScan := 0x10
ki.ki.dwFlags := 0x0008
DllCall("SendInput", "UInt", 1, "Ptr", ki[], "Int", sizeof(ki))
msgbox % a_lasterror
sleep 100
ki.ki.dwFlags := 0x000A
DllCall("SendInput", "UInt", 1, "Ptr", ki[], "Int", sizeof(ki))
return

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Can't get INPUT to work using Struct

Post by swagfag » 25 Apr 2020, 15:40

ur struct size is wrong. u have a union in there(size of largest member + padding), u cant just mix and match

Code: Select all

MOUSEINPUT := "
(
	LONG      dx;
	LONG      dy;
	DWORD     mouseData;
	DWORD     dwFlags;
	DWORD     time;
	ULONG_PTR dwExtraInfo;
)"


KEYBDINPUT := "
(
	WORD      wVk;
	WORD      wScan;
	DWORD     dwFlags;
	DWORD     time;
	ULONG_PTR dwExtraInfo;
)"

HARDWAREINPUT := "
(
	DWORD uMsg;
	WORD  wParamL;
	WORD  wParamH;
)"

INPUT := "
(
	DWORD type;
	  union {
	    MOUSEINPUT    mi;
	    KEYBDINPUT    ki;
	    HARDWAREINPUT hi;
	  };
)"

ki := Struct(INPUT)

HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: Can't get INPUT to work using Struct

Post by HotKeyIt » 25 Apr 2020, 15:43

You have to use the structure properly, otherwise the size won't be correct!

Code: Select all

INPUT := "
(
    DWORD type;
    {
        MOUSEINPUT mi;
        KEYBDINPUT ki;
        HARDWAREINPUT hi;
    }
)"
MOUSEINPUT := "
(
	LONG      dx;
	LONG      dy;
	DWORD     mouseData;
	DWORD     dwFlags;
	DWORD     time;
	ULONG_PTR dwExtraInfo;
)"
KEYBDINPUT := "
(
	WORD      wVk;
	WORD      wScan;
	DWORD     dwFlags;
	DWORD     time;
	ULONG_PTR dwExtraInfo;
)"
HARDWAREINPUT:="
(
	DWORD uMsg;
	WORD  wParamL;
	WORD  wParamH;
)"

f2::
	if !ki
		ki := Struct(INPUT,,{type:1,ki:{wScan:0x10}})
	ki.ki.dwFlags := 0x0008
	DllCall("SendInput", "UInt", 1, "Ptr", ki[], "Int", sizeof(ki))
	sleep 100
	ki.ki.dwFlags := 0x000A
	DllCall("SendInput", "UInt", 1, "Ptr", ki[], "Int", sizeof(ki))
return
swagfag wrote:
25 Apr 2020, 09:44
for v2 if u implemented the addressof struct as a .Ptr property, u could pass it to DllCall as is
implemented ;)

swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Can't get INPUT to work using Struct

Post by swagfag » 25 Apr 2020, 15:53

nice nice :thumbup:

kyuuuri
Posts: 340
Joined: 09 Jan 2016, 19:20

Re: Can't get INPUT to work using Struct

Post by kyuuuri » 25 Apr 2020, 16:41

Thank you!

Post Reply

Return to “Ask for Help”