Skip to content

Commit

Permalink
Merge pull request #4 from arcanexhoax/bugfix/seek-win11-explorer-window
Browse files Browse the repository at this point in the history
Bugfix/seek win11 explorer window
  • Loading branch information
arcanexhoax authored Nov 29, 2024
2 parents d3b25d7 + 517aaa5 commit f754052
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 174 deletions.
1 change: 0 additions & 1 deletion GlobalKeyInterceptor
Submodule GlobalKeyInterceptor deleted from 30faff
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## WinTool
![NET](https://img.shields.io/badge/.NET%208-%23512BD4)
![Version](https://img.shields.io/badge/Version-0.6.1-%230c7ebf)
![NET](https://img.shields.io/badge/.NET%209-%23512BD4)
![Version](https://img.shields.io/badge/Version-0.6.2-%230c7ebf)
[![License](https://img.shields.io/github/license/arcanexhoax/GlobalKeyInterceptor.svg?color=00b542&label=License)](https://raw.githubusercontent.com/arcanexhoax/GlobalKeyInterceptor/master/LICENSE)

WinTool is a utility that expands shortcuts for Windows and its apps, it adds shortcuts for useful functions that do not have it.
Expand Down
32 changes: 22 additions & 10 deletions WinTool/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Threading;
using System.Windows;
using WinTool.CommandLine;
using WinTool.Native;
using WinTool.Services;
using WinTool.Utils;
using WinTool.ViewModel;
Expand All @@ -14,19 +16,20 @@ public partial class App : Application
{
private readonly IHost _app;

private Mutex? _secondInstanceMutex;

public App()
{
var builder = Host.CreateDefaultBuilder();
CheckForSecondInstance();

builder.ConfigureServices((context, services) =>
{
services.AddSingleton<MainWindow>();
services.AddSingleton<MainViewModel>();
services.AddSingleton<CommandHandler>();
services.AddSingleton<Shell>();
services.AddSingleton<SettingsManager>();
services.AddSingleton<MemoryCache>();
});
var builder = Host.CreateApplicationBuilder();

builder.Services.AddSingleton<MainWindow>();
builder.Services.AddSingleton<MainViewModel>();
builder.Services.AddSingleton<CommandHandler>();
builder.Services.AddSingleton<Shell>();
builder.Services.AddSingleton<SettingsManager>();
builder.Services.AddSingleton<MemoryCache>();

_app = builder.Build();
}
Expand All @@ -51,6 +54,14 @@ protected override async void OnStartup(StartupEventArgs e)
base.OnStartup(e);
}

private void CheckForSecondInstance()
{
_secondInstanceMutex = new Mutex(true, "WinTool-10fdf33711f4591a368bd6a0b0e20cc1", out bool isFirstInstance);

if (!isFirstInstance && NativeMethods.ShowWindow("WinTool"))
Environment.Exit(0);
}

private void HandleOperations(CommandHandler commandHandler, CommandLineParameters clp)
{
if (clp.CreateFileParameter is { FilePath: not (null or [])})
Expand All @@ -68,6 +79,7 @@ private void HandleOperations(CommandHandler commandHandler, CommandLineParamete

protected override async void OnExit(ExitEventArgs e)
{
_secondInstanceMutex?.Dispose();
await _app.StopAsync();
base.OnExit(e);
}
Expand Down
25 changes: 25 additions & 0 deletions WinTool/Native/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,24 @@ namespace WinTool.Native
{
public class NativeMethods
{
private const int SW_NORMAL = 1;

[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string? lpClassName, string lpWindowName);

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

public static string? GetWindowText(IntPtr hWnd)
{
string? text = null;
Expand All @@ -23,5 +35,18 @@ public class NativeMethods

return text;
}

public static bool ShowWindow(string windowTitle)
{
var firstInstanceHwnd = FindWindow(null, windowTitle);

if (firstInstanceHwnd == nint.Zero)
return false;

ShowWindow(firstInstanceHwnd, SW_NORMAL);
SetForegroundWindow(firstInstanceHwnd);

return true;
}
}
}
8 changes: 4 additions & 4 deletions WinTool/Services/SettingsManager.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Newtonsoft.Json;
using System;
using System;
using System.Diagnostics;
using System.IO;
using System.Text.Json;
using WinTool.Model;

namespace WinTool.Services
Expand All @@ -28,7 +28,7 @@ public SettingsManager()
try
{
string json = File.ReadAllText(_settingsFilePath);
var settings = JsonConvert.DeserializeObject<Settings>(json);
var settings = JsonSerializer.Deserialize<Settings>(json);
return settings;
}
catch (Exception ex)
Expand All @@ -42,7 +42,7 @@ public void UpdateSettings(Settings settings)
{
try
{
string json = JsonConvert.SerializeObject(settings);
string json = JsonSerializer.Serialize(settings);
File.WriteAllText(_settingsFilePath, json);
}
catch (Exception ex)
Expand Down
40 changes: 25 additions & 15 deletions WinTool/Services/Shell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,7 @@ public Task<List<string>> GetSelectedItemsPathsAsync()
if (window is null)
return null;

if (window.Document is not IShellFolderViewDual2 shellWindow)
return null;

var currentFolder = shellWindow.Folder.Items().Item();

// special folder - use window title, for some reason on "Desktop" gives null
if (currentFolder == null || currentFolder.Path.StartsWith("::"))
return NativeMethods.GetWindowText(handle);
else
return currentFolder.Path;
return new Uri(window.LocationURL).LocalPath;
}
catch (Exception ex)
{
Expand Down Expand Up @@ -127,17 +118,36 @@ private List<string> GetSelectedItemsPaths()
private InternetExplorer? GetActiveShellWindow11(IntPtr handle)
{
string? windowTitle = NativeMethods.GetWindowText(handle);
ShellWindows shellWindows = new();

if (windowTitle is null or [])
{
Trace.WriteLine("Failed to get window title of current Explorer window");
return null;
}

ShellWindows shellWindows = new();
InternetExplorer? seekingWindow = null;
int pathLength = 0;

foreach (InternetExplorer window in shellWindows)
{
if (window.HWND != (int)handle)
continue;

string currentExplorerPath = new Uri(window.LocationURL).LocalPath;

// The explorer window in Windows 11 supports multiple tabs, these tabs will have the same window handle, so we need to compare
// the title (indicates the path) of the current explorer window with the local path of each tab of this window
if (window.HWND == (int)handle && new Uri(window.LocationURL).LocalPath == windowTitle)
return window;
// the title (indicates the path) of the current explorer window with the local path of each tab of this window. In recent Windows 11
// versions, the Explorer title format has changed to "C:\\folder - File Explorer" or "C:\\folder and X more tabs - File Explorer".
// So now it's unable to get current explorer window if it's Desktop/Downloads/Pictures etc
if (windowTitle.StartsWith(currentExplorerPath) && currentExplorerPath.Length > pathLength)
{
seekingWindow = window;
pathLength = currentExplorerPath.Length;
}
}

return null;
return seekingWindow;
}
}
}
3 changes: 2 additions & 1 deletion WinTool/View/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
Width="800"
x:Name="mainWindow"
WindowStartupLocation="CenterScreen"
Closing="OnWindowClosing">
Closing="OnWindowClosing"
Activated="OnWindowActivated">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding WindowLoadedCommand}" />
Expand Down
2 changes: 2 additions & 0 deletions WinTool/View/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public MainWindow(MainViewModel mainViewModel)
InitializeComponent();
}

private void OnWindowActivated(object? sender, System.EventArgs e) => Show();

private void OnWindowClosing(object sender, CancelEventArgs e)
{
e.Cancel = true;
Expand Down
58 changes: 19 additions & 39 deletions WinTool/ViewModel/ChangeFilePropertiesViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Prism.Commands;
using Prism.Mvvm;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Diagnostics;
using System.IO;
Expand All @@ -9,83 +9,63 @@

namespace WinTool.ViewModel
{
public class ChangeFilePropertiesViewModel : BindableBase
public class ChangeFilePropertiesViewModel : ObservableObject
{
private string? _fileName;
private string? _title;
private string? _performers;
private string? _album;
private string? _genres;
private string? _lyrics;
private uint _year;
private bool _mediaTagsSupported;
private DateTime _creationTime;
private DateTime _changeTime;
private Window? _window;

public string? FileName
{
get => _fileName;
set => SetProperty(ref _fileName, value);
get; set => SetProperty(ref field, value);
}

public string? Title
{
get => _title;
set => SetProperty(ref _title, value);
get; set => SetProperty(ref field, value);
}

public string? Performers
{
get => _performers;
set => SetProperty(ref _performers, value);
get; set => SetProperty(ref field, value);
}

public string? Album
{
get => _album;
set => SetProperty(ref _album, value);
get; set => SetProperty(ref field, value);
}

public string? Genres
{
get => _genres;
set => SetProperty(ref _genres, value);
get; set => SetProperty(ref field, value);
}

public string? Lyrics
{
get => _lyrics;
set => SetProperty(ref _lyrics, value);
get; set => SetProperty(ref field, value);
}

public uint Year
{
get => _year;
set => SetProperty(ref _year, value);
get; set => SetProperty(ref field, value);
}

public bool MediaTagsSupported
{
get => _mediaTagsSupported;
set => SetProperty(ref _mediaTagsSupported, value);
get; set => SetProperty(ref field, value);
}

public DateTime CreationTime
{
get => _creationTime;
set => SetProperty(ref _creationTime, value);
get; set => SetProperty(ref field, value);
}

public DateTime ChangeTime
{
get => _changeTime;
set => SetProperty(ref _changeTime, value);
get; set => SetProperty(ref field, value);
}

public DelegateCommand<Window> WindowLoadedCommand { get; }
public DelegateCommand SaveCommand { get; }
public DelegateCommand CloseWindowCommand { get; }
public RelayCommand<Window> WindowLoadedCommand { get; }
public RelayCommand SaveCommand { get; }
public RelayCommand CloseWindowCommand { get; }

public ChangeFilePropertiesViewModel(string filePath, TagLib.File? tfile = null)
{
Expand All @@ -104,7 +84,7 @@ public ChangeFilePropertiesViewModel(string filePath, TagLib.File? tfile = null)
Year = tfile.Tag.Year;
}

SaveCommand = new DelegateCommand(() =>
SaveCommand = new RelayCommand(() =>
{
try
{
Expand All @@ -131,8 +111,8 @@ public ChangeFilePropertiesViewModel(string filePath, TagLib.File? tfile = null)

_window?.Close();
});
WindowLoadedCommand = new DelegateCommand<Window>(w => _window = w);
CloseWindowCommand = new DelegateCommand(() => _window?.Close());
WindowLoadedCommand = new RelayCommand<Window>(w => _window = w);
CloseWindowCommand = new RelayCommand(() => _window?.Close());
}
}
}
Loading

0 comments on commit f754052

Please sign in to comment.