2014-10-10 117 views
2

我一直在嘗試和尋找整天,不能爲我的生活弄清楚如何做到這一點。發送由GetAsyncKeyState()忽略的虛擬鼠標點擊?

隨着標題的讀取,我希望能夠發送被GetAsyncKeyState()等東西忽略的鼠標點擊。

基本上我在做什麼:

//While physically holding left mouse button... 
while (GetAsyncKeyState(0x01) != 0) 
{ 
    //left mouse button virtually down (obviously already is down the first loop) 
    mouse_event(2, 0, 0, 0, 0); 

    Thread.Sleep(100); 

    //left mouse button virtually up 
    mouse_event(4, 0, 0, 0, 0); 
} 

現在,while循環停止,因爲我幾乎解除按鈕,所以我要問的是mouse_event/GetAsyncKeyState(或某些參數的替代方法我不知道),所以我可以在不影響實際狀態的情況下操縱關鍵狀態。

舉例來說,我已經能夠使用發送{LButton起來}函數GetKeyState爲此在AutoHotkey的( 「LButton」, 「P」)

任何想法?

+0

順便說一句,你想這樣做,爲什麼! ! – Orace 2014-10-10 14:55:40

+0

嗯,我正在做一個自動答題器,需要奇怪的時間,我真的希望它點擊我身體上按下的鍵。這主要是出於實驗原因。你的回答確實讓我朝着正確的方向發展,非常感謝! :) – Jobot 2014-10-10 18:19:40

+0

不客氣。 – Orace 2014-10-13 08:25:04

回答

1

MSLLHOOKSTRUCT包含LLMHF_INJECTEDLLMHF_LOWER_IL_INJECTED標誌。也許你應該看看它。

下面的代碼只是一個帶有定時器的空表單,配置爲「開」,每秒鐘調用「TimerOnTick」。

當你點擊時,輸出爲 「497,361,0」 當定時器點擊輸出爲 「497,361,1」

using System; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using System.Threading; 
using System.Windows.Forms; 

namespace Syracuse 
{ 
    public partial class Form1 : Form 
    { 
     private const int WH_MOUSE_LL = 14; 
     private static LowLevelMouseProc _proc = HookCallback; 
     private static IntPtr _hookID = IntPtr.Zero; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     protected override void OnLoad(EventArgs e) 
     { 
      base.OnLoad(e); 
      _hookID = SetHook(_proc); 
     } 

     protected override void OnClosed(EventArgs e) 
     { 
      base.OnClosed(e); 
      UnhookWindowsHookEx(_hookID); 
     } 

     private void TimerOnTick(object sender, EventArgs e) 
     { 
      //left mouse button virtually down (obviously already is down the first loop) 
      mouse_event(2, 0, 0, 0, UIntPtr.Zero); 

      Thread.Sleep(100); 

      //left mouse button virtually up 
      mouse_event(4, 0, 0, 0, UIntPtr.Zero); 
     } 


     private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
     { 
      if (nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages) wParam) 
      { 
       var hookStruct = (MSLLHOOKSTRUCT) Marshal.PtrToStructure(lParam, typeof (MSLLHOOKSTRUCT)); 
       Console.WriteLine(hookStruct.pt.x + ", " + hookStruct.pt.y + ", " + hookStruct.flags); 
      } 

      // Todo create OnMouseUpExEvent, OnMouseDownExEvent witch provide MSLLHOOKSTRUCT informations. 

      return CallNextHookEx(_hookID, nCode, wParam, lParam); 
     } 

     private static IntPtr SetHook(LowLevelMouseProc proc) 
     { 
      using (var curProcess = Process.GetCurrentProcess()) 
      using (var curModule = curProcess.MainModule) 
      { 
       return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0); 
      } 
     } 

     private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam); 

     #region Enum & Struct 
     private enum MouseMessages 
     { 
      WM_LBUTTONDOWN = 0x0201, 
      WM_LBUTTONUP = 0x0202, 
      WM_MOUSEMOVE = 0x0200, 
      WM_MOUSEWHEEL = 0x020A, 
      WM_RBUTTONDOWN = 0x0204, 
      WM_RBUTTONUP = 0x0205 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     private struct MSLLHOOKSTRUCT 
     { 
      public POINT pt; 
      public uint mouseData; 
      public uint flags; 
      public uint time; 
      public IntPtr dwExtraInfo; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     private struct POINT 
     { 
      public int x; 
      public int y; 
     } 
     #endregion 

     #region Extern 
     [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 
     public static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint cButtons, UIntPtr dwExtraInfo); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); 

     [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr GetModuleHandle(string lpModuleName); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     [return: MarshalAs(UnmanagedType.Bool)] 
     private static extern bool UnhookWindowsHookEx(IntPtr hhk); 
     #endregion 
    } 
}