2011-11-05 10 views
22

İmleç hareket etmedikçe SendInput, fare düğmesini tıklatmaz.SendInput, imleci hareket ettirmedikçe fare düğmesini tıklatmıyor

Bu konuda bir yardım için minnettarım.

Sol fare tıklaması taklit etmek için SendInput kullandığım ön plan penceresinde fare tıklaması gerçekleştiren bir programım var. Sorun şu ki, imleci tıklatarak SendInput konumuna tıklarsanız tıklamayı yapamazsınız, ancak imleci hareket ettirmektense imleci hareket ettirmeme rağmen x ve y noktalarını MouseInputData'ya geçiriyorum. Ben imleci hiç hareket ettirmek gerek kalmadan sol fare tıklaması yapmak istiyorum. Böyle imleç konumunu elde kaldırmak eğer

Körük Ben sınıftır (oldukça basit ve ileri stright)

namespace StackSolution.Classes 
{ 
    public static class SendInputClass 
    { 

     [DllImport("user32.dll", SetLastError = true)] 
     static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize); 

     [DllImport("user32.dll")] 
     static extern bool SetCursorPos(int X, int Y); 

     [DllImport("user32.dll")] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     static extern bool GetCursorPos(out Point lpPoint); 



     [StructLayout(LayoutKind.Sequential)] 
     struct INPUT 
     { 
      public SendInputEventType type; 
      public MouseKeybdhardwareInputUnion mkhi; 
     } 
     [StructLayout(LayoutKind.Explicit)] 
     struct MouseKeybdhardwareInputUnion 
     { 
      [FieldOffset(0)] 
      public MouseInputData mi; 

      [FieldOffset(0)] 
      public KEYBDINPUT ki; 

      [FieldOffset(0)] 
      public HARDWAREINPUT hi; 
     } 
     [StructLayout(LayoutKind.Sequential)] 
     struct KEYBDINPUT 
     { 
      public ushort wVk; 
      public ushort wScan; 
      public uint dwFlags; 
      public uint time; 
      public IntPtr dwExtraInfo; 
     } 
     [StructLayout(LayoutKind.Sequential)] 
     struct HARDWAREINPUT 
     {   
      public int uMsg; 
      public short wParamL; 
      public short wParamH; 
     } 
     struct MouseInputData 
     { 
      public int dx; 
      public int dy; 
      public uint mouseData; 
      public MouseEventFlags dwFlags; 
      public uint time; 
      public IntPtr dwExtraInfo; 
     } 
     [Flags] 
     enum MouseEventFlags : uint 
     { 
      MOUSEEVENTF_MOVE = 0x0001, 
      MOUSEEVENTF_LEFTDOWN = 0x0002, 
      MOUSEEVENTF_LEFTUP = 0x0004, 
      MOUSEEVENTF_RIGHTDOWN = 0x0008, 
      MOUSEEVENTF_RIGHTUP = 0x0010, 
      MOUSEEVENTF_MIDDLEDOWN = 0x0020, 
      MOUSEEVENTF_MIDDLEUP = 0x0040, 
      MOUSEEVENTF_XDOWN = 0x0080, 
      MOUSEEVENTF_XUP = 0x0100, 
      MOUSEEVENTF_WHEEL = 0x0800, 
      MOUSEEVENTF_VIRTUALDESK = 0x4000, 
      MOUSEEVENTF_ABSOLUTE = 0x8000 
     } 
     enum SendInputEventType : int 
     { 
      InputMouse, 
      InputKeyboard, 
      InputHardware 
     } 

     public static void ClickLeftMouseButton(int x, int y) 
     { 
      INPUT mouseInput = new INPUT(); 
      mouseInput.type = SendInputEventType.InputMouse; 
      mouseInput.mkhi.mi.dx = x; 
      mouseInput.mkhi.mi.dy = y; 
      mouseInput.mkhi.mi.mouseData = 0; 

      //getting current cursor location 
      Point p; 
      if (GetCursorPos(out p)) 
       SetCursorPos(x, y); 


      mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN; 
      SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); 

      mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP; 
      SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); 

      //returning cursor to previous position 
      SetCursorPos(p.X, p.Y); 
     }  
    } 
    } 

aynı ClickLeftMouseButton işlevi tıklamayacaktır.

public static void ClickLeftMouseButton(int x, int y) 
     { 
      INPUT mouseInput = new INPUT(); 
      mouseInput.type = SendInputEventType.InputMouse; 
      mouseInput.mkhi.mi.dx = x; 
      mouseInput.mkhi.mi.dy = y; 
      mouseInput.mkhi.mi.mouseData = 0;      


      mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN; 
      SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); 

      mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP; 
      SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT()));    
     } 

Şimdiden teşekkür ederiz.

+0

X ve y koordinatlarını nereden aldığınızı ve tam olarak ne anlama geldiğini net olarak belirtin. Eksik MOUSEEVENTF_ABSOLUTE bayrağı bir problem gibi görünüyor. –

cevap

24

SendInput işlevini kullanırken göz önünde bulundurmanız gereken birkaç şey vardır. Eğer MOUSEEVENTF_ABSOLUTE bayrağı belirtmezseniz

sonra dx ve dy (MouseInputData yapısı) geçerli fare konumuna göre koordinatlar.

enum SystemMetric 
{ 
    SM_CXSCREEN = 0, 
    SM_CYSCREEN = 1, 
} 

[DllImport("user32.dll")] 
static extern int GetSystemMetrics(SystemMetric smIndex); 

int CalculateAbsoluteCoordinateX(int x) 
{ 
    return (x * 65536)/GetSystemMetrics(SystemMetric.SM_CXSCREEN); 
} 

int CalculateAbsoluteCoordinateY(int y) 
{ 
    return (y * 65536)/GetSystemMetrics(SystemMetric.SM_CYSCREEN); 
} 

göndermek Dahası önce: Belirttiğiniz yaparsanız MOUSEEVENTF_ABSOLUTE sonra dx ve dy 0 ile 65535 senin x ve y koordinatları Yani ekranı dx ve dy hesaplamak için aşağıdaki işlevi kullanmalısınız koordinatları arasındaki mutlak koordinatlar SendInput aracılığıyla mouseDown ve mouseUp olayları size tıklayarak istediğiniz denetime fareyi gerekir:

public static void ClickLeftMouseButton(int x, int y) 
{ 
    INPUT mouseInput = new INPUT(); 
    mouseInput.type = SendInputEventType.InputMouse; 
    mouseInput.mkhi.mi.dx = CalculateAbsoluteCoordinateX(x); 
    mouseInput.mkhi.mi.dy = CalculateAbsoluteCoordinateY(y); 
    mouseInput.mkhi.mi.mouseData = 0;      


    mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_MOVE |MouseEventFlags.MOUSEEVENTF_ABSOLUTE; 
    SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); 

    mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN; 
    SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT())); 

    mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP; 
    SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT()));    
} 

yukarıdaki kod varsayar x veo, ekran piksel koordinatlarıdır. Sen şu kodu kullanarak bir winform bir düğme (hedef) için olanlar koordinatları hesaplayabilirsiniz:

Point screenCoordsCentre= 
button1.PointToScreen(new Point(button1.Width/2, button1.Height/2)); 

Umut, bu yardımcı olur.

+2

Yardım için çok teşekkürler, aslında merak ettiğim birkaç şeyi açıklıyor. – Dmitris

+1

Teşekkürler. Ama fareyi o koordine taşımadan nasıl yapılacağını biliyor musun? (Çift fare oluşturmak istiyorum). – Jet

+0

İlk önce imleç konumunu hareket ettirmeden fare tıklatmayı nasıl simüle edebilirim? soruda belirtildiği gibi. – tcboy88