123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- using System;
- using System.Threading;
- using System.Windows.Forms;
- namespace PaintDotNet.SystemLayer
- {
- /// <summary>
- /// Encapsulates information and events about the current user session.
- /// This relates to Terminal Services in Windows.
- /// </summary>
- public static class UserSessions
- {
- private static OurControl messageControl;
- private static bool lastRemoteSessionValue;
- private static EventHandler sessionChanged;
- private static int sessionChangedCount;
- private static object lockObject = new object();
- private sealed class OurControl
- : Control
- {
- public event EventHandler WmWtSessionChange;
- private void OnWmWtSessionChange()
- {
- if (WmWtSessionChange != null)
- {
- WmWtSessionChange(this, EventArgs.Empty);
- }
- }
- protected override void WndProc(ref Message m)
- {
- switch (m.Msg)
- {
- case NativeConstants.WM_WTSSESSION_CHANGE:
- OnWmWtSessionChange();
- break;
- default:
- base.WndProc(ref m);
- break;
- }
- }
- }
- private static void OnSessionChanged()
- {
- if (sessionChanged != null)
- {
- sessionChanged(null, EventArgs.Empty);
- }
- }
- /// <summary>
- /// Occurs when the user changes between sessions. This event will only be
- /// raised when the value returned by IsRemote() changes.
- /// </summary>
- /// <remarks>
- /// For example, if the user is currently logged in at the console, and then
- /// switches to a remote session (they use Remote Desktop from another computer),
- /// then this event will be raised.
- /// Note to implementors: This may be implemented as a no-op.
- /// </remarks>
- public static event EventHandler SessionChanged
- {
- add
- {
- lock (lockObject)
- {
- sessionChanged += value;
- ++sessionChangedCount;
- if (sessionChangedCount == 1)
- {
- messageControl = new OurControl();
- messageControl.CreateControl(); // force the HWND to be created
- messageControl.WmWtSessionChange += new EventHandler(SessionStrobeHandler);
- SafeNativeMethods.WTSRegisterSessionNotification(messageControl.Handle, NativeConstants.NOTIFY_FOR_ALL_SESSIONS);
- lastRemoteSessionValue = IsRemote;
- }
- }
- }
- remove
- {
- lock (lockObject)
- {
- sessionChanged -= value;
- int decremented = Interlocked.Decrement(ref sessionChangedCount);
- if (decremented == 0)
- {
- try
- {
- SafeNativeMethods.WTSUnRegisterSessionNotification(messageControl.Handle);
- }
- catch (EntryPointNotFoundException)
- {
- }
- messageControl.Dispose();
- messageControl = null;
- }
- }
- }
- }
- /// <summary>
- /// Determines whether the user is running within a remoted session (Terminal Server, Remote Desktop).
- /// </summary>
- /// <returns>
- /// <b>true</b> if we're running in a remote session, <b>false</b> otherwise.
- /// </returns>
- /// <remarks>
- /// You can use this to optimize the presentation of visual elements. Remote sessions
- /// are often bandwidth limited and less suitable for complex drawing.
- /// Note to implementors: This may be implemented as a no op; in this case, always return false.
- /// </remarks>
- public static bool IsRemote
- {
- get
- {
- return 0 != SafeNativeMethods.GetSystemMetrics(NativeConstants.SM_REMOTESESSION);
- }
- }
- private static void SessionStrobeHandler(object sender, EventArgs e)
- {
- if (IsRemote != lastRemoteSessionValue)
- {
- lastRemoteSessionValue = IsRemote;
- OnSessionChanged();
- }
- }
- }
- }
|