2017-02-09 2 views
0

Я пытаюсь сделать какой-то трюк с Powershell. Я хочу написать сценарий, и этот скрипт может прослушивать события мыши (щелчок, перемещение и т. Д.) Внутри консоли powershell.Powershell - захват события щелчка мыши внутри консоли powershell

Например, когда мой скрипт активен, когда я нажимаю кнопку мыши внутри консоли powershell, консоль может выводить позицию моего курсора.

Возможно ли это? Если возможно, как?

Заранее спасибо.

+0

Почему некоторые люди отказались от этого сообщения? Разве это не правильный вопрос? – Fentoyal

+0

Привет, * Хороший вопрос * на SO содержит хотя бы немного кода для начала, что * может * быть причиной для downvote. – sodawillow

+0

К сожалению, у меня пока нет кода, потому что, как и мой вопрос, я даже не знаю, возможно ли это или нет. Я рассмотрел объект $ host, но, похоже, у него нет обработчика событий. И когда я ищу в Интернете, большинство результатов касательно «Отправка события» вместо «Прослушивание события». Поэтому я пришел сюда, чтобы получить помощь. – Fentoyal

ответ

0

Не знаете, как все это будет собираться вместе. Возможно, это поможет.

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

Спасибо за ответ. Однако это не может зафиксировать событие click. Я хочу, чтобы у PS было что-то вроде ReadKey для мыши, например ReadClick – Fentoyal

0

Я обнаружил, что это можно сделать, используя следующее:

[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", чтобы проверять, когда щелкнуто также окно консоли.

+0

Спасибо за подробный ответ! У меня пока нет возможности проверить ваше решение, но я очень ценю ваше подробное объяснение! – Fentoyal

Смежные вопросы