Some programs, such as MSN Messenger, change their behavior when the current session is locked and unlocked. Messenger, for instance, will change your status to Away while your machine is locked, and then back to Online when your machine is unlocked.
In order to pull this off, you'll need Windows to notify your application when the locked status of the current session is changing. On Windows XP and higher, you can get this notification via a WM_WTSSESSION_CHANGE message. You notify Windows that you want to receive that message via a call to WTSRegisterSessionNotification (which requires that you make a matching call to WTSUnRegisterSessionNotification when you no longer need notification). Both of these APIs are declared in the WtsApi32.h header in the platform SDK.
When the WM_WTSESSION_CHANGE message arrives, there is a status code in the wParam indicating what type of change is happening. The two changes we care about are WTS_SESSION_LOCK and WTS_SESSION_UNLOCK to represent locking and unlocking the machine.
All of the APIs involved are relatively simple, and creating P/Invoke signatures for them is easy. Once that work is done, creating a simple base class that is capable of receiving lock and unlock notifications is very straightforward.
This class exposes three interesting protected members to its derived classes. The ReceivingLockNotifications property is a flag that indicates that the form is receiving lock and unlock messages. The most likely reasons this would be set to false is if the form is not running on Windows XP or higher, or the form is disposed. OnSessionLock and OnSessionUnlock are methods called when the user locks and unlocks the current Windows session.
Control flow through the form is pretty basic. In the OnHandleCreated method, we check to see if the user is running on XP or higher, and if so, call out to WTSRegisterSessionNotification, requesting notifications only for the current session. This call needs to be done in OnHandleCreated so that there is an HWND associated with the form, since that HWND is required to register for notifications.
The WndProc is overridden so that we can check to see if we've gotten any WM_WTSESSION_CHANGE messages. If we have, and their wParam is either lock or unlock, we call the appropriate virtual function. The rest of the messages just get processed by the default WndProc implementation.
Finally, in the form's Dispose method, we check to see if we ever registered for notifications, and if so unregister.
Using this class is very easy. Here's a tiny sample that just keeps track of the lock and unlock times in a text box:
Running this code yields results similar to: