Processing Ajax...
Save 25% on our desktop apps during our Black Friday/Cyber Monday sale!Save 25% on our desktop apps during our Black Friday/Cyber Monday sale, including DisplayFusion, ClipboardFusion, FileSeek, LogFusion, TrayStatus, and VoiceBot!Save 25% on our desktop apps during our Black Friday/Cyber Monday sale!

Title
Close Dialog

Message

Confirm
Close Dialog

Confirm
Close Dialog

Switch to Last Focused Window

Description
This script switches to the previously focused window (2nd window in the z-order).
Language
C#.net
Minimum Version
Created By
Thomas Malloch (BFS)
Contributors
-
Date Created
Jul 19, 2018
Date Last Modified
Aug 27, 2018

Scripted Function (Macro) Code

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

// 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)
	{
        BFS.Window.Focus(GetWindowByZOrder(2));
	}
	
	private static IntPtr GetWindowByZOrder(uint zOrder)
	{
		if(zOrder == 1)
			return BFS.Window.GetFocusedWindow();

		//get the visible window handles for that monitor
		HashSet<IntPtr> visibleWindows = new HashSet<IntPtr>( BFS.Window.GetVisibleWindowHandles() );

		//enumerate through the monitors, starting with the focused window, and moving down
		//only enumerate if we havn't found the windows yet
		IntPtr topmost = BFS.Window.GetFocusedWindow();
		int lastZOrderFound = 1;
		for (IntPtr window = GetWindow(topmost, GW_HWNDNEXT); ; window = GetWindow(window, GW_HWNDNEXT))
		{
			//check to see if there are no windows left
			if(window == IntPtr.Zero)
				break;
				
            //check to see if the window is visible. if it's not, ignore it
			if(!visibleWindows.Contains(window))
                continue;
				
			//if it is a window we should ignore, ignore it
			if(IsDisplayFusionWindowOrHiddenExplorerWindow(window))
				continue;

			//this is a cantidate! increment the lastZOrderFound, and see if we're at the level we want
			lastZOrderFound++;
			if (lastZOrderFound != zOrder)
				continue;

			return window;
		}
	
        //return IntPtr.Zero if we didn't find anything
        return IntPtr.Zero;
	}
	
	private static bool IsDisplayFusionWindowOrHiddenExplorerWindow(IntPtr window)
	{
        //ignore any DisplayFusion windows (title bar buttons, etc.)
        //ignore pesky hidden explorer.exe windows
        if((BFS.Window.GetClass(window).StartsWith("DF", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("EdgeUiInputTopWndClass", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("EdgeUiInputWndClass", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("NativeHWNDHost", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("ModeInputWnd", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("MetroGhostWindow", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("ImmersiveLauncher", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("ApplicationManager_ImmersiveShellWindow", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("Shell_TrayWnd", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("WorkerW", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("Progman", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("SearchPane", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetText(window).Equals("")))
        {
            return true;
        }
        
        return false;
	}
}