2016-04-07 10 views
0

SendInputメソッドを使用してマウス入力をシミュレートしようとしています。クリックなどが正しく機能していますが、座標が正しく設定されていません。入力が実行されるたびに、マウスカーソルが画面の右下隅に移動します。 MOUSEINPUT XとY座標を長いデータ型as listed in the MSDN documentationに変更しようとしましたが、SendInputメソッドは常にエラーを返し、入力は実行されません。C# - SendInputを使用するとMOUSEINPUT座標が正しく設定されない

以下は、これを試みるために使用しているコードです。 KEYBDINPUT構造体が作成され実行された同様の実装からこのコードを移植しました。その実装は完全に機能したので、私はなぜそうではないのか混乱しています。私は、それが問題を引き起こしている座標だけで、マウスクリックなどがうまく実行されると、非常に小さいものだと確信しています。

ここで何がうまくいかないかについての洞察があれば、援助をいただければ幸いです。

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 

namespace SequenceAutomation 
{ 
    #region Stucture declarations 

    public struct MOUSEINPUT 
    { 
     public int X; 
     public int Y; 
     public uint MouseData; 
     public uint Flags; 
     public uint Time; 
     public IntPtr ExtraInfo; 
    } 

    public struct HARDWAREINPUT 
    { 
     public uint Msg; 
     public ushort ParamL; 
     public ushort ParamH; 
    } 

    public struct KEYBDINPUT 
    { 
     public ushort KeyCode; 
     public ushort Scan; 
     public uint Flags; 
     public uint Time; 
     public IntPtr ExtraInfo; 
    } 

    [StructLayout(LayoutKind.Explicit)] 
    public struct MOUSEKEYBDHARDWAREINPUT 
    { 
     [FieldOffset(0)] 
     public MOUSEINPUT Mouse; 

     [FieldOffset(0)] 
     public KEYBDINPUT Keyboard; 

     [FieldOffset(0)] 
     public HARDWAREINPUT Hardware; 
    } 

    public struct INPUT 
    { 
     public uint Type; 
     public MOUSEKEYBDHARDWAREINPUT Data; 
    } 

    #endregion 

    public class PlayRecording 
    { 
     #region Variable declarations 

     public bool stopPlayback; 
     private RecordingManager recManager; 
     private float timeFactor; 
     private Dictionary<long, Dictionary<IntPtr, Dictionary<string, int>>> mouseDict; 
     private Dictionary<long, INPUT[]> keysToPlay; 
     private Stopwatch watch; 
     private long currentEntry; 

     #endregion 

     #region Libary importations 

     // Importation of native libraries 
     [DllImport("user32.dll", SetLastError = true)] 
     private static extern uint SendInput(uint numberOfInputs, INPUT[] inputs, int sizeOfInputStructure); 

     #endregion 

     #region Public methods 

     public PlayRecording(string inputJson, float timeFactor) 
     { 
      currentEntry = 0; 
      this.timeFactor = timeFactor; 
      stopPlayback = false; 
      watch = new Stopwatch(); 

      recManager = new RecordingManager(inputJson); 
      recManager.getDictionaries(inputJson); 
      mouseDict = recManager.mouseDict; 

      inputsToPlay = new Dictionary<long, INPUT[]>(); 
      prepareInputsToPlay(); 
     } 

     public void Start() 
     { 
      currentEntry = 0; 
      watch.Reset(); 
      watch.Start(); 
      IEnumerator<long> enumerator = inputsToPlay.Keys.GetEnumerator(); 
      while (enumerator.MoveNext()) 
      { 
       while (watch.ElapsedTicks < (enumerator.Current * timeFactor)) { } 

       if (!stopPlayback) 
        uint err = SendInput((uint)keysToPlay[enumerator.Current].Length, keysToPlay[enumerator.Current], Marshal.SizeOf(typeof(INPUT))); 

       currentEntry = enumerator.Current; 
      } 
     } 


     public bool Stop() 
     { 
      watch.Stop(); 
      return true; 
     } 

     #endregion 

     #region Private methods 

     private void prepareInputsToPlay() 
     { 
      foreach (KeyValuePair<long, Dictionary<IntPtr, Dictionary<string, int>>> kvp in mouseDict) 
      { 
       List<INPUT> inputs = new List<INPUT>(); 

       foreach (KeyValuePair<IntPtr, Dictionary<string, int>> kvp2 in kvp.Value) 
       { 
        int x = 0; 
        int y = 0; 
        foreach (KeyValuePair<string, int> kvp3 in kvp2.Value) 
        { 
         if (kvp3.Key == "X") 
          x = Convert.ToInt32(kvp3.Value); 
         if (kvp3.Key == "Y") 
          y = Convert.ToInt32(kvp3.Value); 
        } 
        inputs.Add(loadMouse(x, y, getFlags(kvp2.Key))); 
       } 
       inputsToPlay.Add(kvp.Key, inputs.ToArray()); 
      } 
     } 

     // This is where the flags are set 
     private uint getFlags(IntPtr activity) 
     { 
      string activityInt = Convert.ToString(activity); 
      switch(activityInt) 
      { 
        return 0x0002; 
       case "512": 
        return 0x0001; 
       case "513": 
        return 0x0002; 
       case "514": 
        return 0x0004; 
       case "516": 
        return 0x0008; 
       case "517": 
        return 0x0010; 
       case "522": 
        return 0x0800; 
       default: 
        return 0; 
      } 
     } 

     // This is where the input structures are being created 
     private INPUT loadMouse(int x, int y, uint flags) 
     { 
      return new INPUT 
      { 
       Type = 0, 
       Data = 
       { 
        Mouse = new MOUSEINPUT 
        { 
         X = x, 
         Y = y, 
         MouseData = 0, 
         Flags = flags, 
         Time = 0, 
         ExtraInfo = IntPtr.Zero 
        } 
       } 
      }; 
     } 

     #endregion 
    } 
} 

答えて

1

あなたはフラグMOUSEEVENTF_ABSOLUTE(0x8000番地)が含まれていない限り、マウスの座標は相対座標です。このフラグなしで絶対座標を渡すと、マウスは画面の一隅に素早く移動します

+0

左クリック、右クリックなどの他のフラグを渡している間、そのフラグをどのように渡すことができますか?また、絶対座標を使用する必要がある場合はどうしますか?私は記録し、マウス入力を正確にシミュレートしようとしているので、最初に記録されたものと一致するように座標を必要とします。 – Briscoooe

+0

使用する必要がある他のフラグとその番号だけ。 'getFlags(kvp2.Key)のようなもの| 0x8000'を入力してください.Add line –

+0

これでコードに変更を加えました。カーソルが右下ではなく左上に撃たれます。しかし、それは動き回る。これは記録された通りの動きをまねしますが、左上隅の微少な領域にしかありません。ここで起こっていることは何ですか?アプリケーションが画面サイズを約2cm x 2cmと考えているかのようです。これは、longsではなくintである座標に関連していますか? – Briscoooe