Royi Namir
Royi Namir

Reputation: 148744

Get window title via mouse cursor in Powershell/wasp?

I have built a powershell script ( using wasp) which sets any window to "always on top" mode .

I run the script via :

Get-WindowByTitle *emul* | Set-TopMost

When I program in Eclipse/Androidstudio - I want the emulator to be always in front. so the script is looking for all windows which has title like emul (which is part of the actual title which is "emulator.exe") and sets it to always on top.

Okay.

But now I want to do it for every window without changing the script.

How will I chose the window ? by mouse cursor (hover only). (When I put the mouse over calc.exe , and press some sequence of keys - which will activate the PS script - it will search which window has the cursor at)

Question

How can I select the title of a window which has the mouse cursor on it ? (the window doesn't have to be active)

Example :

looking at :

enter image description here

I want to get MyChromeBrowserTitle although it is in the background , ( and notepad is in front). it should return chrome's title because the cursor is at the chrome window.

Upvotes: 0

Views: 1246

Answers (1)

Micky Balladelli
Micky Balladelli

Reputation: 10011

The following might not be the best way of doing this, and it won't work for the Explorer windows as Explorer is running the desktop + some specific folder explorer windows. However it works for the rest.

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
        }
    }
}

EDIT

As I'm running Powershell V3, the code above worked for me.

I tried setting Set-StrictMode -Version 2 so we're running the same version. The following works for me in 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
        }
    }
}

Upvotes: 2

Related Questions