0

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

  • Why do I need it ?*

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.

Royi Namir
  • 144,742
  • 138
  • 468
  • 792

1 Answers1

2

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
        }
    }
}
Micky Balladelli
  • 9,781
  • 2
  • 33
  • 31
  • Interesting indeed, works well here with ISE or other Powershell editors. Which version of Powershell are you using? – Micky Balladelli Jan 08 '15 at 13:23
  • Updated answer for Powershell V2. – Micky Balladelli Jan 08 '15 at 13:36
  • If that doesn't work for you, then I believe the problem is elsewhere, and I'd recommend trying it on a different system. – Micky Balladelli Jan 08 '15 at 13:38
  • **Working !** http://i.imgur.com/OFc6kR8.png .Thank you _so_ much. ps can you please elaborate on the "explorer" problem ( not that i need it on the explorer.exe but just for general knowledge - why it wouldnt work?) ? – Royi Namir Jan 08 '15 at 13:44
  • Basically Explorer is the Start menu, it's the desktop, and it's the explorer windows we use to browse folders. So the Main Window handle for the explorer window points to the window running the desktop. All of that is under one process. So in order to fix that, we'd need to take a different approach and browse all top level windows instead of all the processes. – Micky Balladelli Jan 08 '15 at 13:49