2 messages in net.java.dev.jna.usersRe: [jna-users] Invoke "SendInput" th...
FromSent OnAttachments
ZipliesJan 20, 2008 4:52 am 
Timothy WallJan 20, 2008 6:17 am 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:Re: [jna-users] Invoke "SendInput" through JNA pressing LWINActions...
From:Timothy Wall (twal@dev.java.net)
Date:Jan 20, 2008 6:17:49 am
List:net.java.dev.jna.users

On Jan 20, 2008, at 7:52 AM, Ziplies wrote:

Hello,

yes, I know such questions may not be seen very well but I am really stuck here.

I want to send a KeyStroke to "SendInput" in user32.dll. I looked up some things at pinvoke and tried the procedure itself in VS2008 and C#. I think I did everything right while copying and changing it to Java and JNA, but it won't work.

The interface is pretty straight forward:

public interface User32 extends StdCallLibrary {

public static final User32 INSTANCE = (User32)Native.loadLibrary("user32", User32.class);

Extend W32API instead of StdCallLibrary, and pass DEFAULT_OPTIONS to loadLibrary. This will avoid issues with ASCII vs unicode options, and map String to the proper type.

/** * static extern uint SendInput(uint nInputs, INPUT [] pInputs, int cbSize); */ public abstract int SendInput(int nInputs, INPUT[] pInputs, int cbSize); }

From the header:

WINUSERAPI UINT WINAPI SendInput(UINT,LPINPUT,int);

As I do not really know what type to use as Structure Array I already tried INPUT[], Structure[], ByRef, PointerType etc pp.

You should be able to use either INPUT[], Structure[], or just plain Structure, assuming it is the first element of the array returned by Structure.toArray().

The Structs are: public static class MOUSEINPUT extends Structure { public int dx; public int dy; public int mouseData; public int dwFlags; public int time; public int dwExtraInfo; }

public static class KEYBDINPUT extends Structure { public short wVk; public short wScan; public int dwFlags; public int time; public int dwExtraInfo; }

public static class HARDWAREINPUT extends Structure { public int uMsg; public short wParamL; public short wParamH; }

public static class INPUT extends Structure { public int type; public MOUSEINPUT mi; public KEYBDINPUT ki; public HARDWAREINPUT hi; }

The fields mi/ki/hi are fields in an inner union.

public static class INPUT extends Structure { public int type; public _Anon anon; public static class _Anon extends Union { public MOUSEINPUT mi; public KEYBDINPUT ki; public HARDWAREINPUT hi; }

And I call it by: User32 user32 = User32.INSTANCE;

INPUT in = new INPUT(); in.type = 1; in.anon.ki.wVk = 0x5B; // Keycode für LWIN in.anon.ki.dwFlags = 0x00; // Keydown

in.anon.setType(KEYBDINPUT.class); // this will select the "ki" field

INPUT[] input = (INPUT[])in.toArray(1); int out = user32.SendInput(input.length, input, 28);

INPUT in2 = new INPUT(); in2.type = 1; in2.ki.wVk = 0x5B; // Keycode für LWIN in2.ki.dwFlags = 0x02; // Keydown INPUT[] input2 = (INPUT[])in2.toArray(2);

This will fail when calling the function, since the second union will be uninitialized.

out = user32.SendInput(input2.length, input2, 28);

The 28 come from Marshalling it under C#, but I tried everything over length, size etc pp. If it's input[0].size int out returns 0, if it's 28 int out returns 1, which if I understood correctly means one key is pressed, but still nothing happens.

The last argument is the size of one INPUT, which should get fixed up once you fix the structure declaration. If not, there's a bug in JNA's structure size calculation, but as long as it's bigger, you can still pass in a single INPUT and hard-code "28" and not have problems.

I tried to do it ByReference as suggested in the APIDoc but same effect.

You only want ByReference if you want a pointer to struct within a structure (instead of using a vanilla Pointer). By default, structs are by value when used within another struct.