From 8764348c51e1d68ef77e0360f64b02ed62ca7789 Mon Sep 17 00:00:00 2001
From: Evgeny Gryaznov <inspirer@users.sourceforge.net>
Date: Thu, 27 Mar 2008 21:30:36 +0000
Subject: [PATCH] disconnect on computer lock

git-svn-id: https://webim.svn.sourceforge.net/svnroot/webim/trunk@48 c66351dc-e62f-0410-b875-e3a5c0b9693f
---
 .../WebIMTray/LockNotificationForm.cs         | 98 +++++++++++++++++++
 src/webimtray/WebIMTray/Main.cs               | 18 +++-
 src/webimtray/WebIMTray/Main.resx             | 54 +++++-----
 src/webimtray/WebIMTray/Options.cs            |  9 ++
 .../OptionsConnectionPanel.Designer.cs        |  2 +-
 .../options/OptionsConnectionPanel.cs         |  7 ++
 src/webimtray/WebIMTray/webImTray.csproj      |  5 +-
 7 files changed, 164 insertions(+), 29 deletions(-)
 create mode 100644 src/webimtray/WebIMTray/LockNotificationForm.cs

diff --git a/src/webimtray/WebIMTray/LockNotificationForm.cs b/src/webimtray/WebIMTray/LockNotificationForm.cs
new file mode 100644
index 00000000..a38535d5
--- /dev/null
+++ b/src/webimtray/WebIMTray/LockNotificationForm.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Drawing;
+using System.Runtime.InteropServices;
+using System.Windows.Forms;
+
+namespace webImTray {
+
+    /// <summary>
+    /// Base class for a form that wants to be notified of Windows
+    /// session lock / unlock events
+    /// </summary>
+    public abstract class LockNotificationForm : Form {
+        // from wtsapi32.h
+        private const int NotifyForThisSession = 0;
+
+        // from winuser.h
+        private const int SessionChangeMessage = 0x02B1;
+        private const int SessionLockParam = 0x7;
+        private const int SessionUnlockParam = 0x8;
+
+        [DllImport("wtsapi32.dll")]
+        private static extern bool WTSRegisterSessionNotification(IntPtr hWnd, int dwFlags);
+
+        [DllImport("wtsapi32.dll")]
+        private static extern bool WTSUnRegisterSessionNotification(IntPtr hWnd);
+
+        // flag to indicate if we've registered for notifications or not
+        private bool registered = false;
+
+        /// <summary>
+        /// Is this form receiving lock / unlock notifications
+        /// </summary>
+        protected bool ReceivingLockNotifications {
+            get { return registered; }
+        }
+
+        /// <summary>
+        /// Unregister for event notifications
+        /// </summary>
+        protected override void Dispose(bool disposing) {
+            if (registered) {
+                WTSUnRegisterSessionNotification(Handle);
+                registered = false;
+            }
+
+            base.Dispose(disposing);
+            return;
+        }
+
+        /// <summary>
+        /// Register for event notifications
+        /// </summary>
+        protected override void OnHandleCreated(EventArgs e) {
+            base.OnHandleCreated(e);
+
+            // WtsRegisterSessionNotification requires Windows XP or higher
+            bool haveXp = Environment.OSVersion.Platform == PlatformID.Win32NT &&
+                                (Environment.OSVersion.Version.Major > 5 ||
+                                    (Environment.OSVersion.Version.Major == 5 &&
+                                     Environment.OSVersion.Version.Minor >= 1));
+
+            if (haveXp)
+                registered = WTSRegisterSessionNotification(Handle, NotifyForThisSession);
+
+            return;
+        }
+
+        /// <summary>
+        /// The windows session has been locked
+        /// </summary>
+        protected virtual void OnSessionLock() {
+            return;
+        }
+
+        /// <summary>
+        /// The windows session has been unlocked
+        /// </summary>
+        protected virtual void OnSessionUnlock() {
+            return;
+        }
+
+        /// <summary>
+        /// Process windows messages
+        /// </summary>
+        protected override void WndProc(ref Message m) {
+            // check for session change notifications
+            if (m.Msg == SessionChangeMessage) {
+                if (m.WParam.ToInt32() == SessionLockParam)
+                    OnSessionLock();
+                else if (m.WParam.ToInt32() == SessionUnlockParam)
+                    OnSessionUnlock();
+            }
+
+            base.WndProc(ref m);
+            return;
+        }
+    }
+}
diff --git a/src/webimtray/WebIMTray/Main.cs b/src/webimtray/WebIMTray/Main.cs
index fa614cdc..11bb2084 100644
--- a/src/webimtray/WebIMTray/Main.cs
+++ b/src/webimtray/WebIMTray/Main.cs
@@ -9,7 +9,7 @@ using System.Data;
 
 namespace webImTray {
 
-    public partial class MainWindow : System.Windows.Forms.Form {
+    public partial class MainWindow : LockNotificationForm {
 
         public MainWindow() {
             InitializeComponent();
@@ -46,6 +46,10 @@ namespace webImTray {
 #endif
         }
 
+        void navigateBlank() {
+            webBrowser1.Navigate("about:blank");
+        }
+
         private void showWindow() {
             this.Visible = true;
             this.Activate();
@@ -146,5 +150,17 @@ namespace webImTray {
         private void toolHideWindow_Click(object sender, EventArgs e) {
             hideWindow();
         }
+
+        protected override void OnSessionLock() {
+            if (Options.DisconnectOnLock) {
+                navigateBlank();
+            }
+        }
+
+        protected override void OnSessionUnlock() {
+            if (Options.DisconnectOnLock) {
+                navigateThere();
+            }
+        }
     }
 }
diff --git a/src/webimtray/WebIMTray/Main.resx b/src/webimtray/WebIMTray/Main.resx
index aff1f91d..8965f0bd 100644
--- a/src/webimtray/WebIMTray/Main.resx
+++ b/src/webimtray/WebIMTray/Main.resx
@@ -127,10 +127,10 @@
   <data name="optionsToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAIVJREFUOE/dk0EO
-        gCAMBPlgv+l/DBcTH4O2WrLCFi56kaQJgXbYbUNKXy4RKSz2bT3PF4vwfS3MOdO4oAOAF48hN4BJ1Jdn
-        kKpAE321RRHkYcEBmKxABnO12rhOgV9WOQ3Eodh1mwJawGK0hftubDNAqygEoAU2GWbBYD9REH0adv76
-        5z0AIQLwRor4ZGsAAAAASUVORK5CYII=
+        YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAASdAAA
+        EnQB3mYfeAAAAIVJREFUOE/dk0EOgCAMBPlgv+l/DBcTH4O2WrLCFi56kaQJgXbYbUNKXy4RKSz2bT3P
+        F4vwfS3MOdO4oAOAF48hN4BJ1JdnkKpAE321RRHkYcEBmKxABnO12rhOgV9WOQ3Eodh1mwJawGK0hftu
+        bDNAqygEoAU2GWbBYD9REH0adv765z0AIQLwRor4ZGsAAAAASUVORK5CYII=
 </value>
   </data>
   <data name="notifyIcon.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@@ -167,38 +167,40 @@
   <data name="toolNavigate.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAY9JREFUOE9jYBh0
-        wHTS1/+mEz7/N+n/8B/mOOOeN/+Ne17/N+59AxfD6nCzqb//m035+d908rf/JhM+/jfpew/WYNz9EmyA
-        UddLIH6B2xCwAVN//TedBDQA6AKQzSADDNsf/zdse/TfsPXBf4PW+3gMmPzjv+nEL0Cb34FtAmkEGaDf
-        dPu/fsON/3r11/7r1V3B7w2wUzuf/TdoQdikW3Pxv07V2f86lWfwa6ZKjOrWXAbadu6/dsUpuG2ahfv/
-        axTs/a+Rvxu/CzRLTv7XLD7+X6PoCFDDgf/qeXvhGtSytv1Xy9r6Xy1zC3ZDVLP2/lfJ2vNfJXPnf1Ug
-        Vknf9l85bct/5dRNcA3KKRv+g7BK6gZUQxQSN/1XSNj4XyF+PRjLx68D0mv/y8euBmOFuFVwDQpxQH78
-        6v+KCWsQhkhHLP8vHQbEoUuBNBCHL/0vA6RlwpcAMYSGBTCILxux7L9c1HKEARIBC/5L+IPwvP8SASA8
-        H4ID5/+XDASKA9kwA0B8yaCF/6VDFtEhSolJFwDyA+nk71GvlAAAAABJRU5ErkJggg==
+        YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAASdAAA
+        EnQB3mYfeAAAAY9JREFUOE9jYBh0wHTS1/+mEz7/N+n/8B/mOOOeN/+Ne17/N+59AxfD6nCzqb//m035
+        +d908rf/JhM+/jfpew/WYNz9EmyAUddLIH6B2xCwAVN//TedBDQA6AKQzSADDNsf/zdse/TfsPXBf4PW
+        +3gMmPzjv+nEL0Cb34FtAmkEGaDfdPu/fsON/3r11/7r1V3B7w2wUzuf/TdoQdikW3Pxv07V2f86lWfw
+        a6ZKjOrWXAbadu6/dsUpuG2ahfv/axTs/a+Rvxu/CzRLTv7XLD7+X6PoCFDDgf/qeXvhGtSytv1Xy9r6
+        Xy1zC3ZDVLP2/lfJ2vNfJXPnf1UgVknf9l85bct/5dRNcA3KKRv+g7BK6gZUQxQSN/1XSNj4XyF+PRjL
+        x68D0mv/y8euBmOFuFVwDQpxQH786v+KCWsQhkhHLP8vHQbEoUuBNBCHL/0vA6RlwpcAMYSGBTCILxux
+        7L9c1HKEARIBC/5L+IPwvP8SASA8H4ID5/+XDASKA9kwA0B8yaCF/6VDFtEhSolJFwDyA+nk71GvlAAA
+        AABJRU5ErkJggg==
 </value>
   </data>
   <data name="toolOptions.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAIVJREFUOE/dk0EO
-        gCAMBPlgv+l/DBcTH4O2WrLCFi56kaQJgXbYbUNKXy4RKSz2bT3PF4vwfS3MOdO4oAOAF48hN4BJ1Jdn
-        kKpAE321RRHkYcEBmKxABnO12rhOgV9WOQ3Eodh1mwJawGK0hftubDNAqygEoAU2GWbBYD9REH0adv76
-        5z0AIQLwRor4ZGsAAAAASUVORK5CYII=
+        YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAASdAAA
+        EnQB3mYfeAAAAIVJREFUOE/dk0EOgCAMBPlgv+l/DBcTH4O2WrLCFi56kaQJgXbYbUNKXy4RKSz2bT3P
+        F4vwfS3MOdO4oAOAF48hN4BJ1JdnkKpAE321RRHkYcEBmKxABnO12rhOgV9WOQ3Eodh1mwJawGK0hftu
+        bDNAqygEoAU2GWbBYD9REH0adv765z0AIQLwRor4ZGsAAAAASUVORK5CYII=
 </value>
   </data>
   <data name="toolHideWindow.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
         iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
-        YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAgxJREFUOE+lkvtL
-        U2EYx+0PEbtpFwnBKPGKiJImGP0gYhIYs1E5GF5gIxkpA00JRSmMEF0ohMh+GaRWYlqabMVcNdS2QpaI
-        VqiDIYhk397vA6fXhCjyhYdzeM/5fp7vczkAdeL2cwho7v/wWzT1zcN+Pwhr51uY2/y41PQaF+wzKKiZ
-        QvaN58g0jyLd5KEUcQbg+84P/Cm2tncQjW3j68YWIqubCC3FcOJc478BAuGoZM6zvoRnakXEruEIjhc4
-        /g5gZop9c+voGAyLbQIfeBZxLL9BA1jzXvuGbWamuKh+GmmVbswE19A59FEBbmoAG7YbsLtm2mZmiml9
-        cvabNDwpz6YB7LYBoMXCumkJr7LOmnnHzBQ/9X2Bo2cOibm1GsBREbAQiYmw/8lnuCeWkVzcgnZlnw1j
-        3HV/wuNXK6i/9x5Hc6wawDlTXHbLJ+LZUBQPRyKwdQdxutwl1h+NLXHh5Ht1ewBHsiwawCW57HyDAfWR
-        dvl0uhZQ1eqX8aVc7EKLqrum651ATLf9OJx5XQM4KmY0xPzZ0hFAiQJnXB0WwME0E3IsL5B17ZlADqWb
-        NYDrOepdlcysmTWWOrxqbceRWtaLk0VO1XW72D5Vckd2gMBfq8zdpmUG62NJvKM4+XyziDk24xmfWoGE
-        s1c0gHPmbrPTpHNJKOCo2G1mZs20zcwUJ5yp1AB5+8/zEwgF5GMVDxh4AAAAAElFTkSuQmCC
+        YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAASdAAA
+        EnQB3mYfeAAAAgxJREFUOE+lkvtLU2EYx+0PEbtpFwnBKPGKiJImGP0gYhIYs1E5GF5gIxkpA00JRSmM
+        EF0ohMh+GaRWYlqabMVcNdS2QpaIVqiDIYhk397vA6fXhCjyhYdzeM/5fp7vczkAdeL2cwho7v/wWzT1
+        zcN+Pwhr51uY2/y41PQaF+wzKKiZQvaN58g0jyLd5KEUcQbg+84P/Cm2tncQjW3j68YWIqubCC3FcOJc
+        478BAuGoZM6zvoRnakXEruEIjhc4/g5gZop9c+voGAyLbQIfeBZxLL9BA1jzXvuGbWamuKh+GmmVbswE
+        19A59FEBbmoAG7YbsLtm2mZmiml9cvabNDwpz6YB7LYBoMXCumkJr7LOmnnHzBQ/9X2Bo2cOibm1GsBR
+        EbAQiYmw/8lnuCeWkVzcgnZlnw1j3HV/wuNXK6i/9x5Hc6wawDlTXHbLJ+LZUBQPRyKwdQdxutwl1h+N
+        LXHh5Ht1ewBHsiwawCW57HyDAfWRdvl0uhZQ1eqX8aVc7EKLqrum651ATLf9OJx5XQM4KmY0xPzZ0hFA
+        iQJnXB0WwME0E3IsL5B17ZlADqWbNYDrOepdlcysmTWWOrxqbceRWtaLk0VO1XW72D5Vckd2gMBfq8zd
+        pmUG62NJvKM4+XyziDk24xmfWoGEs1c0gHPmbrPTpHNJKOCo2G1mZs20zcwUJ5yp1AB5+8/zEwgF5GMV
+        Dxh4AAAAAElFTkSuQmCC
 </value>
   </data>
   <metadata name="reloadPageTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
diff --git a/src/webimtray/WebIMTray/Options.cs b/src/webimtray/WebIMTray/Options.cs
index d7ded258..45ce1805 100644
--- a/src/webimtray/WebIMTray/Options.cs
+++ b/src/webimtray/WebIMTray/Options.cs
@@ -38,6 +38,15 @@ namespace webImTray {
             }
         }
 
+        public static bool DisconnectOnLock {
+            get {
+                return Application.UserAppDataRegistry.GetValue("disconnectonlock", "true").ToString().ToLower().Equals("true");
+            }
+            set {
+                Application.UserAppDataRegistry.SetValue("disconnectonlock", value.ToString());
+            }
+        }
+
         public static bool ShowInTaskBar {
             get {
                 return Application.UserAppDataRegistry.GetValue("showintaskbar", "false").ToString().ToLower().Equals("true");
diff --git a/src/webimtray/WebIMTray/options/OptionsConnectionPanel.Designer.cs b/src/webimtray/WebIMTray/options/OptionsConnectionPanel.Designer.cs
index fe620d95..98536eb6 100644
--- a/src/webimtray/WebIMTray/options/OptionsConnectionPanel.Designer.cs
+++ b/src/webimtray/WebIMTray/options/OptionsConnectionPanel.Designer.cs
@@ -144,7 +144,6 @@ namespace webImTray {
             // autoDisconnect
             // 
             this.autoDisconnect.AutoSize = true;
-            this.autoDisconnect.Enabled = false;
             this.autoDisconnect.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
             this.autoDisconnect.Location = new System.Drawing.Point(23, 96);
             this.autoDisconnect.Margin = new System.Windows.Forms.Padding(4);
@@ -153,6 +152,7 @@ namespace webImTray {
             this.autoDisconnect.TabIndex = 3;
             this.autoDisconnect.Text = "Become idle if the computer is locked";
             this.autoDisconnect.UseVisualStyleBackColor = true;
+            this.autoDisconnect.CheckedChanged += new System.EventHandler(this.autoDisconnect_CheckedChanged);
             // 
             // groupBox2
             // 
diff --git a/src/webimtray/WebIMTray/options/OptionsConnectionPanel.cs b/src/webimtray/WebIMTray/options/OptionsConnectionPanel.cs
index b6a9a14c..557944e0 100644
--- a/src/webimtray/WebIMTray/options/OptionsConnectionPanel.cs
+++ b/src/webimtray/WebIMTray/options/OptionsConnectionPanel.cs
@@ -17,6 +17,7 @@ namespace webImTray {
         void OptionsPanel.apply() {
             if (modified) {
                 Options.WebIMServer = webimServer.Text;
+                Options.DisconnectOnLock = autoDisconnect.Checked;
                 if (forceRefresh.Checked) {
                     Options.ForceRefreshTime = forceRefreshTime.Value;
                 } else {
@@ -27,6 +28,7 @@ namespace webImTray {
 
         void OptionsPanel.initialize() {
             webimServer.Text = Options.WebIMServer;
+            autoDisconnect.Checked = Options.DisconnectOnLock;
 
             decimal refreshTime = Options.ForceRefreshTime;
             forceRefreshTime.Enabled = forceRefresh.Checked = refreshTime != 0;
@@ -60,5 +62,10 @@ namespace webImTray {
         private void showUserPropertiesOnline(object sender, LinkLabelLinkClickedEventArgs e) {
             System.Diagnostics.Process.Start(Options.WebIMServer + Options.SETTINGS_PAGE);
         }
+
+        private void autoDisconnect_CheckedChanged(object sender, EventArgs e) {
+            modified = true;
+            PanelModified.Invoke();
+        }
     }
 }
diff --git a/src/webimtray/WebIMTray/webImTray.csproj b/src/webimtray/WebIMTray/webImTray.csproj
index 00acdc13..ea9bfd15 100644
--- a/src/webimtray/WebIMTray/webImTray.csproj
+++ b/src/webimtray/WebIMTray/webImTray.csproj
@@ -91,6 +91,9 @@
   </ItemGroup>
   <ItemGroup>
     <Content Include="App.ico" />
+    <Compile Include="LockNotificationForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
     <Compile Include="Options.cs" />
     <Compile Include="options\About.cs">
       <SubType>UserControl</SubType>
@@ -165,4 +168,4 @@
     <PostBuildEvent>
     </PostBuildEvent>
   </PropertyGroup>
-</Project>
+</Project>
\ No newline at end of file