簡體   English   中英

Powershell - 在 powershell 控制台中捕獲鼠標單擊事件

[英]Powershell - capture mouse click event inside a powershell console

我正在嘗試使用 Powershell 做一些技巧。 我想編寫一個腳本,該腳本可以偵聽 powershell 控制台內的鼠標事件(單擊、移動等)。

例如,當我的腳本處於活動狀態時,當我在 powershell 控制台內單擊鼠標時,控制台可以輸出我的光標位置。

是否可以? 如果可以,怎么做?

提前致謝。

我發現可以使用以下方法來做到這一點:

[System.Windows.Forms.UserControl]::MouseButtons

它返回當前按下的鼠標按鈕的字符串。 我們根據 WorWin 輪詢此和[System.Windows.Forms.Cursor]::Position以跟蹤鼠標的位置和按下的按鈕。

但是,跟蹤鼠標在控制台窗口內的位置有點棘手。 我個人為此使用自定義類。

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);
    }
}
"@

要獲取 Powershell 控制台窗口:

$ourID = (get-process -id (Get-WmiObject -class win32_process -Filter ("ProcessID = $pid")).parentprocessid).mainwindowhandle;
$win = New-Object Window($ourID);

現在, $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]::MouseButtons -match "Left"來僅檢查何時單擊控制台窗口。

不確定所有這些將如何拼湊在一起。 也許這會有所幫助。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM