Получить заголовок окна с помощью курсора мыши в Powershell/wasp?

Я создал скрипт powershell (используя wasp), который устанавливает любое окно в режим "всегда сверху".

Я запускаю скрипт через:

Get-WindowByTitle *emul* | Set-TopMost

  • Зачем мне это нужно?*

Когда я программирую в Eclipse/Androidstudio - Я хочу, чтобы эмулятор был всегда впереди. поэтому скрипт ищет все окна с заголовком emul (который является частью фактического названия, которое"emulator.exe") и устанавливает его всегда сверху.

Хорошо.

Но сейчас я хочу сделать это для каждого окна, не меняя сценарий.

Как я выберу окно? с помощью курсора мыши (только при наведении курсора). (Когда я наведу указатель мыши на calc.exe и нажму некоторую последовательность клавиш, которая активирует скрипт PS, он будет искать, в каком окне находится курсор)

Вопрос

Как я могу выбрать title окна, на котором есть курсор мыши? (окно не должно быть активным)

Пример:

смотря на:

я хочу получить MyChromeBrowserTitle хотя это на заднем плане, (и блокнот спереди). он должен вернуть заголовок Chrome, потому что курсор находится в окне Chrome.

1 ответ

Решение

Следующее может быть не лучшим способом сделать это, и оно не будет работать для окон Explorer, так как Explorer работает на рабочем столе + некоторые специфические окна проводника папок. Однако это работает для остальных.

Add-Type -TypeDefinition @"
using System; 
using System.Runtime.InteropServices;
public class Utils
{ 
    public struct RECT
    {
        public int Left;        
        public int Top;         
        public int Right;       
        public int Bottom;     
    }

    [DllImport("user32.dll")]
    public static extern bool GetWindowRect(
        HandleRef hWnd,
        out RECT lpRect);
}
"@

Add-Type -AssemblyName System.Windows.Forms
$p = [Windows.Forms.Cursor]::Position
Get-Process | %{ 
    if ($_.MainWindowHandle)
    {
        $o = New-Object -TypeName System.Object            
        $href = New-Object -TypeName System.RunTime.InteropServices.HandleRef -ArgumentList $o, $_.MainWindowHandle            

        $rect = New-Object utils+RECT            
        [Void][Utils]::GetWindowRect($href, [ref]$rect)

        if ($p.X -ge $rect.Left -and $p.X -le $rect.Right -and 
            $p.Y -ge $rect.Top -and $p.Y -le $rect.Bottom
           )
        {
            $_.MainWindowTitle
        }
    }
}

РЕДАКТИРОВАТЬ

Поскольку я использую Powershell V3, приведенный выше код работает для меня.

Я пробовал настройку Set-StrictMode -Version 2 так что мы работаем с той же версией. Следующее работает для меня в V2:

$def = @'
public struct RECT
{
    public int Left;
    public int Top;  
    public int Right;
    public int Bottom; 
}

[DllImport("user32.dll")]
public static extern bool GetWindowRect(
    HandleRef hWnd,
    out RECT lpRect);

'@

Add-Type -MemberDefinition $def -Namespace Utils -Name Utils 

Add-Type -AssemblyName System.Windows.Forms
$p = [Windows.Forms.Cursor]::Position
Get-Process | %{ 
    if ($_.MainWindowHandle)
    {
        $o = New-Object -TypeName System.Object            
        $href = New-Object -TypeName System.RunTime.InteropServices.HandleRef -ArgumentList $o, $_.MainWindowHandle            

        $rect = New-Object Utils.Utils+RECT            
        [Void][Utils.Utils]::GetWindowRect($href, [ref]$rect)

        if ($p.X -ge $rect.Left -and $p.X -le $rect.Right -and 
            $p.Y -ge $rect.Top -and $p.Y -le $rect.Bottom
           )
        {
            $_.MainWindowTitle
        }
    }
}
Другие вопросы по тегам