Я обнаружил, что это можно сделать, используя следующее:
[System.Windows.Forms.UserControl]::MouseButtons
который возвращает строку в настоящее время нажатых кнопок мыши. Мы опросили это и [System.Windows.Forms.Cursor]::Position
в соответствии с WorWin, чтобы отслеживать, где находится мышь и какие кнопки нажаты.
Отслеживание того, где мышь находится внутри окна консоли, немного сложнее. Я лично использую для этого специальный класс.
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
дает нам внешние границы окна консоли, так что, если мы хотим, чтобы выяснить, какие buffercell курсор находится в мы собираемся чтобы сделать некоторые работы на наших границах.
$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"
, чтобы проверять, когда щелкнуто также окно консоли.
Почему некоторые люди отказались от этого сообщения? Разве это не правильный вопрос? – Fentoyal
Привет, * Хороший вопрос * на SO содержит хотя бы немного кода для начала, что * может * быть причиной для downvote. – sodawillow
К сожалению, у меня пока нет кода, потому что, как и мой вопрос, я даже не знаю, возможно ли это или нет. Я рассмотрел объект $ host, но, похоже, у него нет обработчика событий. И когда я ищу в Интернете, большинство результатов касательно «Отправка события» вместо «Прослушивание события». Поэтому я пришел сюда, чтобы получить помощь. – Fentoyal