Staring at Tiny Windows

Posted by SarahElSaig on February 18, 2024

First World Problems

Pixel games are really something else. They look great when sharp but some creators take it a bit too far. If you like them, you have probably met your fair share of titles made in tools (like certain versions of Clickteam Fusion, RPG Maker and Adventure Game Studio) that are less friendly with high res or (ultra)wide monitors in full screen mode. I've seen a lot that either flat-out refuse to go full screen or cause the display to commit sudoku right there as the monitor is trying to display a tiny resolution it just can't comprehend any more. This happens even with relatively modern software! If you want to play something from a few decades back, you better hope there is a console port you can emulate because PC games that want to play at 320x240 are pretty much a lost cause... or are they?

Maybe you've faced the same problem and thought of using the Magnifier tool in Windows while the game is in windowed mode. That's a good start, but centering the screen is extremely fiddly. If the game doesn't capture your mouse, you are doomed to accidentally nudge it and pan the screen way far away from the window you are actually interested in. Also the magnifier's zoom levels are not very fine so you can leave a lot of dead space. What if there is a more civilized tool for the job?

A Niche Solution

Introducing Big Peek!

So it turns out you can access the Windows Magnification API from code. It has basically infinite level of precision and you can fix the zoom location. The Magnifier utility just won't trust you with such power!

I made my own utility called Big Peek! (enthusiasm is part of the correct pronunciation). A simple window that can target another window on the same screen. It simply does a pan & zoom to fit around the selected window, centering it as much as possible. Then it stays like that until you hit Ctrl+Win+X. It's not doing anything weird like polling to see if the target is still alive, so if you forgot the combo you are trapped in zoom land. (skill issue) Also it does some non-permanent logging in ts own window, though it only shows the window title and the zoom rectangle (in X11 geometry notation, just to remind myself that I haven't sold my soul to Bill Gates just yet).

If you are interested you can find the Git repository along with the download link here!

Some Background

It's using WPF for the GUI, because that's what I'm most comfortable with on the desktop and this will never be cross-platform so there is no point trying to re-familiarize myself with Avalonia. Under the hood it's doing a ton of native interop calls with different Windows APIs. Normally when you have to interact with unmanaged DLLs you start to cry, then once you are done with that you try to look up how to do it with P/Invoke and start to cry again. If you are a bit more experienced, you might use a library like AdvancedDLSupport. But the truth is, Windows APIs are used by all kinds of people, someone has mapped the whole thing already! I've used Vanara, specifically Vanara.PInvoke.Magnification for the zoom feature and Vanara.PInvoke.User32 for the rest. The upside of using a library like Vanara is that they have already collected the documentation and the constants, something that's all over the place in Microsoft's original C++ documentation. So if you don't like wild goose chases, this is a huge help. Even then, you will find yourself looking over StackOverflow code made in Visual C++ if you try to interact with these libraries.

What was all that API use for anyway? Most importantly, the Magnification API just lets you do a single call full screen transform like you are a trustworthy adult or something! But sadly that was the easy part. I also had to register window events to pick a window handle with the mouse and had to implement a whole hotkey service using global keyboard hooks just to register the unzoom hotkey. WPF only lets you register hotkeys within its own window (afaik Winforms is the same), but if you have already selected the Big Peek! window you could just as well unzoom with Alt+F4. It wasn't that harrowing thanks to these NuGet packages, but it still felt like studying occult magic. I was actually surprised when I looked for a solution for global hotkeys in WPF and people just casually suggested using P/invoke, because apparently there is no pre-made library for this. Weird. Anyway, if you need a global hotkey service feel free to yoink the file I've just linked.

Note

I've shown an example above using Void Stranger, it very conveniently starts in a borderless window anyway. This is very rare. Personally I'm not bothered by window titles and borders, but if you want to get rid of them you can always bully the window manager into doing your bidding. One option is Borderless Gaming, but it's meant for borderless full screen so it will pull the window to the top right corner. You can also use AutoHotKey with the WinSet, Style, -0xC00000, ahk_exe filename.exe command with filename.exe correctly substituted. Hope that helps.