Powershell-捕获Powershell控制台内的鼠标单击事件

Powershell-捕获Powershell控制台内的鼠标单击事件,powershell,Powershell,我想用Powershell玩些把戏。我想编写一个脚本,该脚本可以在powershell控制台中侦听鼠标事件(单击、移动等) 例如,当我的脚本处于活动状态时,当我在powershell控制台内单击鼠标时,控制台可以输出光标的位置 可能吗?如果可能,怎么做 提前谢谢。我不知道所有这些将如何组合在一起。 也许这会有帮助 <# Gets the Mouse Position #> [System.Windows.Forms.Cursor]::Position [System.Window

我想用Powershell玩些把戏。我想编写一个脚本,该脚本可以在powershell控制台中侦听鼠标事件(单击、移动等)

例如,当我的脚本处于活动状态时,当我在powershell控制台内单击鼠标时,控制台可以输出光标的位置

可能吗?如果可能,怎么做


提前谢谢。

我不知道所有这些将如何组合在一起。 也许这会有帮助

<# Gets the Mouse Position #>
[System.Windows.Forms.Cursor]::Position

[System.Windows.Forms.Cursor]::位置

我发现使用以下方法可以做到这一点:

[System.Windows.Forms.UserControl]::MouseButtons
返回当前按下的鼠标按钮的字符串。我们根据WorWin轮询此和
[System.Windows.Forms.Cursor]::定位
,以跟踪鼠标的位置和按下的按钮

不过,跟踪鼠标在控制台窗口中的位置有点棘手。我个人为此使用自定义类

Add-Type -ReferencedAssemblies System.Drawing @"
using System;
using System.Drawing;
using System.Runtime.InteropServices;
public class Window 
{
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();

    public RECT bounds;
    public bool isForeground;
    private IntPtr hWnd;
    public int Width;
    public int Height;

    public Window(IntPtr handle)
    {
        hWnd = handle;
        Update();
    }
    public void Update()
    {
        if(GetWindowRect(hWnd, out bounds))
        {
            Width = bounds.Right - bounds.Left;
            Height = bounds.Bottom - bounds.Top;

            if(GetForegroundWindow() == hWnd){isForeground = true;}
            else{isForeground = false;}
        }
    }
    public bool Contains(Point pt)
    {
        return bounds.Contains(pt);
    }
}
public struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;

    public Boolean Contains(Point pt)
    {
        if( (pt.X >= Left) && (pt.X < Right) && (pt.Y >= Top) && (pt.Y < Bottom) ){ return true;}
        return false;
    }
}
public struct POINT
{
    public int X;
    public int Y;
    public static implicit operator Point(POINT point)
    {
        return new Point(point.X, point.Y);
    }
}
"@
现在,
$win.bounds
为我们提供了控制台窗口的外部边界,因此如果我们想找到光标所在的缓冲区,我们必须对边界做一些工作

$innerOffsets = new-object RECT;
$innerOffsets.Top = [Windows.Forms.SystemInformation]::CaptionHeight + [Windows.Forms.SystemInformation]::HorizontalResizeBorderThickness + [Windows.Forms.SystemInformation]::Border3DSize.Height;
$innerOffsets.Bottom = -([Windows.Forms.SystemInformation]::HorizontalResizeBorderThickness + [Windows.Forms.SystemInformation]::Border3DSize.Height);    
$inneroffsets.Left = [Windows.Forms.SystemInformation]::VerticalResizeBorderThickness + [Windows.Forms.SystemInformation]::Border3DSize.Width;
$inneroffsets.Right = -([Windows.Forms.SystemInformation]::VerticalResizeBorderThickness + [Windows.Forms.SystemInformation]::Border3DSize.Width);

if([console]::bufferheight -gt [console]::windowheight)
{
    $inneroffsets.right -= [Windows.Forms.SystemInformation]::HorizontalScrollBarThumbWidth;
}
if([console]::bufferwidth -gt [console]::windowwidth)
{
    $inneroffsets.bottom -= [Windows.Forms.SystemInformation]::VerticalScrollBarThumbHeight;
}
这为我们提供了获得窗口内边界所需的偏移量。从这里我们可以得到窗口上的相对位置

$mp = [Windows.Forms.Cursor]::Position;
$mp.x -= ($win.bounds.left + $inneroffsets.left);
$mp.y -= ($win.bounds.top + $inneroffsets.top);
现在我们可以将鼠标位置转换为缓冲单元格位置

$innerWidth = ($win.bounds.right + $inneroffsets.right) - ($win.bounds.left + $inneroffsets.left);
$innerheight = ($win.bounds.bottom + $inneroffsets.bottom) - ($win.bounds.top + $inneroffsets.top);
$mp.x = [Math]::Floor($mp.x / ( $innerwidth / [console]::windowWidth));
$mp.y = [Math]::Floor($mp.y / ( $innerheight / [console]::windowheight));

每次检查时都必须使用
$win.update()
。您还可以使用
$win.isforeground
[Windows.Forms.UserControl]::鼠标按钮-匹配“Left”
仅在单击控制台窗口时进行检查。

为什么有些人对此帖子投了否决票?这不是一个正确的问题吗?嗨,一个关于SO的好问题至少包含一点代码,这可能是一个否决投票的原因。对不起,我还没有任何代码,因为,就像我的问题所说的,我甚至不知道这是否可能。我检查了$host对象,但它似乎没有事件处理程序。当我在网上搜索时,大多数结果都是关于“发送事件”而不是“收听事件”。所以我来这里寻求帮助。谢谢你的回答。但是,这无法捕获单击事件。我希望PS有像ReadKey for mouse这样的东西,比如ReadClickThank谢谢你的详细回答!我还没有机会测试你的解决方案,但我真的很感谢你详细的解释!
$innerWidth = ($win.bounds.right + $inneroffsets.right) - ($win.bounds.left + $inneroffsets.left);
$innerheight = ($win.bounds.bottom + $inneroffsets.bottom) - ($win.bounds.top + $inneroffsets.top);
$mp.x = [Math]::Floor($mp.x / ( $innerwidth / [console]::windowWidth));
$mp.y = [Math]::Floor($mp.y / ( $innerheight / [console]::windowheight));