3 Commits
Author SHA1 Message Date
ded_ikar 0c2212cde9 Add dark custom title bar with WindowChrome 2026-06-08 20:31:38 +05:00
Your Name 793076b948 initial 2026-06-06 00:37:49 +05:00
ded_ikar e7ea83daa0 fix QoS 2026-05-04 01:50:35 +05:00
13 changed files with 531 additions and 110 deletions
BIN
View File
Binary file not shown.
+60 -7
View File
@@ -108,7 +108,7 @@ namespace QoSManager.Services
private string GetPolicyStore()
{
return $"GPO:{Environment.MachineName}";
return "localhost";
}
private static string EscapePowerShellString(string value)
@@ -251,7 +251,7 @@ namespace QoSManager.Services
var escapedName = EscapePowerShellString(policy.Name);
var escapedProcess = EscapePowerShellString(policy.Process);
var escapedStore = EscapePowerShellString(GetPolicyStore());
var command = $"New-NetQosPolicy -Name '{escapedName}' -AppPathNameMatchCondition '{escapedProcess}' -DSCPAction {policy.DSCP} -PolicyStore '{escapedStore}'";
var command = $"New-NetQosPolicy -Name '{escapedName}' -AppPathNameMatchCondition '{escapedProcess}' -DSCPAction {policy.DSCP} -PolicyStore '{escapedStore}' -NetworkProfile All";
var encodedCommand = Convert.ToBase64String(Encoding.Unicode.GetBytes(command));
var startInfo = new ProcessStartInfo
@@ -291,7 +291,7 @@ namespace QoSManager.Services
{
try
{
_logger.LogInformation("Refreshing Group Policy to synchronize with gpedit.msc");
LogInformation("Refreshing Group Policy to synchronize with gpedit.msc");
var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
@@ -310,19 +310,19 @@ namespace QoSManager.Services
var output = process.StandardOutput.ReadToEnd();
var error = process.StandardError.ReadToEnd();
_logger.LogInformation($"Gpupdate output: {output}");
LogInformation($"Gpupdate output: {output}");
if (!string.IsNullOrEmpty(error))
{
_logger.LogInformation($"Gpupdate error: {error}");
LogInformation($"Gpupdate error: {error}");
}
if (process.ExitCode == 0)
{
_logger.LogInformation("Group Policy updated successfully");
LogInformation("Group Policy updated successfully");
}
else
{
_logger.LogInformation($"Group Policy update returned exit code: {process.ExitCode}");
LogInformation($"Group Policy update returned exit code: {process.ExitCode}");
}
}
}
@@ -332,6 +332,59 @@ namespace QoSManager.Services
}
}
public void RefreshQoSPolicies()
{
try
{
if (_loggingEnabled)
{
LogInformation("Force refreshing QoS policies to ensure they apply after reboot");
}
// Force update Group Policy
RefreshGroupPolicy();
// Restart QoS service to ensure policies apply
var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/c sc query QWAVE | find \"STATE\" && net stop QWAVE && net start QWAVE || net start QWAVE",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
StandardOutputEncoding = System.Text.Encoding.UTF8,
StandardErrorEncoding = System.Text.Encoding.UTF8
};
using (var process = Process.Start(startInfo))
{
process.WaitForExit();
var output = process.StandardOutput.ReadToEnd();
var error = process.StandardError.ReadToEnd();
LogInformation($"QoS service restart output: {output}");
if (!string.IsNullOrEmpty(error))
{
LogInformation($"QoS service restart error: {error}");
}
if (process.ExitCode == 0)
{
LogInformation("QoS service restarted successfully");
}
else
{
LogInformation($"QoS service restart returned exit code: {process.ExitCode}");
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error refreshing QoS policies");
}
}
public void DeletePolicy(string policyName, bool autoRefreshGPO = true)
{
try
+57
View File
@@ -83,6 +83,63 @@
<Setter Property="Foreground" Value="White"/>
</Style>
<!-- Стиль для кастомного заголовка окна -->
<Style x:Key="TitleBar" TargetType="Border">
<Setter Property="Background" Value="#2D2D2D"/>
<Setter Property="Height" Value="30"/>
<Setter Property="BorderBrush" Value="#444444"/>
<Setter Property="BorderThickness" Value="0,0,0,1"/>
<Setter Property="CornerRadius" Value="8,8,0,0"/>
</Style>
<Style x:Key="TitleBarText" TargetType="TextBlock">
<Setter Property="Foreground" Value="#CCCCCC"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="12,0,0,0"/>
</Style>
<Style x:Key="TitleBarButton" TargetType="Button">
<Setter Property="Width" Value="46"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}">
<TextBlock Text="{TemplateBinding Content}"
FontFamily="Segoe MDL2 Assets"
FontSize="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#3C3C3C"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#2A2A2A"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TitleBarCloseButton" TargetType="Button" BasedOn="{StaticResource TitleBarButton}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#E81123"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#F1707A"/>
</Trigger>
</Style.Triggers>
</Style>
<!-- Стиль для MessageBox buttons -->
<Style TargetType="Button" x:Key="{x:Type Button}">
<Setter Property="Background" Value="#3C3C3C"/>
+33 -6
View File
@@ -3,23 +3,48 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="QoS Manager"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
ResizeMode="NoResize"
SizeToContent="WidthAndHeight"
Background="#2D2D2D"
WindowStyle="SingleBorderWindow"
BorderBrush="#444444"
BorderThickness="1"
FontFamily="Segoe UI"
MinWidth="300"
MaxWidth="500">
<Grid Margin="20">
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" GlassFrameThickness="0" ResizeBorderThickness="0" UseAeroCaptionButtons="False"/>
</WindowChrome.WindowChrome>
<Border BorderBrush="#555555" BorderThickness="1" CornerRadius="8" Background="#2D2D2D">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="20"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Title Bar -->
<Border Grid.Row="0" Style="{StaticResource TitleBar}"
MouseLeftButtonDown="TitleBar_MouseLeftButtonDown">
<Grid>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}"
Style="{StaticResource TitleBarText}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="CloseButton" Style="{StaticResource TitleBarCloseButton}"
Click="CloseButton_Click" Content="&#xE8BB;"/>
</StackPanel>
</Grid>
</Border>
<!-- Content -->
<Grid Grid.Row="1" Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="20"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Сообщение -->
<TextBlock x:Name="MessageTextBlock"
Grid.Row="0"
@@ -70,5 +95,7 @@
Click="NoButton_Click"
Visibility="Collapsed"/>
</StackPanel>
</Grid>
</Grid>
</Grid>
</Border>
</Window>
+15
View File
@@ -1,4 +1,5 @@
using System.Windows;
using System.Windows.Input;
namespace QoSManager.Views
{
@@ -83,5 +84,19 @@ namespace QoSManager.Views
Result = MessageBoxResult.No;
Close();
}
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
DragMove();
}
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Result = MessageBoxResult.Cancel;
Close();
}
}
}
+113 -64
View File
@@ -5,77 +5,108 @@
Height="600" Width="900"
MinHeight="400" MinWidth="600"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
Background="#1E1E1E">
<Grid Margin="20">
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" GlassFrameThickness="0" ResizeBorderThickness="5" UseAeroCaptionButtons="False"/>
</WindowChrome.WindowChrome>
<Border BorderBrush="#555555" BorderThickness="1" CornerRadius="8" Background="#1E1E1E">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Заголовок -->
<StackPanel Grid.Row="0" Margin="0,0,0,20">
<!-- Title Bar -->
<Border Grid.Row="0" Style="{StaticResource TitleBar}"
MouseLeftButtonDown="TitleBar_MouseLeftButtonDown">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="Управление QoS-политиками Windows"
FontSize="18"
FontWeight="SemiBold"
Foreground="White"/>
<TextBlock Text="Добавляйте, удаляйте и просматривайте политики для отдельных процессов."
FontSize="12"
Foreground="#A0A0A0"
Margin="0,5,0,10"/>
</StackPanel>
<StackPanel Grid.Column="1"
Orientation="Horizontal"
VerticalAlignment="Top"
Margin="20,0,0,0">
<CheckBox x:Name="LoggingCheckBox"
Content="Вести логи"
Width="120"
Height="30"
Foreground="White"
VerticalContentAlignment="Center"/>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}"
Style="{StaticResource TitleBarText}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="MinimizeButton" Style="{StaticResource TitleBarButton}"
Click="MinimizeButton_Click" Content="&#xE921;"/>
<Button x:Name="MaximizeButton" Style="{StaticResource TitleBarButton}"
Click="MaximizeButton_Click" Content="&#xE922;"/>
<Button x:Name="CloseButton" Style="{StaticResource TitleBarCloseButton}"
Click="CloseButton_Click" Content="&#xE8BB;"/>
</StackPanel>
</Grid>
</StackPanel>
</Border>
<!-- Таблица политик -->
<DataGrid x:Name="PoliciesDataGrid"
Grid.Row="1"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
CanUserResizeRows="False"
IsReadOnly="True"
BeginningEdit="PoliciesDataGrid_BeginningEdit"
CellEditEnding="PoliciesDataGrid_CellEditEnding"
GridLinesVisibility="All"
HorizontalGridLinesBrush="#333333"
VerticalGridLinesBrush="#555555"
Background="#2D2D2D"
Foreground="White"
BorderBrush="#444444"
BorderThickness="1"
HeadersVisibility="Column"
SelectionMode="Single"
AlternatingRowBackground="#252525"
RowHeight="30"
MinRowHeight="25"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<!-- Content -->
<Grid Grid.Row="1" Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Заголовок -->
<StackPanel Grid.Row="0" Margin="0,0,0,20">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="Управление QoS-политиками Windows"
FontSize="18"
FontWeight="SemiBold"
Foreground="White"/>
<TextBlock Text="Создавайте и управляйте QoS-политиками для приоритизации сетевого трафика"
FontSize="12"
Foreground="#CCCCCC"
Margin="0,5,0,0"/>
</StackPanel>
<StackPanel Grid.Column="1"
Orientation="Horizontal"
VerticalAlignment="Top">
<TextBlock Text="Статус: "
FontSize="12"
Foreground="#CCCCCC"
VerticalAlignment="Center"/>
<TextBlock Text="Активно"
FontSize="12"
FontWeight="SemiBold"
Foreground="#4CAF50"
VerticalAlignment="Center"/>
</StackPanel>
</Grid>
</StackPanel>
<!-- DataGrid -->
<DataGrid x:Name="PoliciesDataGrid"
Grid.Row="1"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
CanUserResizeColumns="True"
CanUserResizeRows="False"
CanUserSortColumns="True"
GridLinesVisibility="Horizontal"
HorizontalGridLinesBrush="#3C3C3C"
VerticalGridLinesBrush="Transparent"
Background="#1E1E1E"
Foreground="White"
BorderBrush="#3C3C3C"
BorderThickness="1"
HeadersVisibility="Column"
SelectionMode="Single"
AlternatingRowBackground="#252525"
RowHeight="30"
MinRowHeight="25"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
@@ -129,7 +160,7 @@
Binding="{Binding Name}"
Width="180"
IsReadOnly="True"/>
<DataGridTextColumn Header="Процесс / путь"
<DataGridTextColumn Header="Процесс"
Binding="{Binding Process}"
Width="*"
IsReadOnly="True"/>
@@ -145,8 +176,23 @@
</DataGrid>
<!-- Настройки -->
<StackPanel x:Name="SettingsPanel"
Grid.Row="2"
Orientation="Horizontal"
HorizontalAlignment="Left"
Margin="0,20,0,10">
<CheckBox x:Name="LoggingCheckBox"
Content="Вести логи"
Width="120"
Height="30"
Foreground="White"
VerticalContentAlignment="Center"/>
</StackPanel>
<!-- Кнопки -->
<StackPanel Grid.Row="2"
<StackPanel Grid.Row="3"
Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="0,20,0,0">
@@ -172,6 +218,7 @@
Margin="0,0,10,0"
Style="{StaticResource DarkButtonStyle}"/>
<Button x:Name="LogButton"
Content="Открыть лог"
Width="100"
@@ -185,5 +232,7 @@
Height="35"
Style="{StaticResource DarkButtonStyle}"/>
</StackPanel>
</Grid>
</Grid>
</Grid>
</Border>
</Window>
+96 -5
View File
@@ -1,9 +1,15 @@
using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Data;
using QoSManager.Models;
using QoSManager.Services;
@@ -14,7 +20,8 @@ namespace QoSManager.Views
private readonly QoSService _qosService;
private readonly LoggingService _loggingService;
private readonly ObservableCollection<QoSPolicy> _policies;
private bool _loggingEnabled = true;
private bool _loggingEnabled = false;
private bool _isInitialized = false;
public MainWindow()
{
@@ -41,9 +48,22 @@ namespace QoSManager.Views
// Initialize checkbox state
LoggingCheckBox.IsChecked = _loggingEnabled;
// Hide settings panel initially and show it after UI is fully loaded
SettingsPanel.Visibility = Visibility.Collapsed;
// Don't log startup - let user enable logging manually if needed
LoadPolicies();
// Show settings panel and mark initialization as complete after UI loads
Dispatcher.BeginInvoke(() => {
// Always show checkboxes panel with current settings state
SettingsPanel.Visibility = Visibility.Visible;
_isInitialized = true;
// Auto-refresh QoS policies disabled on startup to prevent unwanted behavior
// User must manually enable auto-refresh if needed
});
}
public ObservableCollection<QoSPolicy> Policies => _policies;
@@ -65,7 +85,7 @@ namespace QoSManager.Views
{
try
{
// Load logging preference from Properties.Settings
// Load preferences from Properties.Settings
_loggingEnabled = Properties.Settings.Default.EnableLogging;
}
catch
@@ -78,7 +98,7 @@ namespace QoSManager.Views
{
try
{
// Save logging preference to Properties.Settings
// Save preferences to Properties.Settings
Properties.Settings.Default.EnableLogging = _loggingEnabled;
Properties.Settings.Default.Save();
}
@@ -215,6 +235,40 @@ namespace QoSManager.Views
LoadPolicies();
}
private void RefreshPoliciesButton_Click(object sender, RoutedEventArgs e)
{
try
{
_loggingService.LogInformation("Force refreshing QoS policies by user request", _loggingEnabled);
// Show progress message
CustomMessageBox.Show(
"Выполняется принудительное перечитывание QoS политик...\n\n" +
"Это может занять несколько секунд.\n" +
"После обновления может потребоваться перезапуск приложений.",
"Перечитывание политик", MessageBoxButton.OK, MessageBoxImage.Information);
// Force refresh QoS policies
_qosService.RefreshQoSPolicies();
// Reload policies list
LoadPolicies();
_loggingService.LogInformation("QoS policies refreshed successfully", _loggingEnabled);
// Show success message
CustomMessageBox.Show(
"QoS политики перечитаны",
"Успешно", MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
{
_loggingService.LogError($"Error refreshing QoS policies: {ex.Message}", _loggingEnabled);
CustomMessageBox.Show($"Ошибка при перечитывании QoS политик:\n\n{ex.Message}",
"Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void LogButton_Click(object sender, RoutedEventArgs e)
{
try
@@ -235,23 +289,60 @@ namespace QoSManager.Views
_loggingEnabled = true;
_qosService.SetLoggingEnabled(_loggingEnabled);
((App)Application.Current).SetLoggingEnabled(_loggingEnabled);
_loggingService.LogInformation("Логирование включено", _loggingEnabled);
if (_isInitialized)
{
_loggingService.LogInformation("Логирование включено", true);
}
}
private void LoggingCheckBox_Unchecked(object sender, RoutedEventArgs e)
{
// Log the disable action before actually disabling
_loggingService.LogInformation("Логирование отключено пользователем", _loggingEnabled);
if (_isInitialized && _loggingEnabled)
{
_loggingService.LogInformation("Логирование отключено пользователем", true);
}
_loggingEnabled = false;
_qosService.SetLoggingEnabled(_loggingEnabled);
((App)Application.Current).SetLoggingEnabled(_loggingEnabled);
}
private void ExitButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
DragMove();
}
}
private void MinimizeButton_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
}
private void MaximizeButton_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
protected override void OnStateChanged(EventArgs e)
{
base.OnStateChanged(e);
if (MaximizeButton != null)
MaximizeButton.Content = WindowState == WindowState.Maximized ? "\uE923" : "\uE922";
}
protected override void OnClosed(EventArgs e)
{
SaveSettings();
+37 -9
View File
@@ -1,23 +1,49 @@
<Window x:Class="QoSManager.Views.PolicyEditWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Создание QoS-политики"
Title="Создание QoS-политики"
Height="320" Width="500"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
Background="#1E1E1E"
ResizeMode="NoResize">
<Grid Margin="20">
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" GlassFrameThickness="0" ResizeBorderThickness="0" UseAeroCaptionButtons="False"/>
</WindowChrome.WindowChrome>
<Border BorderBrush="#555555" BorderThickness="1" CornerRadius="8" Background="#1E1E1E">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<!-- Title Bar -->
<Border Grid.Row="0" Style="{StaticResource TitleBar}"
MouseLeftButtonDown="TitleBar_MouseLeftButtonDown">
<Grid>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}"
Style="{StaticResource TitleBarText}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="CloseButton" Style="{StaticResource TitleBarCloseButton}"
Click="CloseButton_Click" Content="&#xE8BB;"/>
</StackPanel>
</Grid>
</Border>
<!-- Content -->
<Grid Grid.Row="1" Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
@@ -128,5 +154,7 @@
Height="35"
Style="{StaticResource DarkButtonStyle}"/>
</StackPanel>
</Grid>
</Grid>
</Grid>
</Border>
</Window>
+15 -1
View File
@@ -1,6 +1,7 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Win32;
using QoSManager.Models;
using QoSManager.Services;
@@ -134,7 +135,7 @@ namespace QoSManager.Views
if (string.IsNullOrWhiteSpace(ProcessTextBox.Text))
{
CustomMessageBox.Show("Укажите процесс или путь к исполняемому файлу.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
CustomMessageBox.Show("Укажите имя процесса.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
ProcessTextBox.Focus();
return false;
}
@@ -184,5 +185,18 @@ namespace QoSManager.Views
DSCP = dscpValue
};
}
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
DragMove();
}
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
}
}
+36 -12
View File
@@ -4,26 +4,48 @@
Title="Выбор процесса"
Height="600" Width="800"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
ResizeMode="CanResize"
Background="#2b2b2b"
TextElement.Foreground="White">
<Window.Resources>
<Style TargetType="Window">
<Setter Property="Foreground" Value="White"/>
</Style>
</Window.Resources>
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" GlassFrameThickness="0" ResizeBorderThickness="5" UseAeroCaptionButtons="False"/>
</WindowChrome.WindowChrome>
<Grid Margin="10">
<Border BorderBrush="#555555" BorderThickness="1" CornerRadius="8" Background="#2b2b2b">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Выберите запущенный процесс:"
FontSize="14" FontWeight="Bold"
Foreground="White" Margin="0,0,0,10"/>
<!-- Title Bar -->
<Border Grid.Row="0" Style="{StaticResource TitleBar}"
MouseLeftButtonDown="TitleBar_MouseLeftButtonDown">
<Grid>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}"
Style="{StaticResource TitleBarText}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="MinimizeButton" Style="{StaticResource TitleBarButton}"
Click="MinimizeButton_Click" Content="&#xE921;"/>
<Button x:Name="CloseButton" Style="{StaticResource TitleBarCloseButton}"
Click="CloseButton_Click" Content="&#xE8BB;"/>
</StackPanel>
</Grid>
</Border>
<!-- Content -->
<Grid Grid.Row="1" Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Выберите запущенный процесс:"
FontSize="14" FontWeight="Bold"
Foreground="White" Margin="0,0,0,10"/>
<DataGrid x:Name="ProcessesDataGrid" Grid.Row="1"
AutoGenerateColumns="False"
@@ -63,5 +85,7 @@
Background="#4a4a4a" Foreground="White"
BorderBrush="#6a6a6a" Margin="0,0,10,0" Click="CancelButton_Click"/>
</StackPanel>
</Grid>
</Grid>
</Grid>
</Border>
</Window>
+22 -2
View File
@@ -4,6 +4,7 @@ using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using QoSManager.Models;
namespace QoSManager.Views
@@ -30,7 +31,7 @@ namespace QoSManager.Views
var processInfo = new ProcessInfo
{
Id = process.Id,
Name = process.ProcessName,
Name = (process.ProcessName + ".exe").ToLower(),
Path = process.MainModule?.FileName ?? "Unknown"
};
@@ -57,7 +58,7 @@ namespace QoSManager.Views
{
if (ProcessesDataGrid.SelectedItem is ProcessInfo selectedProcess)
{
SelectedProcess = selectedProcess.Path;
SelectedProcess = selectedProcess.Name;
DialogResult = true;
Close();
}
@@ -68,5 +69,24 @@ namespace QoSManager.Views
DialogResult = false;
Close();
}
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
DragMove();
}
}
private void MinimizeButton_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
Close();
}
}
}
+32 -4
View File
@@ -3,16 +3,42 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Неподдерживаемая версия Windows" Height="520" Width="580"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
ResizeMode="NoResize"
Background="#2D2D30">
<Grid Margin="25">
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" GlassFrameThickness="0" ResizeBorderThickness="0" UseAeroCaptionButtons="False"/>
</WindowChrome.WindowChrome>
<Border BorderBrush="#555555" BorderThickness="1" CornerRadius="8" Background="#2D2D30">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Title Bar -->
<Border Grid.Row="0" Style="{StaticResource TitleBar}"
MouseLeftButtonDown="TitleBar_MouseLeftButtonDown">
<Grid>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}"
Style="{StaticResource TitleBarText}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="CloseButton" Style="{StaticResource TitleBarCloseButton}"
Click="CloseButton_Click" Content="&#xE8BB;"/>
</StackPanel>
</Grid>
</Border>
<!-- Content -->
<Grid Grid.Row="1" Margin="25">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Заголовок с иконкой -->
<StackPanel Orientation="Horizontal" Grid.Row="0" Margin="0,0,0,25">
<TextBlock Text="⚠️" FontSize="36" Margin="0,0,15,0" VerticalAlignment="Center"/>
@@ -74,5 +100,7 @@
Cursor="Hand"
Click="ExitButton_Click"/>
</StackPanel>
</Grid>
</Grid>
</Grid>
</Border>
</Window>
+15
View File
@@ -1,5 +1,6 @@
using System;
using System.Windows;
using System.Windows.Input;
using QoSManager.Services;
namespace QoSManager.Views
@@ -22,5 +23,19 @@ namespace QoSManager.Views
DialogResult = false;
Close();
}
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
DragMove();
}
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
Close();
}
}
}