-
Notifications
You must be signed in to change notification settings - Fork 367
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a dedicated dialog instead of drop down for excluding processes.
- Loading branch information
Showing
5 changed files
with
254 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
Project-Aurora/Project-Aurora/Settings/Window_ProcessSelection.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
<Window x:Class="Aurora.Settings.Window_ProcessSelection" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:local="clr-namespace:Aurora.Settings" | ||
mc:Ignorable="d" | ||
Height="480" Width="340" | ||
Title="Exclude process" ResizeMode="NoResize" Background="#181818"> | ||
<Window.Resources> | ||
<local:IconToImageConverter x:Key="IconToImageConverter" /> | ||
</Window.Resources> | ||
<Grid> | ||
<Grid.RowDefinitions> | ||
<RowDefinition /> | ||
<RowDefinition Height="Auto" /> | ||
</Grid.RowDefinitions> | ||
|
||
<TabControl x:Name="MainTabControl" BorderThickness="0"> | ||
<TabItem Header="Select running process"> | ||
<Grid> | ||
<Grid.RowDefinitions> | ||
<RowDefinition /> | ||
<RowDefinition Height="Auto" /> | ||
</Grid.RowDefinitions> | ||
|
||
<ListBox x:Name="RunningProcessList" Margin="0,0,0,10"> | ||
<ListBox.ItemTemplate> | ||
<DataTemplate> | ||
<Grid> | ||
<Grid.ColumnDefinitions> | ||
<ColumnDefinition Width="Auto" /> | ||
<ColumnDefinition /> | ||
</Grid.ColumnDefinitions> | ||
<Image Source="{Binding Path=Icon, Converter={StaticResource IconToImageConverter}}" Height="16" Width="16" Margin="2,0,4,0" HorizontalAlignment="Left" /> | ||
<TextBlock Text="{Binding Path=Name}" Grid.Column="1" /> | ||
</Grid> | ||
</DataTemplate> | ||
</ListBox.ItemTemplate> | ||
</ListBox> | ||
|
||
<TextBox x:Name="RunningProcessListFilterText" Grid.Row="1" TextChanged="RunningListFilter_TextChanged" PreviewKeyDown="RunningProcessListFilterText_KeyDown" /> | ||
<TextBlock IsHitTestVisible="False" Text="Filter list..." VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3,0,0,0" Foreground="#757575" Grid.Row="1"> | ||
<TextBlock.Style> | ||
<Style TargetType="{x:Type TextBlock}"> | ||
<Setter Property="Visibility" Value="Collapsed"/> | ||
<Style.Triggers> | ||
<DataTrigger Binding="{Binding Text, ElementName=RunningProcessListFilterText}" Value=""> | ||
<Setter Property="Visibility" Value="Visible"/> | ||
</DataTrigger> | ||
</Style.Triggers> | ||
</Style> | ||
</TextBlock.Style> | ||
</TextBlock> | ||
</Grid> | ||
</TabItem> | ||
|
||
|
||
<TabItem Header="Browse for executable"> | ||
<Grid Margin="0,10,0,0"> | ||
<Grid.RowDefinitions> | ||
<RowDefinition Height="Auto" /> | ||
<RowDefinition /> | ||
</Grid.RowDefinitions> | ||
<Grid.ColumnDefinitions> | ||
<ColumnDefinition /> | ||
<ColumnDefinition Width="Auto" /> | ||
</Grid.ColumnDefinitions> | ||
|
||
<TextBox x:Name="ProcessBrowseResult" /> | ||
<TextBlock IsHitTestVisible="False" Text="Browse for executable..." VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3,0,0,0" Foreground="#757575"> | ||
<TextBlock.Style> | ||
<Style TargetType="{x:Type TextBlock}"> | ||
<Setter Property="Visibility" Value="Collapsed"/> | ||
<Style.Triggers> | ||
<DataTrigger Binding="{Binding Text, ElementName=ProcessBrowseResult}" Value=""> | ||
<Setter Property="Visibility" Value="Visible"/> | ||
</DataTrigger> | ||
</Style.Triggers> | ||
</Style> | ||
</TextBlock.Style> | ||
</TextBlock> | ||
|
||
<Button Content="Browse" Grid.Column="1" Margin="10,0,0,0" Padding="5,0" Click="BrowseButton_Click" /> | ||
</Grid> | ||
</TabItem> | ||
</TabControl> | ||
|
||
<StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Right" Margin="0,10"> | ||
<Button Content="Exclude process" Padding="5,0" Click="OkayButton_Click" IsDefault="True" /> | ||
<Button Content="Cancel" Margin="10,0" Padding="5,0" Click="CancelButton_Click" IsCancel="True" /> | ||
</StackPanel> | ||
</Grid> | ||
</Window> |
148 changes: 148 additions & 0 deletions
148
Project-Aurora/Project-Aurora/Settings/Window_ProcessSelection.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
using Microsoft.Win32; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Drawing; | ||
using System.Globalization; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using System.Windows; | ||
using System.Windows.Controls; | ||
using System.Windows.Data; | ||
using System.Windows.Documents; | ||
using System.Windows.Input; | ||
using System.Windows.Media; | ||
using System.Windows.Media.Imaging; | ||
using System.Windows.Navigation; | ||
using System.Windows.Shapes; | ||
|
||
namespace Aurora.Settings { | ||
public partial class Window_ProcessSelection : Window { | ||
|
||
public Window_ProcessSelection() { | ||
InitializeComponent(); | ||
|
||
// Scan running processes and add them to a list | ||
List<RunningProcess> processList = new List<RunningProcess>(); | ||
foreach (var p in Process.GetProcesses()) | ||
try { | ||
// Get the exe name | ||
string name = System.IO.Path.GetFileName(p.MainModule.FileName); | ||
// Check if we've already got an exe by that name, if not add it | ||
if (!processList.Any(x => x.Name == name)) | ||
processList.Add(new RunningProcess { | ||
Name = name, | ||
Icon = System.Drawing.Icon.ExtractAssociatedIcon(p.MainModule.FileName) | ||
}); | ||
} catch { } | ||
|
||
// Sort the list, set the ListBox control to use that list | ||
RunningProcessList.ItemsSource = processList.OrderBy(p => p.Name); | ||
RunningProcessList.SelectedIndex = 0; | ||
|
||
// CollectionViewSorce to provide search/filter feature | ||
CollectionViewSource.GetDefaultView(RunningProcessList.ItemsSource).Filter = RunningProcessFilterPredicate; | ||
RunningProcessListFilterText.Focus(); | ||
} | ||
|
||
/// <summary>The exe that the user has selected to exclude.</summary> | ||
public string ChosenExecutable { get; private set; } = ""; | ||
|
||
/// <summary> | ||
/// Handler for the browse button on the custom exe path tab. Sets | ||
/// </summary> | ||
/// <param name="sender"></param> | ||
/// <param name="e"></param> | ||
private void BrowseButton_Click(object sender, RoutedEventArgs e) { | ||
OpenFileDialog dialog = new OpenFileDialog() { | ||
AddExtension = true, | ||
Filter = "Executable files (*.exe)|*.exe", | ||
Multiselect = false | ||
}; | ||
if (dialog.ShowDialog() == true) // requires "== true" because ShowDialog is a bool?, so doing "if (dialog.ShowDialog())" is invalid | ||
ProcessBrowseResult.Text = dialog.FileName; | ||
} | ||
|
||
/// <summary> | ||
/// Updates the running process filter when the textbox is changed. | ||
/// </summary> | ||
private void RunningListFilter_TextChanged(object sender, TextChangedEventArgs e) { | ||
CollectionViewSource.GetDefaultView(RunningProcessList.ItemsSource).Refresh(); | ||
if (RunningProcessList.SelectedIndex == -1) | ||
RunningProcessList.SelectedIndex = 0; | ||
} | ||
|
||
/// <summary> | ||
/// Method that makes Up/Down arrow keys when focussed on the RunningListFilter change the selection of the running list element. | ||
/// This means you don't have to click on the item when you are typing in a filter. | ||
/// We do not need to handle Enter key here as it is done by setting the OK button "IsDefault" to true. | ||
/// </summary> | ||
private void RunningProcessListFilterText_KeyDown(object sender, KeyEventArgs e) { | ||
if (e.Key == Key.Up) | ||
RunningProcessList.SelectedIndex = Math.Max(RunningProcessList.SelectedIndex - 1, 0); | ||
else if (e.Key == Key.Down) | ||
RunningProcessList.SelectedIndex = RunningProcessList.SelectedIndex + 1; // Automatically clamped | ||
} | ||
|
||
/// <summary> | ||
/// Filter that is run on each item in the running process list (List<RunningProcess>) and returns a bool | ||
/// indicating whether it should appear on the list. | ||
/// </summary> | ||
private bool RunningProcessFilterPredicate(object item) { | ||
return ((RunningProcess)item).Name.IndexOf(RunningProcessListFilterText.Text, StringComparison.InvariantCultureIgnoreCase) >= 0; | ||
} | ||
|
||
/// <summary> | ||
/// Handler for when the confimation button is clicked. Handles closing and informing the result of the dialog. | ||
/// </summary> | ||
private void OkayButton_Click(object sender, RoutedEventArgs e) { | ||
// If the user is on the running process list tab | ||
if (MainTabControl.SelectedIndex == 0) { | ||
if (RunningProcessList.SelectedItem == null) return; // Cannot OK if there is no item selected | ||
ChosenExecutable = ((RunningProcess)RunningProcessList.SelectedItem).Name; | ||
|
||
// Else if user is on browse tab | ||
} else { | ||
string exe = ProcessBrowseResult.Text; | ||
if (String.IsNullOrWhiteSpace(exe)) return; // Cannot OK if there is no text entered | ||
// Get just the exe name, | ||
ChosenExecutable = exe.Substring(exe.LastIndexOfAny(new[] { '/', '\\' }) + 1); | ||
} | ||
|
||
// Close the window and set result as successful | ||
DialogResult = true; | ||
Close(); | ||
} | ||
|
||
/// <summary> | ||
/// Handler for when the cancel button is clicked. Closes the window. | ||
/// </summary> | ||
private void CancelButton_Click(object sender, RoutedEventArgs e) { | ||
DialogResult = false; | ||
Close(); | ||
} | ||
} | ||
|
||
|
||
/// <summary> | ||
/// Converts an Icon into a WPF-compatible BitmapSource. | ||
/// </summary> | ||
class IconToImageConverter : IValueConverter { | ||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { | ||
Icon ico = (Icon)value; | ||
// Taken from https://stackoverflow.com/a/51438725/1305670 | ||
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(ico.Handle, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => null; | ||
} | ||
|
||
/// <summary> | ||
/// Container for a Running Process definition. | ||
/// </summary> | ||
struct RunningProcess { | ||
public string Name { get; set; } | ||
public Icon Icon { get; set; } | ||
} | ||
} |