Taxes: Detecting session state changes, such as a locked workstation

Date:January 4, 2006 / year-entry #8
Orig Link:
Comments:    23
Summary:Another developer tax is playing friendly with Fast User Switching and Terminal Services. When the workstation is locked or disconnected, you should turn off non-essential timers, minimize background activities, and generally send your program into a quiet state. If you already used the technique of painting only when your window is visible on the screen,...

Another developer tax is playing friendly with Fast User Switching and Terminal Services. When the workstation is locked or disconnected, you should turn off non-essential timers, minimize background activities, and generally send your program into a quiet state. If you already used the technique of painting only when your window is visible on the screen, then you get all of this for free, since a locked workstation and a disconnected session do not generate paint messages.

If you have other activities that you need to scale back or shut down when the user has locked the workstation or disconnected, you can register to be notified when the state changes. Knowing about these state changes is also important so that you can tell when your display is local or remote. As we saw last time, drawing on Remote Desktop Connection is much slower than on a local display, since all the bitmaps need to be transferred over the network to the Remote Desktop client.

Since locking a workstation and disconnecting a session remove the ability to use visual feedback to indicate our program's state, we'll use the speaker. Start with our new scratch program and make the following changes:

#include <wtsapi32.h>

LRESULT RootWindow::OnCreate()
 WTSRegisterSessionNotification(m_hwnd, NOTIFY_FOR_THIS_SESSION);
 return 0;

LRESULT RootWindow::HandleMessage(
                          UINT uMsg, WPARAM wParam, LPARAM lParam)
 switch (uMsg) {
  switch (wParam) {
   Beep(440, 250); break;

   Beep(880, 250); break;

In this program, we register for a session notification when we create our main window, and listen for the session change message in our window procedure. If we see one of the "going away" messages, we make a low beep; if we see one of the "coming back" messages, we make a high beep.

Run this program and then lock the workstation or use Fast User Switching to switch away. You should be greeted by a low beep (though you may have to listen carefully if you have a sound associated with the action you performed because the low beep will be mixed in with it). When you switch back, you should hear a high beep.

Of course, a real program would respond to the notifications by starting or stopping its background tasks. The purpose of this program was merely to show how to get the notifications in the first place.

Comments (23)
  1. Mike says:

    Oh, get real. Even XP itself emits sounds using the local machine from time to time when you’re connected using mstsc (MicrtoSoft Terminal Server Client), even if you told it to remote the sounds. (you might also want to try to wrap your head around the "Microsoft Server Client" stuff, and righfully bash the people ever coming up with "TS" with a clue-by-four)

    Who are you trying to fool? XP, actually Windows as a whole, is nothing more than a desktop-OS with some server features bolted on, much like you could force a DOS machine to become a NetWare server of sorts. In its core, Windows is a single-user, single desktop OS, no matter what version.

    Make no mistake, I actually like RDP, assuming an XPsp2 or above "server". It’s the only thing that has enabled me to remote-use machines like I did using X for a decade with decent speed. Not good spped, but decent speed. But it still is really nothing more than a fancy VNC, is it. It has gained some of the X features to draw lines and stuff, but it’s still basically an optimized VNC connection, nothing even remotely (no pun intended) designed to the extent the X protocol was many, many moons ago.

    Pair that with the insanely single-machine (not single-user, single-machine) assumptions in many, many of the API’s, and then for good measure add the single-user assumption, and we basically have a 1.5-2 gigabytes of diskspace 32-bit MS-DOS with a GUI and many, many unwanted "services" (some might call them disserives) – but it’s still a single-user OS at heart.

    The problems Microsoft now sees in this area, is nothing more than a display of Microsofts own fallacies when they failed to design a sustainable model for the GUI. Hell, your window model is more like an Amiga – an OS that effectivelly died two decades ago.

  2. Mark L says:

    Good grief. Apparently somebody forgot to take their Midol today.

  3. Av says:

    I vote troll comments be removed!

  4. hmmmm says:

    I agree! Boot the troll — he clearly doesn’t know a think about OS’ anway.

    My question: How long should Raymond go before the "new scratch program" is just the "scratch program" (or even the "old scratch program")?

  5. josh says:

    Is there some interaction between FUS and multiple monitors that’s difficult to handle? I’ve noticed that Explorer gathers all icons to the primary monitor and wonder if there’s some technicaly reason for this.

  6. Ryan Phelps says:

    Raymond, get in touch with O’Reilly and write a damn book. I promise I’ll buy it. The taxes need to be in an easy to browse, in-your-face format, with some very specific guidelines. I realize you’ll have the caveat that there will be more things later, but that’s just a reason for people to buy the second edition. Here’s your title: Effective Win32: 50 Specific Items to Improve Your Windows Programs. (apologies to Scott Meyers)

  7. RobertWrayUK says:

    hmmmm – wouldn’t that make it the "old new scratch program"

    << Now retreating before he gets beaten with a stick for the worst pun ever!

  8. Doug says:

    The code I use to do this (itself based on MSDN examples) loads the Terminal Services library dynamically. This way the code runs on the older Windows versions which don’t have TS installed. (Otherwise the prog will refuse to run when the loader cant find the TS library.)

  9. Marvin says:

    Taxes, taxes… Almost nobody is going to pay taxes (the ones Raymond is talking about or real ones) unless there is a man with a stick standing nearby. Raymond can write and admonish and educate but this will not make an average developer or a company to pay any attention. Either the users will complain (extremely unlikely) or the OS will play the role of the man with a stick.

    The real problem is the collaborative nature of many things in Windows (and other OSes including Linux). I don’t have an easy solution for this in my pocket but perhaps MS should think about reducing its reliance on programs good behavior.

  10. Daev says:

    How does a console mode program handle notifications like this?

  11. John C. Kirk says:

    I’m all in favour of "paying my taxes", and I can see why you need to handle fast-switching/remote desktop. However, I don’t understand why you’d want to do things differently when the PC is locked (the only issue I can think of is power consumption). Putting it another way, what’s the cost involved? Speaking for myself, if I lock my PC then I actively want it to keep doing whatever it’s doing, so that it can make use of the "dead time" while I’m on the toilet. So, if anything, I’d say that it makes more sense to ramp up the background activities (e.g. a spell-check in Word) when it knows that there won’t be any foreground things to worry about.

    That said, it’s still useful to know how to handle the notifications, so I’m just wondering whether I’m missing something obvious.

    (And echoing Ryan’s comment, I’d cheerfully buy a book by Raymond, sight-unseen.)

  12. Tim Smith says:

    One example would be a program that actively animates objects in a window, for example a level design program for a video game. When the application is active, the user might wish to have the animation frame rate close fully utilizing the CPU while more application friendly when the program isn’t active. However, when the computer is locked, there is no point at all to doing any animation rendering or processing.

  13. Cooney says:

    The only problem with your example is that the downside is so small – the only real consequence of leaving the animation spinning is increased power consumption (and possibly some disk activity). On the other hand, if that dev used an OpenGL screensaver, it might fight with the app for control of the cpu, thus trashing any sort of batch activities.

  14. Dean Harding says:

    How does a console mode program handle notifications like this?

    Console applications can still have windows and so can still register for notifications. The window doesn’t have to be visible to receive them.

  15. amit joshi says:

    It will be great if frameworks like MFC/ATL/WTL/.Net were built with the support for these ‘taxes’ by default, so that even a simple ‘Hello World’ application created using a Appwizard gets those benefits. This will go a long way towards ensuring compliance to the standard (or expected) behavior.

    Applications will behave like good citizens by default and developers won’t have to sell the advantages of being ‘good citizens’ and ‘paying taxes’ in face of demanding schedules.

  16. Tim Smith says:

    The problem isn’t as small as you think. Animation and other background operations done can be very costly.

  17. Ben Cooke says:

    Another problem which I assume can be solved by these notifications is changing display characteristics over the course of a session.

    While I’m using my workstation at my office interactively, I have a bunch of programs running. At the end of the day, I tend to lock my workstation and leave everything up so I can continue where I left off the next day.

    Sometimes, though, I will be working from home the next day. I use the remote desktop client to log in. The workstation has just been "unlocked" but with the desktop connected to a completely different device than it was before. Windows seems to send out a broadcast message to all apps telling them about the screen resolution change, but sometimes resizing your windows isn’t good enough.

    It seems that other things go awry in this situation. For example, some applications which have GDI bitmaps allocated seem to end up drawing garbage to the screen, presumably due to the fact that the raw bitmap format is different on the local graphics card vs. the remote desktop connection. (I’m just guessing here) Causing these apps to remake the bitmaps (for example, hitting refresh in my web browser) fixes the problem.

    If these apps listened for the messages indicating a lock and unlock they could check to see what’s changed and rebuild the graphics if necessary. Of course, it makes more sense to do this when windows sends the message about the display change, but it can’t help to do both…

  18. I concur with Ryan. You should make a book about (for one thing) all the things good behaving apps should do that most programs don’t; taxes are just one part of this (other things are even more blatently obvious, but people still don’t do it right).

  19. Simon Cooke says:

    I’d buy that book :)

  20. sfb says:

    "Putting it another way, what’s the cost involved?"

    "The only problem with your example is that the downside is so small – the only real consequence of leaving the animation spinning is increased power consumption (and possibly some disk activity)"

    Increased power consumption is a bad thing, although more for Laptops and Tablet PCs than for desktops…

  21. Iain says:

    Re book – heh, the bestselling Books result for ‘Raymond Chen’ on is already ‘Citizens and Taxes’…

  22. If you are writing rich-client applications for the Windows desktop there are lots of little touches…

  23. Otherwise you end up creating the impossible.

Comments are closed.

*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index