I'm trying to make a powershell windows form all transparent as i was able to get the aero style controls working and hiding the powershell console window this is the only thing missing.
The tutorial I was trying to implement in powershell is this:
http://blogs.msdn.com/b/tims/archive/2006/04/18/578637.aspx but its in C#, help?
You could use the C# sample itself, by compiling/loading it in PowerShell. Sample (untested):
$def = #"
[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
public int left;
public int right;
public int top;
public int bottom;
}
[DllImport("dwmapi.dll")]
public static extern bool DwmIsCompositionEnabled();
[DllImport("dwmapi.dll")]
public static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);
"#
#Load/Compile C# P/Invoke code
Add-Type -Namespace stackoverflow -Name Aero -MemberDefinition $def
#Check if Aero is enabled on this computer
If([stackoverflow.Aero]::DwmIsCompositionEnabled()) {
#Get mainwindowhandle for powershell console process
$hwnd = (Get-Process -Id $pid).MainWindowHandle
#Define margins = how much extra space to make transparent
$margins = New-Object -TypeName 'stackoverflow.Aero+MARGINS'
$margins.top = 50
$margins.bottom = 0
$margins.left = 0
$margins.right = 0
#Make powershell-console partly aero.
[stackoverflow.Aero]::DwmExtendFrameIntoClientArea($hwnd, $margins)
}
Related
I'm trying to hide Internet Explorer windows using PowerShell and have tried different approaches but no luck. I've found this code at https://superuser.com/questions/1079133/run-a-windows-application-without-displaying-its-gui, This only works for Notepad. I need help to make this code work for IE i.e an internet explorer window is opened with page Google. I want to hide this window using below code.
$definition = #"
[DllImport("user32.dll")]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
public static void Show(string wClass, string wName)
{
IntPtr hwnd = FindWindow(wClass, wName);
if ((int)hwnd > 0)
ShowWindow(hwnd, 1);
}
public static void Hide(string wClass, string wName)
{
IntPtr hwnd = FindWindow(wClass, wName);
if ((int)hwnd > 0)
ShowWindow(hwnd, 0);
}
"#
add-type -MemberDefinition $definition -Namespace my -Name WinApi
[my.WinApi]::Hide('Internet Explorer', 'Google - Internet Explorer')
This code doesn't work to hide internet explorer window.
I've figured out that it works when replace 'Internet Explorer' with 'IEFrame'.
it worked with below line
[my.WinApi]::Hide("IEFrame", 'Google - Internet Explorer')
I have a strange Requierment for a Task. In gernerall terms, i need to prepare Windows PCs for Presentations with a PowerShell Script and one of the Requierments is to activate the "hightlight pointer position if ctrl is hit" function in the extended pointer settings.
My first idea was to change the reg-key but if that even works, i think it would be linked to a PC-Restart. I allready tryed to change the Value of the key after finding the diffrenece in the on and off state of the function but i cant force it to "refresh the setting" or it simply does not work.
Any ideas, workaround or the like would be appriciated.
The function is controlled by the Reg-Key HKCU:\Control Panel\Desktop - UserPrefernecesMask
The 'Mouse Sonar' function can be enabled or disabled using the SystemParametersInfo function inside user32.dll.
To use that in PowerShell, add a bit of CSharp:
Add-Type -TypeDefinition #'
using System.Runtime.InteropServices;
public class MouseSonar {
public const uint SPI_SETMOUSESONAR = 0x101D;
public const uint SPIF_UPDATEINIFILE = 0x01;
public const uint SPIF_SENDCHANGE = 0x02;
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int SystemParametersInfo (uint uAction, uint uParam, bool lpvParam, uint fuWinIni);
public static void SetSonar (bool Enable) {
SystemParametersInfo(SPI_SETMOUSESONAR, 0, Enable, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
}
}
'#
and use it like this:
# turn Mouse Sonar on
[MouseSonar]::SetSonar($true)
# to switch Mouse Sonar off again:
[MouseSonar]::SetSonar($false)
No need to restart the computer, this works immediately.
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 :
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.
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
}
}
}
With a powershell code I try to change the position of a window (is works correctly) and put this windows "Always on top".
Please find below my code:
Import-Module C:/install/WASP/wasp.dll
Add-Type #"
using System;
using System.Runtime.InteropServices;
public class SFW {
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
"#
Add-Type #"
using System;
using System.Runtime.InteropServices;
public class Tricks {
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
}
"#
Add-Type #"
using System;
using System.Runtime.InteropServices;
public class allowFor {
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AllowSetForegroundWindow(IntPtr hWnd);
}
"#
Add-Type #"
using System;
using System.Runtime.InteropServices;
public class lockFor {
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool LockSetForegroundWindow(IntPtr hWnd);
}
"#
do
{
Start-Sleep -m 3000
$allWindow = Select-Window Perso*
if($allWindow)
{
foreach ($currentWindow in $allWindow)
{
$positionWindow = WindowPosition $currentWindow
foreach ($currentPosition in $positionWindow)
{
#Loop on each windows
if ( $currentWindow.title -match "\([0-9]*\)#" )
{
# Retrieve windows ID
$id = $currentWindow.title.Substring($currentWindow.title.IndexOf("(")+1, $currentWindow.title.IndexOf(")")-$currentWindow.title.IndexOf("(")-1)
$allHUDWindow = Select-Window * | where {$_.Title -match "\($id\).*.txt"}
if($allHUDWindow)
{
foreach ($currentHUDWindow in $allHUDWindow)
{
$currentForgr = [Tricks]::GetForegroundWindow()
if ( ($currentForgr -match $currentWindow.Handle -or $currentForgr -match $currentHUDWindow.Handle) )
{
write-host "Pus currentHUDWindow in Front"
$hud = (get-process -Id $currentHUDWindow.ProcessId).MainWindowHandle
[allowFor]::AllowSetForegroundWindow(-1)
[SFW]::SetForegroundWindow($hud)
#Modification de la position
Set-WindowPosition -X ($currentPosition.x-10) -Y ($currentPosition.y-30) -WIDTH ($currentPosition.width+20) -HEIGHT ($currentPosition.height+30) -Window $currentHUDWindow
}
}
}
}
}
}
}
} while(1)
But :
[allowFor]::AllowSetForegroundWindow(-1)
[SFW]::SetForegroundWindow($hud)
return me False.
From the documentation:
An application cannot force a window to the foreground while the user is working with another window. Instead, Windows flashes the taskbar button of the window to notify the user.
Do you know how can I force $currentHUDWindow to move in front ? And not only flashes the taskbar button ?
Thanks for your help
e.g, Is the user playing a movie full screen, or looking at powerpoint in full screen mode?
I could have sworn I saw a IsFullScreenInteractive API before, but can't find it now
Here's how I've solved this problem:
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Test
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(IsForegroundWwindowFullScreen());
}
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern int GetSystemMetrics(int smIndex);
public const int SM_CXSCREEN = 0;
public const int SM_CYSCREEN = 1;
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(IntPtr hWnd, out W32RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
public struct W32RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
public static bool IsForegroundWwindowFullScreen()
{
int scrX = GetSystemMetrics(SM_CXSCREEN),
scrY = GetSystemMetrics(SM_CYSCREEN);
IntPtr handle = GetForegroundWindow();
if (handle == IntPtr.Zero) return false;
W32RECT wRect;
if (!GetWindowRect(handle, out wRect)) return false;
return scrX == (wRect.Right - wRect.Left) && scrY == (wRect.Bottom - wRect.Top);
}
}
}
Vista indeed has an API pretty much exactly for this purpose - it's called SHQueryUserNotificationState.
Use GetForegroundWindow to get a handle to the window the user is working with. GetClientRect will give the dimensions of the active part of the window sans borders; use ClientToScreen to convert the rectangle to monitor coordinates.
Call MonitorFromRect or MonitorFromWindow to get the monitor that the window is in. Use GetMonitorInfo to get the coordinates of the monitor.
Compare the two rectangles - if the window rectangle completely covers the monitor rectangle, it's a full screen window.
The preferred way of detecting the state of a window is by calling GetWindowPlacement. If you do that in conjunction with GetForegroundWindow, you can easily check if the user sees a fullscreen window or not.