As I’ve mentioned before, I’ve been fuddling around doing UI programming recently – it’s a bit different from my usual work deep in the bowels of the <insert whatever subsystem Larry happens to be working on (redirector, audio stack, POP3 server, whatever)>.
I’ve been having a great deal of fun doing the whole “UI programmer” thingy (although my grandboss is right – once you start doing UI, everyone thinks that you’ve done it wrong) recently, and I’ve learned a ton of stuff.
Most of the UI I work with is written as dialog box applications – for various reasons, many of the audio UI elements are actually dialog boxes. As such, the system controls the actual drawing of the UI elements, especially if you specify the WS_CLIPCHILDREN window style.
I recently had a bug where one of the UI elements wasn’t being painted correctly. For a number of reasons, the element was being overwritten by another element.
It took a lot of work to get to the scenario where the UI element got messed up, so I was going to ignore the problem (it was ugly but transient). But then I got to browsing the web and I ran into this article. The article had nothing to do with the order of painting in a dialog, but it DID mention a windows message that I hadn’t heard of before, WM_PRINTCLIENT.
Hmm, that’s interesting. WM_PRINTCLIENT says “The WM_PRINTCLIENT message is sent to a window to request that it draw its client area in the specified device context, most commonly in a printer device context.”. Ooh, that’s interesting. If I can just send a WM_PRINTCLIENT to each of the controls in the window, maybe I can control the order in which the controls are rendered, which would allow me to fix the problem (and remove a long-standing issue with the program in question).
On Monday of last week, I came in and decided that I’d dedicate a couple of days to see if my idea might work – worst case I’d lose a couple of days of work, but if it did work it would be really cool.
By mid-afternoon on Monday, I had come to the point where I realized that my crazy idea would actually work.
Skip forward one very long week of debugging and tweaking and I had fixed the problem – I had rebuilt the painting algorithm for this application and it worked!
Right now I’m highly enamored of the WM_PRINTCLIENT message simply because it’s so darned useful in scenarios like mine.
PS: It’s possible that I might be able to achieve similar results with the WS_EX_COMPOSITED window style but it’s not clear given some of the UI requirements for the application – I may play around with that idea over the next couple of weeks.
 One of the reasons for the apps being dialog box based is that it makes it easier for localizers if the application is built on dialog boxes because it gives the localizers greater flexibility when translating the OS – if the preferred text in the destination language doesn’t fit, they can adjust the layout of the dialog to make the text fit.
Simon: IN this case it's because of the UX design for sndvol.exe - sndvol is a dialog box with a horizontal line that runs through (above the background below the control) for several other controls.
There ARE better solutions but I've not yet found one that works and can be implemented within a reasonable amount of time.
Ah, I see what you mean there... got ya. I think in that scenario, I'd probably just get down and dirty and override the painting logic for the dialog itself, and paint to its background.
Simon: That's actually what the old code did :). It has "issues" though - stuff doesn't always repaint right, especially after theme changes.