Author Topic: Problem switching to file explorer  (Read 2156 times)

librarian

  • Newbie
  • *
  • Posts: 15
Problem switching to file explorer
« on: March 02, 2022, 03:40:24 PM »
I am having trouble switching to file explorer, obviously because the window name changes depending what was last happening in it. I have read the parts of the manual I thought appropriate and some forum topics but am still unable to solve this problem.

I have tried everything in the "Active Window Details" info box. explorer, explorer.exe and the class with no luck.

What am I doing wrong?

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4790
  • RTFM
Re: Problem switching to file explorer
« Reply #1 on: March 02, 2022, 05:20:19 PM »
The windows you're attempting to target are not the main window of the explorer process, so targeting them using the process name cannot work.


This inline function should bring up the explorer window that was last in focus, or un-minimize one if there are no visible windows:
Code: [Select]
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using System.Diagnostics;

public class VAInline
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", SetLastError=true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

[DllImport("user32.dll")]
private static extern int GetWindowTextLength(IntPtr hWnd);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindow(IntPtr hWnd);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindowVisible(IntPtr hWnd);

[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsIconic(IntPtr hWnd);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_RESTORE = 9;

 
public void main()
{
IntPtr windowHandle = IntPtr.Zero;

List<uint> explorerProcessIDs = new List<uint>();
foreach(Process p in Process.GetProcessesByName("explorer"))
{
explorerProcessIDs.Add((uint)p.Id);
}

IntPtr prevHandle = IntPtr.Zero;
while(true)
{
IntPtr handle = FindWindowEx(IntPtr.Zero, prevHandle, null, null);
if (handle == IntPtr.Zero || handle == null)
{
break;
}

prevHandle = handle;

uint procID = 0;
GetWindowThreadProcessId(handle, out procID);

if (explorerProcessIDs.Contains(procID))
{
int titleLength = GetWindowTextLength(handle);
if (titleLength != 0)
{
StringBuilder sb = new StringBuilder(titleLength + 1);
GetWindowText(handle, sb, titleLength + 1);
string windowTitle = sb.ToString();


if (IsWindow(handle) && IsWindowVisible(handle) && windowTitle != "Program Manager")
{
VA.WriteToLog("Bringing \"" + windowTitle + "\" to front");

//Restore window if minimized
if (IsIconic(handle))
{
ShowWindow(handle, SW_RESTORE);
}

SetForegroundWindow(handle);
return;
}
}
}
}
}
}

If it merely blinks the taskbar, Windows is preventing focus from being switched by a background application. This may work around that, though note that editing the registry is at your own risk, and will require administrator privileges.


Note that minimizing a window moves it to the bottom of the hierarchy, E.G. if you have "Window 1" and "Window 2" open, and you minimize "Window 2", and then minimize "Window 1", executing the inline function will bring up "Window 2", despite "Window 1" having focus most recently
« Last Edit: March 02, 2022, 07:59:28 PM by Pfeil »

librarian

  • Newbie
  • *
  • Posts: 15
Re: Problem switching to file explorer
« Reply #2 on: March 02, 2022, 07:58:15 PM »
That seems to work, thanks