LockScreen
<Window x:Class="XXX.Client.LockScreenView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" Title="ClearLid" Height="484" Width="791" WindowState="Maximized" WindowStartupLocation="CenterScreen" ShowInTaskbar="False" Visibility="Visible" Background="Transparent" WindowStyle="None" SizeChanged="WindowSizeChanged"> <Grid Name="MainGrid"> <Grid.RowDefinitions> <RowDefinition Height="15*"/> <RowDefinition Height="35*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Canvas Grid.ColumnSpan="2" HorizontalAlignment="Center" Height="140" Margin="182,0,183,0" Grid.Row="1" VerticalAlignment="Top" Width="350" Name="MainCanvas" > <TextBlock Height="23" Canvas.Left="92" TextWrapping="Wrap" Text="User Name" Canvas.Top="25" Width="99" Foreground="White"/> <TextBlock Height="23" Canvas.Left="191" Canvas.Top="22" Width="153" Name="txtUserName" Foreground="White"/> <TextBlock Height="20" Canvas.Left="92" TextWrapping="Wrap" Text="Password" Canvas.Top="53" Width="75" Foreground="White"/> <PasswordBox Height="20" Canvas.Left="191" Canvas.Top="53" Width="153" KeyboardNavigation.TabIndex="0" Name="txtPassword"/> <Button Content="Switch User" Height="24" Canvas.Left="185" Canvas.Top="90" Width="75" Foreground="White" KeyboardNavigation.TabIndex="2" Click="OnLogOff" /> <Button Content="Login" Height="24" Canvas.Left="268" Canvas.Top="90" Width="75" Foreground="White" IsDefault="True" KeyboardNavigation.TabIndex="1" Name="btnLogin" Click="OnLogin" /> </Canvas> </Grid> </Window>
public partial class LockScreenView : Window { public LockScreenView() { InitializeComponent(); // Create canvas border m_canvasBorder = new Rectangle(); m_canvasBorder.Stroke = System.Windows.Media.Brushes.Red; m_canvasBorder.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; m_canvasBorder.VerticalAlignment = System.Windows.VerticalAlignment.Top; m_canvasBorder.RadiusX = m_canvasBorder.RadiusY = 5; Grid.SetColumnSpan(m_canvasBorder, 2); Grid.SetRow(m_canvasBorder, 1); MainGrid.Children.Add(m_canvasBorder); this.m_isEnableDWM = this.CheckDWM(); this.InitializeIOCtrl(); this.EnableLockScreen = true; FocusManager.SetFocusedElement(this, this.txtPassword); } private void OnLogin(object sender, RoutedEventArgs e) { if (AppClient.Instance.XXXService.VerifyUser(AppClient.Instance.ClientID, this.txtUserName.Text, this.txtPassword.Password)) { AppClient.Instance.UserContext.CurrentLockCount = AppClient.Instance.UserContext.AutoLockCount; AppClient.Instance.UserMode = UserMode.None; this.EnableLockScreen = false; this.Close(); } else { txtPassword.Clear(); } } private void OnLogOff(object sender, RoutedEventArgs e) { } protected override void OnClosed(EventArgs e) { if (this.m_event != null) this.m_event.Close(); if (this.m_file != null) this.m_file.Close(); base.OnClosed(e); } private void WindowSizeChanged(object sender, SizeChangedEventArgs e) { var left = this.MainGrid.ColumnDefinitions[0].ActualWidth - this.MainCanvas.ActualWidth / 2; var top = this.MainGrid.RowDefinitions[0].ActualHeight; var rect = new System.Drawing.Rectangle((int)left, (int)top, (int)this.MainCanvas.Width, (int)this.MainCanvas.Height); // Draw border m_canvasBorder.Width = rect.Width; m_canvasBorder.Height = rect.Height; m_canvasBorder.Margin = new Thickness(181, 0, 182, 0); if (!this.m_isEnableDWM) return; // Obtain the window handle for WPF application IntPtr mainWindowPtr = new WindowInteropHelper(this).Handle; HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr); mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0); System.Drawing.Graphics desktop = System.Drawing.Graphics.FromHwnd(mainWindowPtr); NativeMethods.DWM_BLURBEHIND blurBehind; blurBehind.dwFlags = NativeMethods.DWM_BB.Enable | NativeMethods.DWM_BB.BlurRegion; blurBehind.fEnable = true; blurBehind.fTransitionOnMaximized = false; blurBehind.hRgnBlur = IntPtr.Zero; var rgn = RoundedRectangle.CreateRegion(rect); blurBehind.hRgnBlur = rgn.GetHrgn(desktop); NativeMethods.DwmEnableBlurBehindWindow(mainWindowSrc.Handle, ref blurBehind); rgn.Dispose(); } private void InitializeIOCtrl() { var file = NativeMethods.CreateFile(NativeMethods.DOS_DEVICE_NAME, NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE, 0, IntPtr.Zero, NativeMethods.OPEN_EXISTING, 0, IntPtr.Zero); m_file = new SafeFileHandle(file, true); if (m_file.IsInvalid == false) m_event = new ManualResetEvent(false); } private bool EnableLockScreen { set { if (value != m_isEnableLS) { if (value == true) enableToolStripMenuItem_Click(this, new EventArgs()); else disableToolStripMenuItem_Click(this, new EventArgs()); m_isEnableLS = value; } } } private void enableToolStripMenuItem_Click(object sender, EventArgs e) { if (m_file.IsInvalid == false) { uint bytesReturned = 0; if (m_isSetFilterData == false) { unsafe { var ioCtrl = NativeMethods.CTL_CODE( NativeMethods.FILE_DEVICE_KEYBOARD_FILTER, NativeMethods.IOCTL_KEYBOARD_FILTER_SET_EVENT, NativeMethods.METHOD_BUFFERED, NativeMethods.FILE_ANY_ACCESS ); int handle = m_event.SafeWaitHandle.DangerousGetHandle().ToInt32(); int* pHandle = &handle; var ret = NativeMethods.DeviceIoControl(m_file.DangerousGetHandle(), ioCtrl, (IntPtr)(pHandle), 4, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero); List<ushort[]> listFd = new List<ushort[]>(); listFd.Add(NativeMethods.GetSAS_L()); listFd.Add(NativeMethods.GetSAS_R()); listFd.Add(NativeMethods.GetTaskSwitch()); listFd.Add(NativeMethods.GetTaskSwitch3D_L()); listFd.Add(NativeMethods.GetTaskSwitch3D_R()); listFd.Add(NativeMethods.GetWin_L()); listFd.Add(NativeMethods.GetWin_R()); int size = listFd.Count * FILTER_DATA_LENGTH; ushort* fd = stackalloc ushort[size]; ushort* tmp = fd; for (int i = 0; i < listFd.Count; ++i) { for (int j = 0; j < FILTER_DATA_LENGTH; ++j, ++tmp) { *tmp = listFd[i][j]; } } ioCtrl = NativeMethods.CTL_CODE( NativeMethods.FILE_DEVICE_KEYBOARD_FILTER, NativeMethods.IOCTL_KEYBOARD_FILTER_SET_KEY, NativeMethods.METHOD_BUFFERED, NativeMethods.FILE_ANY_ACCESS ); ret = NativeMethods.DeviceIoControl(m_file.DangerousGetHandle(), ioCtrl, (IntPtr)(fd), (uint)size * 2, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero); m_isSetFilterData = true; } } m_event.Set(); } } private void disableToolStripMenuItem_Click(object sender, EventArgs e) { if (m_file.IsInvalid == false) { m_event.Reset(); } } private bool CheckDWM() { if (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6) { if (NativeMethods.DwmIsCompositionEnabled() == false) return false; else return true; } else return false; } private SafeFileHandle m_file = null; private ManualResetEvent m_event = null; private bool m_isSetFilterData = false; // Indicate if filter data is sent to kernel private bool m_isEnableLS = false; private const int FILTER_DATA_LENGTH = 4; private bool m_isEnableDWM = false; private Rectangle m_canvasBorder; } internal class NativeMethods { [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern IntPtr CreateFile( string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool DeviceIoControl( IntPtr hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer, uint nOutBufferSize, out uint lpBytesReturned, IntPtr lpOverlapped); [DllImport("dwmapi.dll", PreserveSig = false)] public static extern bool DwmIsCompositionEnabled(); [DllImport("dwmapi.dll")] public static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind); public static uint CTL_CODE(uint DeviceType, uint Function, uint Method, uint Access) { return ((DeviceType << 16) | (Access << 14) | (Function << 2) | Method); } public static ushort[] GetSAS_L() { var fd = new ushort[FILTER_DATA_LENGTH]; fd[0] = KEY_CTRL; fd[1] = KEY_DEL; fd[2] = KEY_ALT; fd[3] = KEY_NUM; return fd; } public static ushort[] GetSAS_R() { var fd = new ushort[FILTER_DATA_LENGTH]; fd[0] = KEY_CTRL; fd[1] = KEY_DEL; fd[2] = KEY_ALT; fd[3] = KEY_NUM_PERIOD; return fd; } public static ushort[] GetTaskSwitch() { var fd = new ushort[FILTER_DATA_LENGTH]; fd[0] = KEY_ALT; fd[1] = KEY_TAB; return fd; } public static ushort[] GetWin_L() { var fd = new ushort[FILTER_DATA_LENGTH]; fd[0] = KEY_LWIN; return fd; } public static ushort[] GetWin_R() { var fd = new ushort[FILTER_DATA_LENGTH]; fd[0] = KEY_RWIN; return fd; } public static ushort[] GetTaskSwitch3D_L() { var fd = new ushort[FILTER_DATA_LENGTH]; fd[0] = KEY_LWIN; fd[1] = KEY_TAB; return fd; } public static ushort[] GetTaskSwitch3D_R() { var fd = new ushort[FILTER_DATA_LENGTH]; fd[0] = KEY_RWIN; fd[1] = KEY_TAB; return fd; } [Flags] public enum DWM_BB { Enable = 1, BlurRegion = 2, TransitionMaximized = 4 } [Flags] public enum SendMessageTimeoutFlags { SMTO_NORMAL = 0x0, SMTO_BLOCK = 0x1, SMTO_ABORTIFHUNG = 0x2, SMTO_NOTIMEOUTIFNOTHUNG = 0x8 } [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Right; public int Top; public int Bottom; }; [StructLayout(LayoutKind.Sequential)] public struct DWM_BLURBEHIND { public DWM_BB dwFlags; public bool fEnable; public IntPtr hRgnBlur; public bool fTransitionOnMaximized; } public const short FILE_ATTRIBUTE_NORMAL = 0x80; public const short INVALID_HANDLE_VALUE = -1; public const uint GENERIC_READ = 0x80000000; public const uint GENERIC_WRITE = 0x40000000; public const uint CREATE_NEW = 1; public const uint CREATE_ALWAYS = 2; public const uint OPEN_EXISTING = 3; public const uint METHOD_BUFFERED = 0; public const uint METHOD_IN_DIRECT = 1; public const uint METHOD_OUT_DIRECT = 2; public const uint METHOD_NEITHER = 3; public const uint FILE_ANY_ACCESS = 0; public const uint FILE_READ_ACCESS = 0x0001; public const uint FILE_WRITE_ACCESS = 0x0002; public const uint FILE_DEVICE_KEYBOARD_FILTER = 0x8000; public const uint IOCTL_KEYBOARD_FILTER_SET_EVENT = 1; public const uint IOCTL_KEYBOARD_FILTER_CLEAR_EVENT = 2; public const uint IOCTL_KEYBOARD_FILTER_SET_KEY = 4; public const string DOS_DEVICE_NAME = "\\\\.\\aKbFilter"; public const int ERROR_TIMEOUT = 1460; public const int ERROR_INVALID_WINDOW_HANDLE = 1400; public const int ERROR_SUCCESS = 0; public const int ERROR_LOGIN_FAIL = 1; public const int ERROR_INVALID_LOGIN = 2; public const int ERROR_INVALID_PWD = 3; public const int ERROR_INVALID_USERNAME = 4; public const int MAX_NAME_PWD_LENGTH = 32; public const int MAX_TIME_OUT = 2000; public const int MAX_PATH = 260; private const int FILTER_DATA_LENGTH = 4; private const ushort KEY_CTRL = 0x1D; private const ushort KEY_ALT = 0x38; private const ushort KEY_DEL = 0x53; private const ushort KEY_NUM = 0x2A; private const ushort KEY_TAB = 0x0F; private const ushort KEY_NUM_PERIOD = 0x53; private const ushort KEY_LWIN = 0x5B; private const ushort KEY_RWIN = 0x5C; } public abstract class RoundedRectangle { public enum RectangleCorners { None = 0, TopLeft = 1, TopRight = 2, BottomLeft = 4, BottomRight = 8, All = TopLeft | TopRight | BottomLeft | BottomRight } public static GraphicsPath Create(int x, int y, int width, int height, int radius, RectangleCorners corners) { int xw = x + width; int yh = y + height; int xwr = xw - radius; int yhr = yh - radius; int xr = x + radius; int yr = y + radius; int r2 = radius * 2; int xwr2 = xw - r2; int yhr2 = yh - r2; GraphicsPath p = new GraphicsPath(); p.StartFigure(); //Top Left Corner if ((RectangleCorners.TopLeft & corners) == RectangleCorners.TopLeft) { p.AddArc(x, y, r2, r2, 180, 90); } else { p.AddLine(x, yr, x, y); p.AddLine(x, y, xr, y); } //Top Edge p.AddLine(xr, y, xwr, y); //Top Right Corner if ((RectangleCorners.TopRight & corners) == RectangleCorners.TopRight) { p.AddArc(xwr2, y, r2, r2, 270, 90); } else { p.AddLine(xwr, y, xw, y); p.AddLine(xw, y, xw, yr); } //Right Edge p.AddLine(xw, yr, xw, yhr); //Bottom Right Corner if ((RectangleCorners.BottomRight & corners) == RectangleCorners.BottomRight) { p.AddArc(xwr2, yhr2, r2, r2, 0, 90); } else { p.AddLine(xw, yhr, xw, yh); p.AddLine(xw, yh, xwr, yh); } //Bottom Edge p.AddLine(xwr, yh, xr, yh); //Bottom Left Corner if ((RectangleCorners.BottomLeft & corners) == RectangleCorners.BottomLeft) { p.AddArc(x, yhr2, r2, r2, 90, 90); } else { p.AddLine(xr, yh, x, yh); p.AddLine(x, yh, x, yhr); } //Left Edge p.AddLine(x, yhr, x, yr); p.CloseFigure(); return p; } public static GraphicsPath Create(System.Drawing.Rectangle rect, int radius, RectangleCorners c) { return Create(rect.X, rect.Y, rect.Width, rect.Height, radius, c); } public static GraphicsPath Create(int x, int y, int width, int height, int radius) { return Create(x, y, width, height, radius, RectangleCorners.All); } public static GraphicsPath Create(System.Drawing.Rectangle rect, int radius) { return Create(rect.X, rect.Y, rect.Width, rect.Height, radius); } public static GraphicsPath Create(int x, int y, int width, int height) { return Create(x, y, width, height, 5); } public static GraphicsPath Create(System.Drawing.Rectangle rect) { return Create(rect.X, rect.Y, rect.Width, rect.Height); } public static System.Drawing.Region CreateRegion(System.Drawing.Rectangle rect) { return new System.Drawing.Region(Create(rect.X, rect.Y, rect.Width, rect.Height)); } }
WindowCollection wins = Application.Current.Windows; foreach (Window win in wins) { if (win is XXX.Client.MainView) continue; win.Close(); } AppClient.Instance.UserMode = UserMode.Lock; LockScreenViewModel vm = new LockScreenViewModel(); WindowManager windowmanager = new WindowManager(); windowmanager.ShowDialog(vm);
AppClient.Instance.UserContext.CurrentLockCount = AppClient.Instance.UserContext.AutoLockCount; if (this._view != null) this._view.MouseMove += new MouseEventHandler(uc_MouseMove); if (autolocktimer == null) { this.autolocktimer = new System.Timers.Timer(); this.autolocktimer.Interval = 10000; this.autolocktimer.Elapsed += new System.Timers.ElapsedEventHandler(autolocktimer_Elapsed); this.autolocktimer.Start(); } private void uc_MouseMove(object sender, MouseEventArgs e) { AppClient.Instance.UserContext.CurrentLockCount = AppClient.Instance.UserContext.AutoLockCount; } private void autolocktimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (Application.Current == null) return; Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate { if (AppClient.Instance.UserMode != UserMode.Lock) { if (AppClient.Instance.UserContext.CurrentLockCount <= 0) { this.Lock(); } AppClient.Instance.UserContext.CurrentLockCount--; } else AppClient.Instance.UserContext.CurrentLockCount = AppClient.Instance.UserContext.AutoLockCount; }); }