Not strictly programming related, but sparked by some recent UX I had with a few programs, including some I wrote. These are not hard and fast rules, by any stretch of the imagination, but they provide a good checklist of basic things that are sometimes forgotten when it comes to Application development, and presentation. I’ll make additions to these “rules” as I consider them through testing or finding frequent trouble spots.
To name and shame- Firefox does this last I checked. Another program that pins itself when it is installed is PowerArchiver, an otherwise excellent archiving tool which only appears one other time in this post. “Pinned” programs have somewhat replaced the Quick Launch bar. Personally, I prefer the quick launch toolbar and don’t pin any programs; but the general idea is that the taskbar icon for pinned programs are always present, so you can “switch” to the program and if it’s not running it will start. (I’m oversimplifying it, mind you). Now, Pinning and unpinning is something which has no programming API; there is no Win32 API function to call to add a pinned program or remove one; the idea is that the user decides what is pinned by explicitly pinning it. My understanding of Firefox’s logic is that Internet Explorer is pinned by default (Edge in Windows 10) so they should pin themselves by default. I can sort of see where they are going with that logic- to be entirely fair, Internet Explorer shouldn’t be pinned in a default Windows install- but I don’t think two wrongs really make a right here. By the time I install Firefox, I’ve already unpinned Internet Explorer and the Windows Store and don’t have any pinned programs; I don’t want Firefox pinned either. And If somebody is a Firefox user or somebody sets up Firefox for somebody else (or Chrome, for that matter, though I don’t think Chrome automatically pins itself on install) then I’m sure they are capable of pinning Firefox themselves if they desire it that way.
The problem is that regardless of the circumstances, it presumes that your application is special. Moving to Powerarchiver, I recently updated to a newer version that was available, and after installing the new version, I found Powerarchiver had automatically pinned itself to the Taskbar. C’mon guys! Very few people use an Archiving tool in a manner where they will want to launch it standalone; speaking for myself, I use it through windows explorer to extract and very occasionally compress zip or 7z or other archive formats. I seldom launch it on it’s own, and I imagine that extends to most people. But even if that was not the case, to bust out a rhyme, ahem…”pinning yourself is forgetting yourself.”. That was a terrible rhyme, which fits with the behaviour. Let the user decide what to pin and whether your program is useful enough to them to pin. The fact that somebody had to grovel through internal Windows functions and structures to find out how they can force their program to be added to the taskbar as a pinned button I think just makes it worse, like nobody along the way said “Hey, guys, maybe our program isn’t the awesomest most useful program ever, perhaps not every single person will want it pinned?”
This extends to a lot of other annoying behaviours. Don’t steal file associations willy nilly- if your program wants file associations, present a prompt- or better yet- only associate unassociated file types, and provide an options dialog to allow users to associate other file types already associated with other programs. Setting as the default program for things like browsing fall into the same category.
When you run a program that doesn’t indicate it supports High DPI in it’s Manifest file on a High DPI display, Windows will try to scale it itself. It effectively does this by allowing the program to think it is running at a standard 72 (100%) DPI, and then stretching the image of the client area to the “actual” scaled size. For example, here is Recoder being displayed in that manner:
As we can see, this scaling feature allows programs that might not support higher DPI or have issues to remain compatible when run on high DPI displays, at the cost of looking rather blurry. If we add a call to SetProcessDPIAware() or if we declare DPI awareness in the manifest file, it looks much better.
The Caveat, of course, is that your program needs to be- well, DPI Aware. Since Windows isn’t going to do any work for you you’ll need to make sure that your Window Layout can be properly displayed regardless of the DPI of the user’s Monitor. This is particularly troublesome when using Windows Forms, as when you save a Form Designer, it saves pixel data that is dependent on your Development system DPI. On target systems, it attempts to scale based on that and the relative size on the system it is running on, but a bug means that if it attempts to scale to a DPI lower than the system on which the designer file was saved, then it completely borks a lot of the layout. The workaround is to save on a system with 100% DPI; for my work I’ve had to do that (we still use Windows Forms as the product is older and far to large to consider moving to a newer tech anytime soon) by using a separate system set for 100% DPI, selecting a element and moving it back and forth (to register a change) and saving and committing the designer.
If your program declares itself “DPI aware” then making sure it’s not a liar by verifying it works on non-standard DPI settings should be part of an exhaustive testing regimen.
Windows as well as other Operating Systems establish conventions for where certain data should be stored. Data should be stored in these locations, such as the Application Data folder, the Common Application Data Folder, and so on. If nothing else, storing any additional data after installation to your programs installation directory is a strict no-no.
One thing that might get neglected in testing is the behaviour of any program uninstallers. These should be verified to remove the program and, if an option is provided, application data. Ideally, an uninstallation would not delete program configuration data, except where an option is provided to do so, and it is checked off.
Sometimes software might have different operating modes. For example, it may work different or even do a completely different task when run with certain arguments; perhaps a program might display different UI elements, or it might perform operations differently. Regardless, when testing software, or making changes, it is a good idea to check that all these operating modes continue to function as expected. Even if an added feature is added in a way that should “magically” work with the other approaches, such as in a central routine used by all the specific “operating modes”, it should still, of course, be verified. This is easy to skip with the justification that it probably works but probably is not knowledge or verification!