如何在f#中模拟鼠标点击和按键

时间:2022-11-03 18:20:41

I'm doing a program that's supposed to move the mouse around and press automatically at places where I specify in the code. Right now i've managed to move the cursor by using this line: Cursor.Position <- System.Drawing.Point(x,y)

我正在做一个程序,它应该移动鼠标并在我在代码中指定的地方自动按下。现在我已经通过使用这一行:游标来移动游标。< - System.Drawing.Point位置(x,y)

What I haven't found out yet is how to simulate mouseclicks or keypresses. The only thing I found about this is the SendKeys Class from MSDN (http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx). I tried to simulate a keypress with this class, but I get a run-time error message.

我还没有发现如何模拟鼠标点击或按键。关于这一点,我唯一找到的是来自MSDN的SendKeys类(http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx)。我尝试用这个类来模拟一个按键,但是我得到了一个运行时错误消息。

The line I use is: SendKeys.Send("{ENTER}")

我使用的行是:sendkey . send(“{ENTER}”)

The error message I get: "SendKeys cannot run inside this application because the application is not handling Windows messages. Either change the application to handle messages, or use the SendKeys.SendWait method."

我得到的错误消息是:“SendKeys不能在这个应用程序中运行,因为应用程序没有处理Windows消息。要么更改应用程序以处理消息,要么使用SendKeys。SendWait方法。”

So I replaced it with the SendWait method, but it still doesn't seem to send the keypress. How do I do this? What I really want the finished program to be able to do, is sending keys and mouse clicks to another program that is already open in the background. For example, painting an image in Paint automatically.

所以我用SendWait方法替换了它,但它似乎仍然没有发送按键。我该怎么做呢?我真正想要完成的程序能够做的是,向后台已经打开的另一个程序发送按键和鼠标点击。例如,自动在绘图中绘制图像。

3 个解决方案

#1


3  

If you want to avoid Win32 native interop, Windows Input Simulator is a promising looking managed wrapper around SendInput. But the latest release doesn't support mouse simulation. However, the active trunk has a patch for supporting mouse simulation (see this discussion). The project is using VS2010 C#, and you can export and build yourself from the subversion repository here.

如果您想避免Win32本机互操作,Windows输入模拟器是一种看起来很有前途的SendInput托管包装。但是最新的版本并不支持鼠标模拟。但是,活动主干有一个支持鼠标模拟的补丁(请参见本讨论)。项目正在使用VS2010 c#,您可以从这里的subversion存储库导出并构建自己。

If you are interested in Win32 native interop, I put together a demonstration of how to use the SendInput API with F#. This application simulates a right click.

如果您对Win32 native interop感兴趣,我将演示如何在f#中使用SendInput API。此应用程序模拟右击。

open System
open System.Runtime.InteropServices

type MOUSEINPUT = struct
    val dx:int
    val dy:int
    val mouseData:int
    val dwFlags:int
    val time:int
    val dwExtraInfo:int
    new(_dx, _dy, _mouseData, _dwFlags, _time, _dwExtraInfo) = {dx=_dx; dy=_dy; mouseData=_mouseData; dwFlags=_dwFlags; time=_time; dwExtraInfo=_dwExtraInfo}
end

type INPUT = struct
    //need to escape traditional INPUT identifier here since "type" is a reserved word
    //though could use any other identifier name if so desired
    val ``type``:int //0 is mouse
    val mi:MOUSEINPUT
    new(_type, _mi) = {``type``=_type; mi=_mi}
end

let MOUSEEVENTF_RIGHTDOWN = 0x0008
let MOUSEEVENTF_RIGHTUP = 0x0010

[<DllImport("user32.dll", SetLastError=true)>]
extern uint32 SendInput(uint32 nInputs, INPUT* pInputs, int cbSize)

let mutable inputRightDown = INPUT(0, MOUSEINPUT(0, 0, 0, MOUSEEVENTF_RIGHTDOWN, 0, 0))
let mutable inputRightUp = INPUT(0, MOUSEINPUT(0, 0, 0, MOUSEEVENTF_RIGHTUP, 0, 0))

SendInput(uint32 1, &&inputRightDown, Marshal.SizeOf(inputRightDown))
SendInput(uint32 1, &&inputRightUp, Marshal.SizeOf(inputRightUp))

On second reading of your question, I see that ultimately you want to send simulated mouse and keyboard events to an application running in the background, in which case SendMessage / PostMessage may be more appropriate APIs. This will still require native interop, and hopefully my example using SendInput will help. Here is a related question.

在第二次阅读您的问题时,我看到您最终希望向运行在后台的应用程序发送模拟鼠标和键盘事件,在这种情况下,SendMessage / PostMessage可能是更合适的api。这仍然需要本机互操作,希望我使用SendInput的示例能有所帮助。这是一个相关的问题。

#2


2  

You're looking for the SendInput Win32 API call.

您正在寻找SendInput Win32 API调用。

#3


0  

open System.Runtime.InteropServices

module InteropWithNative = 
    [<DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)>]
    extern void mouse_event(System.Int64, System.Int64, System.Int64, System.Int64, System.Int64)

    let MOUSEEVENTF_LEFTDOWN    = 0x02L
    let MOUSEEVENTF_LEFTUP      = 0x04L
    let MOUSEEVENTF_RIGHTDOWN   = 0x08L
    let MOUSEEVENTF_RIGHTUP     = 0x10L

    let  MouseLeftClick () = 
        mouse_event(MOUSEEVENTF_LEFTDOWN, 0L, 0L, 0L, 0L)
        mouse_event(MOUSEEVENTF_LEFTUP, 0L, 0L, 0L, 0L)

Then to use:

然后使用:

    InteropWithNative.MouseLeftClick ()

#1


3  

If you want to avoid Win32 native interop, Windows Input Simulator is a promising looking managed wrapper around SendInput. But the latest release doesn't support mouse simulation. However, the active trunk has a patch for supporting mouse simulation (see this discussion). The project is using VS2010 C#, and you can export and build yourself from the subversion repository here.

如果您想避免Win32本机互操作,Windows输入模拟器是一种看起来很有前途的SendInput托管包装。但是最新的版本并不支持鼠标模拟。但是,活动主干有一个支持鼠标模拟的补丁(请参见本讨论)。项目正在使用VS2010 c#,您可以从这里的subversion存储库导出并构建自己。

If you are interested in Win32 native interop, I put together a demonstration of how to use the SendInput API with F#. This application simulates a right click.

如果您对Win32 native interop感兴趣,我将演示如何在f#中使用SendInput API。此应用程序模拟右击。

open System
open System.Runtime.InteropServices

type MOUSEINPUT = struct
    val dx:int
    val dy:int
    val mouseData:int
    val dwFlags:int
    val time:int
    val dwExtraInfo:int
    new(_dx, _dy, _mouseData, _dwFlags, _time, _dwExtraInfo) = {dx=_dx; dy=_dy; mouseData=_mouseData; dwFlags=_dwFlags; time=_time; dwExtraInfo=_dwExtraInfo}
end

type INPUT = struct
    //need to escape traditional INPUT identifier here since "type" is a reserved word
    //though could use any other identifier name if so desired
    val ``type``:int //0 is mouse
    val mi:MOUSEINPUT
    new(_type, _mi) = {``type``=_type; mi=_mi}
end

let MOUSEEVENTF_RIGHTDOWN = 0x0008
let MOUSEEVENTF_RIGHTUP = 0x0010

[<DllImport("user32.dll", SetLastError=true)>]
extern uint32 SendInput(uint32 nInputs, INPUT* pInputs, int cbSize)

let mutable inputRightDown = INPUT(0, MOUSEINPUT(0, 0, 0, MOUSEEVENTF_RIGHTDOWN, 0, 0))
let mutable inputRightUp = INPUT(0, MOUSEINPUT(0, 0, 0, MOUSEEVENTF_RIGHTUP, 0, 0))

SendInput(uint32 1, &&inputRightDown, Marshal.SizeOf(inputRightDown))
SendInput(uint32 1, &&inputRightUp, Marshal.SizeOf(inputRightUp))

On second reading of your question, I see that ultimately you want to send simulated mouse and keyboard events to an application running in the background, in which case SendMessage / PostMessage may be more appropriate APIs. This will still require native interop, and hopefully my example using SendInput will help. Here is a related question.

在第二次阅读您的问题时,我看到您最终希望向运行在后台的应用程序发送模拟鼠标和键盘事件,在这种情况下,SendMessage / PostMessage可能是更合适的api。这仍然需要本机互操作,希望我使用SendInput的示例能有所帮助。这是一个相关的问题。

#2


2  

You're looking for the SendInput Win32 API call.

您正在寻找SendInput Win32 API调用。

#3


0  

open System.Runtime.InteropServices

module InteropWithNative = 
    [<DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)>]
    extern void mouse_event(System.Int64, System.Int64, System.Int64, System.Int64, System.Int64)

    let MOUSEEVENTF_LEFTDOWN    = 0x02L
    let MOUSEEVENTF_LEFTUP      = 0x04L
    let MOUSEEVENTF_RIGHTDOWN   = 0x08L
    let MOUSEEVENTF_RIGHTUP     = 0x10L

    let  MouseLeftClick () = 
        mouse_event(MOUSEEVENTF_LEFTDOWN, 0L, 0L, 0L, 0L)
        mouse_event(MOUSEEVENTF_LEFTUP, 0L, 0L, 0L, 0L)

Then to use:

然后使用:

    InteropWithNative.MouseLeftClick ()