I am trying to get application size using this code :
[DllImport(@"dwmapi.dll")]
private static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out Rect pvAttribute, int cbAttribute);
[Serializable, StructLayout(LayoutKind.Sequential)]
private struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public Rectangle ToRectangle()
{
return Rectangle.FromLTRB(Left, Top, Right, Bottom);
}
}
private static bool DWMWA_EXTENDED_FRAME_BOUNDS(IntPtr handle, out Rectangle rectangle)
{
Rect rect;
var result = DwmGetWindowAttribute(handle, (int)Dwmwindowattribute.DwmwaExtendedFrameBounds,
out rect, Marshal.SizeOf(typeof(Rect)));
rectangle = rect.ToRectangle();
return result >= 0;
}
it's working fine for all running applications but if it's Media Player in fullscreen mode I didn't get the right Rect size.
Windows Media Player is weird in full screen mode such that the main window handle doesn't correspond to the full screen window displayed. The full screen window still has a handle but a little more work is needed to get to it.
First you'd need to declare some WinAPI functions and structs:
delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);
[DllImport("User32.dll")]
static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("User32.dll")]
static extern bool GetMonitorInfo(IntPtr hMonitor, ref MonitorInfo lpmi);
[DllImport("User32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("User32.dll")]
static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
[StructLayout(LayoutKind.Sequential)]
struct MonitorInfo
{
public uint Size;
public Rect Monitor;
public Rect Work;
public uint Flags;
}
// You seem to have this one already
[StructLayout(LayoutKind.Sequential)]
struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
From there, the method looks like this:
// Pass Windows Media Player's main window handle here.
static bool GetWmpFullScreenHandle(IntPtr mainHandle, out IntPtr fullScreenHandle)
{
IntPtr tempHandle = IntPtr.Zero;
// Getting WMP's PID from the main window handle.
GetWindowThreadProcessId(mainHandle, out uint wmpProcessId);
// Optionally, check if the PID resolves to a WMP process.
if (System.Diagnostics.Process.GetProcessById(wmpProcessId).ProcessName != "wmplayer")
{
fullScreenHandle = IntPtr.Zero;
return false;
}
// This iterates through all the open window handles on the machine
// and passes them to the callback below.
EnumWindows((hWnd, lParam) =>
{
// Getting the window handle's PID.
GetWindowThreadProcessId(hWnd, out uint windowProcessId);
// Checking if the window handle belongs to the WMP process.
if (windowProcessId == wmpProcessId)
{
var monitorInfo = new MonitorInfo
{
Size = Convert.ToUInt32(Marshal.SizeOf(typeof(MonitorInfo)))
};
// Getting the dimensions of the monitor the window is displayed on,
// as well as the window dimensions.
if (GetMonitorInfo(MonitorFromWindow(hWnd, 0), ref monitorInfo) &&
GetWindowRect(hWnd, out Rect windowRect))
{
Rect monitorRect = monitorInfo.Monitor;
// If the window dimensions are the same as its monitor's
// dimensions, then we found a hidden full-screen window!
if (windowRect.Left == monitorRect.Left &&
windowRect.Top == monitorRect.Top &&
windowRect.Right == monitorRect.Right &&
windowRect.Bottom == monitorRect.Bottom)
{
tempHandle = hWnd;
}
}
}
return true;
},
IntPtr.Zero);
fullScreenHandle = tempHandle;
// Returns true if the hidden full-screen handle was found, false otherwise.
return fullScreenHandle != IntPtr.Zero;
}
If found, you can then pass the resulting handle to DWMWA_EXTENDED_FRAME_BOUNDS
to get the Rectangle
.