Sunday, January 08, 2012

Hiding Win32 Windows

Summary: This post describes how to hide windows on the Windows operating system, by using the Win32 API from Haskell.

Imagine that whenever your computer restarts, it pops up a message box:

If you interact with this window, your computer will be destroyed. You can't kill the process, or dismiss the window harmlessly. (This scenario isn't hypothetical...) The solution is to hide the window, so it still exists but is out of the way of misplaced clicks. To hide the window, we first find it's OS handle, then we call some Win32 API functions.

Find the Window

To find the handle of the window, we use Spy++. Spy++ comes with Visual Studio, and is bundled in the Express edition (the free version) from 2010 onwards. Start Spy++, got to Search, Find Window, then use the finder tool to select the window in question. Check that the caption of the window matches what Spy++ reports:

The important information is the handle: 0004061E.

Hide the Window

To hide the window you need a programming language capable of making Win32 API calls. In the past I have used Word VBA as the host language, but Haskell is probably easier. Start GHCi, and type:

$ import System.Win32
$ import Graphics.Win32
$ showWindow (castUINTToPtr 0x0004061E) sW_HIDE

Replace 0x0004061E on the final line with 0xyour-handle. The final line should cause the window to be hidden, saving your computer from destruction.

Thanks: Thanks to Roman Leshchinskiy for reminding me that there were better solutions than just trying not to click the window. Thanks to the Win32 Haskell developers - the Win32 binding was a lot of work, which not many people ever see.


Cetin Sert said...

Does the handle really stay the same next time you boot?

Neil Mitchell said...

Cetin: No, you need to Spy++ to find the window handle each time. It's my laptop, so I only reboot it every few weeks - usually I just close the lid.

Anonymous said...

I HAVE to ask... what's the real deal?

Neil Mitchell said...

Anon: Something wants to do a forced software update. I already know that with the new version installed, my computer will suffer very serious performance degradation for no benefit. I'd rather opt out of the new version, and this is the only way I can do it.

Christopher Done said...

Hey Neil, Not sure if you're aware of this if so just ignore it, but with the Win32 API you have FindWindowEx which lets you find a window by its parent, class (as seen in spy++) and title. That way you don't even have to open up spy++ if the World of Pain app is really bugging you every time you log on.

Neil Mitchell said...

Christopher: Yeah, I've used FindWindowEx before, it would certainly do the job. However, I only reboot once every few weeks, and I'm hoping this situation won't last forever, so at the moment I didn't think it was worth automating fully (just blogging, so I can copy and paste the code next time). If it continues or moves to a computer I reboot more regularly I'll certainly automate the rest!