Processing Ajax...

Title

Message

Confirm

Confirm

Confirm

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure?
Save up to 50% on our desktop apps during our Year End Sale!Save up to 50% on our desktop apps during our Year End Sale, including DisplayFusion, ClipboardFusion, FileSeek, LogFusion, TrayStatus, and VoiceBot!Save up to 50% on our desktop apps during our Year End Sale!

Save Window Positions and Z-Order

Description
This script will save the window positions with their Z-order for all currently open windows. It saves by window handle, so if a window is closed and re-opened, it will no longer have its position saved.
Language
C#.net
Minimum Version
Created By
Thomas Malloch (BFS)
Contributors
-
Date Created
13d ago
Date Last Modified
13d ago

Scripted Function (Macro) Code

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

// The 'windowHandle' parameter will contain the window handle for the:
//   - Active window when run by hotkey
//   - Window Location target when run by a Window Location rule
//   - TitleBar Button owner when run by a TitleBar Button
//   - Jump List owner when run from a Taskbar Jump List
//   - Currently focused window if none of these match
public static class DisplayFusionFunction
{
	[DllImport("user32.dll", SetLastError = true)]
	static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
	
	//some constants
	const uint GW_HWNDNEXT = 2;
	
	public static void Run(IntPtr windowHandle)
	{          
        // Get a list of each visible window on our monitors, and throw them in a HashSet		
        HashSet<IntPtr> visibleWindows = new HashSet<IntPtr>(BFS.Window.GetVisibleAndMinimizedWindowHandles());
        
		// A list to store the windows
		List<WindowInfo> windows = new List<WindowInfo>();
		
        // Enumerate through the monitors, starting with the focused window, and moving down
		int order = 0;
		for(IntPtr window = BFS.Window.GetFocusedWindow(); ; window = GetWindow(window, GW_HWNDNEXT))
		{
			// Check to see if there are any windows left
			if(window == IntPtr.Zero)
				break;
			
			// If it is a window we should ignore, ignore it
			if(IsDisplayFusionWindowOrHiddenExplorerWindow(window))
				continue;
			
			// Check to see if the window exists in the hashset.
			// If it does, store it
			if(!visibleWindows.Contains(window))
				continue;
			
			// Store the window with its info
            windows.Add(new WindowInfo(window, order++));
		}
        
        // Save the windows
		BFS.ScriptSettings.WriteValue("WindowInfoList", System.Text.Json.JsonSerializer.Serialize(windows));
	}
	
	private static bool IsDisplayFusionWindowOrHiddenExplorerWindow(IntPtr window)
	{
        // Ignore any DisplayFusion windows (title bar buttons, etc.)
        // Ignore pesky hidden explorer.exe windows
        string windowClass = BFS.Window.GetClass(window);
        if((windowClass.StartsWith("DF", StringComparison.OrdinalIgnoreCase)) ||
            (windowClass.Equals("EdgeUiInputTopWndClass", StringComparison.OrdinalIgnoreCase)) ||
            (windowClass.Equals("EdgeUiInputWndClass", StringComparison.OrdinalIgnoreCase)) ||
            (windowClass.Equals("NativeHWNDHost", StringComparison.OrdinalIgnoreCase)) ||
            (windowClass.Equals("ModeInputWnd", StringComparison.OrdinalIgnoreCase)) ||
            (windowClass.Equals("MetroGhostWindow", StringComparison.OrdinalIgnoreCase)) ||
            (windowClass.Equals("ImmersiveLauncher", StringComparison.OrdinalIgnoreCase)) ||
            (windowClass.Equals("ApplicationManager_ImmersiveShellWindow", StringComparison.OrdinalIgnoreCase)) ||
            (windowClass.Equals("Shell_TrayWnd", StringComparison.OrdinalIgnoreCase)) ||
            (windowClass.Equals("WorkerW", StringComparison.OrdinalIgnoreCase)) ||
            (windowClass.Equals("Progman", StringComparison.OrdinalIgnoreCase)) ||
            (windowClass.Equals("SearchPane", StringComparison.OrdinalIgnoreCase)))
        {
            return true;
        }
        
        return false;
	}
	
	public class WindowInfo
	{
		public long Handle { get; set; }
		public FormWindowState State { get; set; }
		public Rectangle Bounds { get; set; }
		public int ZOrder { get; set; }
		
		public WindowInfo(IntPtr handle, int zOrder)
		{
			this.Handle = handle.ToInt64();
			if(BFS.Window.IsMinimized(handle))
				this.State = FormWindowState.Minimized;			
			else if(BFS.Window.IsMaximized(handle))
				this.State = FormWindowState.Maximized;
			else
				this.State = FormWindowState.Normal;
			
			this.Bounds = BFS.Window.GetBounds(handle);
			this.ZOrder = zOrder;
		}
	}
}