MainWindowHandle is a Lie

How to bring a window to the front

David Klempfner
Level Up Coding

--

Photo by Nicolas Solerieu on Unsplash

The scenario

At work, I had to write a script to copy an Excel file written in a different Excel version to what was installed on my computer, and edit the copy.

The code to do this is quite simple, however the annoying thing is that after you saved the file, the Microsoft Excel — Compatibility Checker would pop up and block the main thread until you clicked Continue.

The popup would always be hidden behind other windows I had open, and I would have to minimise everything to see the Excel window that had popped up.

So I needed a way to automatically bring the Excel popup to the front.

The Compatibility Checker popup

First attempt at a solution

I had a look online and found some code which would get the MainWindowHandle property of the Excel process, and then use this as an input to a Win32 function to bring that process’s window to the front:

MainWindowHandle is a lie

This code worked fine for other windows, but for some reason the System.Diagnostics.Process.MainWindowHandle property had a value of 0 for the Excel popup, which meant the SetForegroundWindow() function didn’t work.

I noticed that the MainWindowHandle property was > 0 for any window that had an icon in the Windows start bar, so maybe the MainWindowHandle was 0 because although the Excel popup had a GUI, there was no icon in the start bar.

Windows API can do it, so can I

In Task Manager, I was able to right click on the Excel process and click on Bring To Front which would successfully bring that popup to the front, so I knew there had to be some Win32 code that would work.

After some research, I found out that every window has a handle regardless of whether or not it has an icon in the start bar, I just needed another way of finding the correct handle.

Turns out the Windows API does not model the concept of a main window. This is purely implemented in the .NET framework, that applies heuristics to determine, what a user would perceive as the main window.

A working solution

Thanks to IInspectable on StackOverflow.com who directed me to the EnumWindows Win32 function, I was able to write some code that got the correct handle :)

Now the MainWindowHandle property is > 0, we can call the SetForegroundWindow() function:

Using this code, I can now copy an Excel file, modify it and bring the Excel popup to the front automatically :D

Have a look at my GitHub page to see the entire code which copies an Excel file and edits it too.

The entire code also shows you how to run the EnumWindows code in its own thread which you have to do since that Excel popup blocks the main thread.

--

--

I’m a software developer who is passionate about learning how things work behind the scenes.