2011-12-06 12 views
10

JavaとJNA(Java Native Access)を使用してWindows APIと対話する方法を学習しようとしていますが、ロードブロックです。 SendInput(...)メソッドは、イベントが正常にキューに入れられたことを示す1を返しますが、マウス自体は何もしません。マウス入力ストリームでマウスイベントをキューイングしてマウスに何かを行わせると、コードが機能します。マウスの移動方法(または何かを行う方法)

マイSSCCE

編集: dwFlagsパラメータフィールドに入力するように編集。私は定数のいくつかの組み合わせを試してみました。ここでも、それが機能する方法を示唆しなければならないようSendInputメソッドは1を返しますが、マウスではびくともしません:

import com.sun.jna.Native; 
import com.sun.jna.platform.win32.WinDef.*; 
import com.sun.jna.platform.win32.WinUser.*; 
import com.sun.jna.win32.StdCallLibrary; 

public class MouseUtils { 
    public interface User32 extends StdCallLibrary { 
     public static final long MOUSEEVENTF_MOVE = 0x0001L; 
     public static final long MOUSEEVENTF_VIRTUALDESK = 0x4000L; 
     public static final long MOUSEEVENTF_ABSOLUTE = 0x8000L; 

     User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class); 
     DWORD SendInput(DWORD dWord, INPUT[] input, int cbSize); 
    } 

    public static void main(String[] args) { 
     INPUT input = new INPUT(); 
     input.type = new DWORD(INPUT.INPUT_MOUSE); 

     input.input.mi.dx = new LONG(500); 
     input.input.mi.dy = new LONG(500); 
     input.input.mi.mouseData = new DWORD(0); 
     input.input.mi.dwFlags = new DWORD(User32.MOUSEEVENTF_MOVE 
      | User32.MOUSEEVENTF_VIRTUALDESK | User32.MOUSEEVENTF_ABSOLUTE); 
     // input.input.mi.dwFlags = new DWORD(0x8000L); 
     input.input.mi.time = new DWORD(0); 

     INPUT[] inArray = {input}; 

     int cbSize = input.size(); // mouse input struct size 
     DWORD nInputs = new DWORD(1); // number of inputs 
     DWORD result = User32.INSTANCE.SendInput(nInputs , inArray, cbSize); 
     System.out.println("result: " + result); // return 1 if the 1 event successfully inserted 
    } 
} 

編集2:より多くの読み取りを行う

、それは私の理解と思われますJNAを使用した配列は不完全であり、配列は単に連続したメモリ領域へのポインタであるC配列に関して考える必要があります。もっと来てください(私は願っています!)。

+0

Offtopic:それは常にあなたが、素敵なリラックスした人々との友好されて見て喜びです。あなたは私が本当にここで調べている人の一人です。ハッピーホリデー;素晴らしい年2017! – GhostCat

+1

@GhostCat:あなたの最初のステートメントはやや面白いですが、2番目のステートメントはあまりにも親切です。そして、私はあなた、あなたの能力、そしてあなたの知識を他の人に伝えるあなたの欲望を見上げます。 –

答えて

9

JNAドキュメントUsing Structures And Unions読み取り:

組合は、構造体と、一般的に交換可能ですが、あなたはそれが正しく関数呼び出しに渡すことができる前に、労働組合のフィールドがsetType方法でアクティブであるかを示していることが必要です。

私はsetType部分を逃したと思います。また、MOUSEEVENTF_ABSOLUTEを使用する場合、dxdyがピクセルではなくマウスの座標として指定されます。

続い作品:

public interface User32 extends StdCallLibrary { 
    ... 
    public static final int SM_CXSCREEN = 0x0; 
    public static final int SM_CYSCREEN = 0x1; 
    int GetSystemMetrics(int index); 
} 

public static void main(String[] args) {  
    ... 
    input.input.setType("mi"); 
    input.input.mi.dx = new LONG(500 * 65536/User32.INSTANCE.GetSystemMetrics(User32.SM_CXSCREEN)); 
    input.input.mi.dy = new LONG(500 * 65536/User32.INSTANCE.GetSystemMetrics(User32.SM_CYSCREEN)); 
    ... 
} 
+3

聖なるチャット! 'setType(...)'はそれでした!入力変数の型フィールドを設定するだけで十分だと誤って想定していましたが、間違っていました。あなたの修正で私のコードが動作します。私は十分にあなたに感謝できません! –

2
input.input.mi.dwFlags = new DWORD(0); 

マウス入力フラグが指定されていないため、マウス入力がありませんでした。

+0

ありがとう!それを見てみましょう! –

+0

私の質問への編集と更新されたコードをご覧ください。すべての助けが大変ありがとう! –

+0

あなたの素晴らしい提案をお寄せいただきありがとうございます。彼らは最も役に立ちました! –

3

構造体のtoArray()メソッドを呼び出して、連続したメモリブロックを取得します。

INPUT input = new INPUT(); 
INPUT[] arg = (INPUT[])input.toArray(1); 

また、あなたは、単にSendInputの代替方法のマッピングを宣言することができます。(?おそらく、権限、UIPIにMSノートを参照してください)

DWORD SendInput(int nInputs, INPUT pInputs, int cbSize); 

しかし、上で起こって何か他のものがあるかもしれない、あなた以来例は(少なくとも1つの配列要素で)動作する必要があります。

EDIT:実際には、Union.setType()の回答が正しいです。

+0

貴重なご意見ありがとうございます!私は大いに感謝します。私はあなたの投稿に投票しましたが、助けてくれた人の中から恩恵を分けることができればと思っています。 –

関連する問題