8 Commits
Author SHA1 Message Date
Stone_Red 9a53be9abe Merge pull request #6 from Stone-Red-Code/develop
Develop
2025-03-05 18:53:04 +01:00
Stone_Red f0dbf4621b Update version 2025-03-05 18:51:49 +01:00
Stone_Red 28eeac5635 Merge remote-tracking branch 'origin/develop' into develop 2025-03-05 17:40:16 +01:00
Stone_Red 6350903d96 Add screen blur option 2025-03-05 17:40:05 +01:00
Stone_Red a13babb780 Add autostart option 2025-03-05 17:39:53 +01:00
Stone_Red beb6fce41a Merge pull request #4 from Stone-Red-Code/develop
Add Microsoft Store link to README.md
2025-02-17 16:54:31 +01:00
Stone_Red 3c39d693fa Add Microsoft Store link to README.md 2025-02-17 16:54:15 +01:00
Stone_Red b065b90f87 Update issue templates 2025-02-14 19:18:43 +01:00
15 changed files with 357 additions and 7 deletions
+38
View File
@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
+20
View File
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
+1 -1
View File
@@ -3,7 +3,7 @@
## Usage ## Usage
1. Download & install the latest release 1. Download & install the latest release
- Microsoft Store: [Store Page (Coming Soon)](https://www.microsoft.com/store/apps) - Microsoft Store: [Store Page](https://apps.microsoft.com/detail/9P5ZXZQJRK4H?hl=en-us&gl=AT&ocid=pdpshare)
- GitHub: [Releases](https://github.com/Stone-Red-Code/InvLock/releases) - GitHub: [Releases](https://github.com/Stone-Red-Code/InvLock/releases)
2. (Optional) Put a shortcut to the `InvLock.exe` file in the installation directory into the `shell:startup` directory. 2. (Optional) Put a shortcut to the `InvLock.exe` file in the installation directory into the `shell:startup` directory.
3. Start the app and configure the settings to your liking. 3. Start the app and configure the settings to your liking.
+1 -1
View File
@@ -11,7 +11,7 @@
[Setup] [Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. ; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId=68d780d4-b946-4154-8815-e4632e5ec5d8 AppId=4B2411E5-1AE9-450C-AF2F-9A515ECBB9DF
AppName={#MyAppName} AppName={#MyAppName}
AppVersion={#MyAppVersion} AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion} ;AppVerName={#MyAppName} {#MyAppVersion}
Binary file not shown.
+15
View File
@@ -0,0 +1,15 @@
<Window x:Class="InvLock.BlurWindow"
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"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:InvLock"
mc:Ignorable="d"
Loaded="Window_Loaded"
WindowStyle="None"
MouseDown="Window_MouseDown"
AllowsTransparency="True"
Background="Black"
Opacity="0"
Title="BlurWindow" Height="450" Width="800">
</Window>
+26
View File
@@ -0,0 +1,26 @@
using InvLock.Utilities;
using System.Windows;
namespace InvLock;
/// <summary>
/// Interaction logic for BlurWindow.xaml
/// </summary>
public partial class BlurWindow : Window
{
public BlurWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
WindowsApi.EnableBlur(this);
}
private void Window_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
DragMove();
}
}
@@ -1,13 +1,19 @@
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using InvLock.Utilities;
using SharpHook.Native; using SharpHook.Native;
using System.ComponentModel;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
namespace InvLock.DataContexts; namespace InvLock.DataContexts;
internal partial class MainWindowDataContext(Func<LockWindow?> lockWindowAccessor) internal partial class MainWindowDataContext(Func<LockWindow?> lockWindowAccessor) : INotifyPropertyChanged
{ {
public event PropertyChangedEventHandler? PropertyChanged;
#if DEBUG #if DEBUG
public string Title => $"{App.AppName} - Dev {AppVersion}"; public string Title => $"{App.AppName} - Dev {AppVersion}";
#else #else
@@ -16,10 +22,28 @@ internal partial class MainWindowDataContext(Func<LockWindow?> lockWindowAccesso
public string AppName => App.AppName; public string AppName => App.AppName;
public string AppVersion => Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "Unknown"; public string AppVersion => Assembly.GetEntryAssembly()?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "Unknown";
public Settings Settings { get; } = Settings.Load(); public Settings Settings { get; } = Settings.Load();
public bool IsAutoStartEnabled
{
get => StartupManager.IsAutoStartEnabled();
set
{
if (value)
{
_ = StartupManager.EnableAutoStart();
}
else
{
_ = StartupManager.DisableAutoStart();
}
OnPropertyChanged();
}
}
[RelayCommand] [RelayCommand]
public async Task RecordLockShortcut() public async Task RecordLockShortcut()
{ {
@@ -55,4 +79,9 @@ internal partial class MainWindowDataContext(Func<LockWindow?> lockWindowAccesso
Settings.UnlockShortcut = unlockShortcut; Settings.UnlockShortcut = unlockShortcut;
} }
} }
protected void OnPropertyChanged([CallerMemberName] string? name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
} }
+6
View File
@@ -8,6 +8,10 @@
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ApplicationIcon>Assets\logo.ico</ApplicationIcon> <ApplicationIcon>Assets\logo.ico</ApplicationIcon>
<Version>1.1.0.0</Version>
<AssemblyVersion>1.1.0.0</AssemblyVersion>
<FileVersion>1.1.0.0</FileVersion>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -17,9 +21,11 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="CuteUtils" Version="1.0.0" /> <PackageReference Include="CuteUtils" Version="1.0.0" />
<PackageReference Include="Interop.IWshRuntimeLibrary" Version="1.0.1" />
<PackageReference Include="SharpHook" Version="5.3.8" /> <PackageReference Include="SharpHook" Version="5.3.8" />
<PackageReference Include="WPF-UI" Version="4.0.0" /> <PackageReference Include="WPF-UI" Version="4.0.0" />
<PackageReference Include="WPF-UI.Tray" Version="4.0.0" /> <PackageReference Include="WPF-UI.Tray" Version="4.0.0" />
<PackageReference Include="WpfScreenHelper" Version="2.1.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
+32 -3
View File
@@ -19,7 +19,9 @@ public partial class LockWindow : Window
private readonly SimpleGlobalHook hook = new SimpleGlobalHook(); private readonly SimpleGlobalHook hook = new SimpleGlobalHook();
private readonly Dictionary<KeyCode, DateTime> pressedKeys = []; private readonly Dictionary<KeyCode, DateTime> pressedKeys = [];
private readonly Settings settings; private readonly Settings settings;
private readonly List<BlurWindow> blurWindows = [];
private List<IntPtr> windows = []; private List<IntPtr> windows = [];
private Point lastMousePosition;
private bool isOpen = true; private bool isOpen = true;
private bool suppressInput = false; private bool suppressInput = false;
@@ -120,11 +122,32 @@ public partial class LockWindow : Window
MinimizeWindows(); MinimizeWindows();
} }
isOpen = true;
suppressInput = true;
Dispatcher.Invoke(() => Dispatcher.Invoke(() =>
{ {
lastMousePosition = WpfScreenHelper.MouseHelper.MousePosition;
if (settings.BlurScreen)
{
foreach (Rect bounds in WpfScreenHelper.Screen.AllScreens.Select(s => s.WpfBounds))
{
BlurWindow blurWindow = new()
{
Width = bounds.Width,
Height = bounds.Height,
Left = bounds.Left,
Top = bounds.Top,
};
blurWindows.Add(blurWindow);
blurWindow.Show();
}
_ = WindowsApi.SetCursorPosition(new Point(100000, 100000));
}
isOpen = true;
suppressInput = true;
_ = Activate(); _ = Activate();
textBlock.Text = settings.LockText; textBlock.Text = settings.LockText;
@@ -155,6 +178,9 @@ public partial class LockWindow : Window
isOpen = true; isOpen = true;
_ = WindowsApi.SetCursorPosition(lastMousePosition);
blurWindows.ForEach(w => w.Close());
textBlock.Text = settings.UnlockText; textBlock.Text = settings.UnlockText;
textBlock.Stroke = (Brush)FindResource("PaletteGreenBrush"); textBlock.Stroke = (Brush)FindResource("PaletteGreenBrush");
@@ -203,6 +229,9 @@ public partial class LockWindow : Window
isOpen = true; isOpen = true;
_ = WindowsApi.SetCursorPosition(lastMousePosition);
blurWindows.ForEach(w => w.Close());
_ = Activate(); _ = Activate();
await Task.Delay(500); await Task.Delay(500);
+21
View File
@@ -79,6 +79,20 @@
</ComboBox> </ComboBox>
</ui:CardControl> </ui:CardControl>
<ui:CardControl Margin="0,0,0,12" Icon="{ui:SymbolIcon Symbol=Clock24}" Height="75">
<ui:CardControl.Header>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ui:TextBlock Grid.Row="0" FontTypography="Body" Text="Run at startup" />
<ui:TextBlock Grid.Row="1" Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}" FontSize="12" Text="Start InvLock when you sign in to Windows" />
</Grid>
</ui:CardControl.Header>
<ui:ToggleSwitch Grid.Column="1" IsChecked="{Binding IsAutoStartEnabled}" OffContent="Off" OnContent="On" />
</ui:CardControl>
<ui:CardControl Margin="0,0,0,12" Icon="{ui:SymbolIcon Symbol=Window24}" Height="75"> <ui:CardControl Margin="0,0,0,12" Icon="{ui:SymbolIcon Symbol=Window24}" Height="75">
<ui:CardControl.Header> <ui:CardControl.Header>
<ui:TextBlock Grid.Row="0" FontTypography="Body" Text="Show desktop while locked" /> <ui:TextBlock Grid.Row="0" FontTypography="Body" Text="Show desktop while locked" />
@@ -86,6 +100,13 @@
<ui:ToggleSwitch Grid.Column="1" IsChecked="{Binding Settings.HideWindows}" OffContent="Off" OnContent="On" /> <ui:ToggleSwitch Grid.Column="1" IsChecked="{Binding Settings.HideWindows}" OffContent="Off" OnContent="On" />
</ui:CardControl> </ui:CardControl>
<ui:CardControl Margin="0,0,0,12" Icon="{ui:SymbolIcon Symbol=Blur24}" Height="75">
<ui:CardControl.Header>
<ui:TextBlock Grid.Row="0" FontTypography="Body" Text="Blur screen while locked" />
</ui:CardControl.Header>
<ui:ToggleSwitch Grid.Column="1" IsChecked="{Binding Settings.BlurScreen}" OffContent="Off" OnContent="On" />
</ui:CardControl>
<ui:CardControl Margin="0,0,0,12" Icon="{ui:SymbolIcon Symbol=WindowShield24}" Height="75"> <ui:CardControl Margin="0,0,0,12" Icon="{ui:SymbolIcon Symbol=WindowShield24}" Height="75">
<ui:CardControl.Header> <ui:CardControl.Header>
<ui:TextBlock Grid.Row="0" FontTypography="Body" Text="Use windows lock screen to unlock" /> <ui:TextBlock Grid.Row="0" FontTypography="Body" Text="Use windows lock screen to unlock" />
+1
View File
@@ -71,6 +71,7 @@ public partial class MainWindow : FluentWindow
e.Cancel = true; e.Cancel = true;
ShowInTaskbar = false; ShowInTaskbar = false;
WindowState = WindowState.Minimized;
Visibility = Visibility.Collapsed; Visibility = Visibility.Collapsed;
} }
} }
+11
View File
@@ -17,6 +17,7 @@ public class Settings : INotifyPropertyChanged
private static readonly string settingsPath = Path.Combine(App.ApplicationDataPath, "settings.json"); private static readonly string settingsPath = Path.Combine(App.ApplicationDataPath, "settings.json");
private bool useWindowsLockScreen = true; private bool useWindowsLockScreen = true;
private bool hideWindows = false; private bool hideWindows = false;
private bool blurScreen = false;
private string lockText = "Lock Screen Active"; private string lockText = "Lock Screen Active";
private string theme = "Windows default"; private string theme = "Windows default";
private HashSet<KeyCode> lockShortcut = [KeyCode.VcLeftControl, KeyCode.VcLeftShift, KeyCode.VcL]; private HashSet<KeyCode> lockShortcut = [KeyCode.VcLeftControl, KeyCode.VcLeftShift, KeyCode.VcL];
@@ -34,6 +35,16 @@ public class Settings : INotifyPropertyChanged
} }
} }
public bool BlurScreen
{
get => blurScreen;
set
{
blurScreen = value;
OnPropertyChanged();
}
}
public bool UseWindowsLockScreen public bool UseWindowsLockScreen
{ {
get => useWindowsLockScreen; get => useWindowsLockScreen;
+81
View File
@@ -0,0 +1,81 @@
using IWshRuntimeLibrary;
using System.IO;
using System.Reflection;
using System.Windows;
namespace InvLock.Utilities;
public enum AutoStartStatus
{
Success = 0,
InvalidParameters = 1,
AlreadyEnabled = 2,
AlreadyDisabled = 3,
UnexpectedError = 4
}
public static class StartupManager
{
private static readonly string appPath = Path.ChangeExtension(Assembly.GetEntryAssembly()?.Location ?? throw new InvalidOperationException("Failed to get the application path."), ".exe");
private static readonly string startupFolder = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
private static readonly string shortcutPath = Path.Combine(startupFolder, Path.GetFileNameWithoutExtension(appPath) + ".lnk");
public static bool IsAutoStartEnabled()
{
return System.IO.File.Exists(shortcutPath);
}
public static AutoStartStatus EnableAutoStart()
{
if (IsAutoStartEnabled())
{
return AutoStartStatus.AlreadyEnabled;
}
try
{
WshShell shell = new WshShell();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath);
shortcut.TargetPath = appPath;
shortcut.WorkingDirectory = Path.GetDirectoryName(appPath);
shortcut.Save();
return AutoStartStatus.Success;
}
catch
{
return AutoStartStatus.UnexpectedError;
}
}
public static AutoStartStatus DisableAutoStart()
{
if (!IsAutoStartEnabled())
{
return AutoStartStatus.AlreadyDisabled;
}
try
{
System.IO.File.Delete(shortcutPath);
return AutoStartStatus.Success;
}
catch
{
return AutoStartStatus.UnexpectedError;
}
}
public static void ToggleAutoStart()
{
AutoStartStatus status = IsAutoStartEnabled() ? DisableAutoStart() : EnableAutoStart();
_ = status switch
{
AutoStartStatus.Success => MessageBox.Show("Auto-start setting changed successfully."),
AutoStartStatus.AlreadyEnabled => MessageBox.Show("Auto-start is already enabled."),
AutoStartStatus.AlreadyDisabled => MessageBox.Show("Auto-start is already disabled."),
_ => MessageBox.Show("Failed to change auto-start setting."),
};
}
}
+73
View File
@@ -1,6 +1,8 @@
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Windows;
using System.Windows.Interop;
namespace InvLock.Utilities; namespace InvLock.Utilities;
@@ -70,12 +72,46 @@ public static class WindowsApi
_ = ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE); _ = ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
} }
public static bool SetCursorPosition(Point point)
{
return SetCursorPos((int)point.X, (int)point.Y);
}
public static void EnableBlur(Window window)
{
WindowInteropHelper windowHelper = new WindowInteropHelper(window);
AccentPolicy accent = new AccentPolicy
{
AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND
};
int accentStructSize = Marshal.SizeOf(accent);
nint accentPtr = Marshal.AllocHGlobal(accentStructSize);
Marshal.StructureToPtr(accent, accentPtr, false);
WindowCompositionAttributeData data = new WindowCompositionAttributeData
{
Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY,
SizeOfData = accentStructSize,
Data = accentPtr
};
_ = SetWindowCompositionAttribute(windowHelper.Handle, ref data);
Marshal.FreeHGlobal(accentPtr);
}
[DllImport("user32.dll")] [DllImport("user32.dll")]
internal static extern bool LockWorkStation(); internal static extern bool LockWorkStation();
[DllImport("user32.dll")] [DllImport("user32.dll")]
internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);
[DllImport("user32.dll")] [DllImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam); private static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam);
@@ -102,4 +138,41 @@ public static class WindowsApi
[DllImport("user32.dll")] [DllImport("user32.dll")]
private static extern bool IsIconic(IntPtr hWnd); private static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool SetCursorPos(int x, int y);
internal enum AccentState
{
ACCENT_DISABLED = 1,
ACCENT_ENABLE_GRADIENT = 0,
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
ACCENT_ENABLE_BLURBEHIND = 3,
ACCENT_INVALID_STATE = 4
}
internal enum WindowCompositionAttribute
{
// ...
WCA_ACCENT_POLICY = 19
// ...
}
[StructLayout(LayoutKind.Sequential)]
internal struct AccentPolicy
{
public AccentState AccentState;
public int AccentFlags;
public int GradientColor;
public int AnimationId;
}
[StructLayout(LayoutKind.Sequential)]
internal struct WindowCompositionAttributeData
{
public WindowCompositionAttribute Attribute;
public IntPtr Data;
public int SizeOfData;
}
} }