fix: 修复切换窗口时自动恢复全屏状态错误的问题

chore: 添加editorconfig
chore: 为c++项目添加spdlog依赖
This commit is contained in:
Xu Liu 2021-07-31 22:22:12 +08:00
commit e4e33eaecb
6 changed files with 573 additions and 351 deletions

217
.editorconfig Normal file
View file

@ -0,0 +1,217 @@
# 如果要从更高级别的目录继承 .editorconfig 设置,请删除以下行
root = true
# c# 文件
[*.cs]
#### Core EditorConfig 选项 ####
# 缩进和间距
indent_size = 4
indent_style = tab
tab_width = 4
# 新行首选项
end_of_line = crlf
insert_final_newline = false
#### .NET 编码约定 ####
# 组织 Using
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
file_header_template = unset
# this. 和 Me. 首选项
dotnet_style_qualification_for_event = false
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false
dotnet_style_qualification_for_property = false
# 语言关键字与 bcl 类型首选项
dotnet_style_predefined_type_for_locals_parameters_members = true
dotnet_style_predefined_type_for_member_access = true
# 括号首选项
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_operators = never_if_unnecessary
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
# 修饰符首选项
dotnet_style_require_accessibility_modifiers = for_non_interface_members
# 表达式级首选项
dotnet_style_coalesce_expression = true
dotnet_style_collection_initializer = true
dotnet_style_explicit_tuple_names = true
dotnet_style_namespace_match_folder = true
dotnet_style_null_propagation = true
dotnet_style_object_initializer = true
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_prefer_auto_properties = true
dotnet_style_prefer_compound_assignment = true
dotnet_style_prefer_conditional_expression_over_assignment = true
dotnet_style_prefer_conditional_expression_over_return = true
dotnet_style_prefer_inferred_anonymous_type_member_names = true
dotnet_style_prefer_inferred_tuple_names = true
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
dotnet_style_prefer_simplified_boolean_expressions = true
dotnet_style_prefer_simplified_interpolation = true
# 字段首选项
dotnet_style_readonly_field = true
# 参数首选项
dotnet_code_quality_unused_parameters = all
# 禁止显示首选项
dotnet_remove_unnecessary_suppression_exclusions = none
# 新行首选项
dotnet_style_allow_multiple_blank_lines_experimental = true
dotnet_style_allow_statement_immediately_after_block_experimental = true
#### c# 编码约定 ####
# var 首选项
csharp_style_var_elsewhere = false
csharp_style_var_for_built_in_types = false
csharp_style_var_when_type_is_apparent = false
# Expression-bodied 成员
csharp_style_expression_bodied_accessors = true
csharp_style_expression_bodied_constructors = false
csharp_style_expression_bodied_indexers = true
csharp_style_expression_bodied_lambdas = true
csharp_style_expression_bodied_local_functions = false
csharp_style_expression_bodied_methods = false
csharp_style_expression_bodied_operators = false
csharp_style_expression_bodied_properties = true
# 模式匹配首选项
csharp_style_pattern_matching_over_as_with_null_check = true
csharp_style_pattern_matching_over_is_with_cast_check = true
csharp_style_prefer_not_pattern = true
csharp_style_prefer_pattern_matching = true
csharp_style_prefer_switch_expression = true
# Null 检查首选项
csharp_style_conditional_delegate_call = true
# 修饰符首选项
csharp_prefer_static_local_function = true
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async
# 代码块首选项
csharp_prefer_braces = true
csharp_prefer_simple_using_statement = true
# 表达式级首选项
csharp_prefer_simple_default_expression = true
csharp_style_deconstructed_variable_declaration = true
csharp_style_implicit_object_creation_when_type_is_apparent = true
csharp_style_inlined_variable_declaration = true
csharp_style_pattern_local_over_anonymous_function = true
csharp_style_prefer_index_operator = true
csharp_style_prefer_range_operator = true
csharp_style_throw_expression = true
csharp_style_unused_value_assignment_preference = discard_variable
csharp_style_unused_value_expression_statement_preference = discard_variable
# "using" 指令首选项
csharp_using_directive_placement = outside_namespace
# 新行首选项
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true
csharp_style_allow_embedded_statements_on_same_line_experimental = true
#### C# 格式规则 ####
# 新行首选项
csharp_new_line_before_catch = false
csharp_new_line_before_else = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = none
csharp_new_line_between_query_expression_clauses = true
# 缩进首选项
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = no_change
csharp_indent_switch_labels = true
# 空格键首选项
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# 包装首选项
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
#### 命名样式 ####
# 命名规则
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# 符号规范
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# 命名样式
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case

View file

@ -1,6 +1,6 @@
from conans import ConanFile, CMake
class EffectCommonConan(ConanFile):
requires = "fmt/8.0.1", "nlohmann_json/3.9.1"
requires = "fmt/8.0.1", "nlohmann_json/3.9.1", "spdlog/1.9.1"
generators = "visual_studio"

View file

@ -40,6 +40,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Magpie", "Magpie\Magpie.csp
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MODULE_FFX", "MODULE_FFX\MODULE_FFX.vcxproj", "{7E9E83EE-673A-490C-A771-F9AA4F0B89E7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{651769E5-E8D5-4347-92E2-9EFFB46D9C16}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64

View file

@ -127,7 +127,4 @@
</Button>
</Grid>
</StackPanel>
</Window>

View file

@ -17,355 +17,357 @@ using System.Threading;
namespace Magpie {
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window {
private OptionsWindow optionsWindow = null;
private readonly OpenFileDialog openFileDialog = new OpenFileDialog();
private readonly DispatcherTimer timerScale = new DispatcherTimer {
Interval = new TimeSpan(0, 0, 1)
};
private readonly FileSystemWatcher scaleModelsWatcher = new FileSystemWatcher();
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window {
private OptionsWindow optionsWindow = null;
private readonly OpenFileDialog openFileDialog = new OpenFileDialog();
private readonly DispatcherTimer timerScale = new DispatcherTimer {
Interval = new TimeSpan(0, 0, 1)
};
private readonly FileSystemWatcher scaleModelsWatcher = new FileSystemWatcher();
private IKeyboardMouseEvents keyboardEvents = null;
private MagWindow magWindow;
private IKeyboardMouseEvents keyboardEvents = null;
private MagWindow magWindow;
// 倒计时时间
private const int DOWN_COUNT = 5;
private int countDownNum;
// 倒计时时间
private const int DOWN_COUNT = 5;
private int countDownNum;
private (string Name, string Model)[] scaleModels;
private (string Name, string Model)[] scaleModels;
private IntPtr Handle;
private IntPtr Handle;
// 不为零时表示全屏窗口不是因为热键关闭的
private IntPtr prevSrcWindow = IntPtr.Zero;
private readonly DispatcherTimer timerRestore = new DispatcherTimer {
Interval = new TimeSpan(0, 0, 0, 0, 200)
};
// 不为零时表示全屏窗口不是因为热键关闭的
private IntPtr prevSrcWindow = IntPtr.Zero;
private readonly DispatcherTimer timerRestore = new DispatcherTimer {
Interval = new TimeSpan(0, 0, 0, 0, 200)
};
public MainWindow() {
InitializeComponent();
public MainWindow() {
InitializeComponent();
timerScale.Tick += TimerScale_Tick;
timerRestore.Tick += TimerRestore_Tick;
timerScale.Tick += TimerScale_Tick;
timerRestore.Tick += TimerRestore_Tick;
LoadScaleModels();
LoadScaleModels();
// 监视ScaleModels.json的更改
scaleModelsWatcher.Path = App.APPLICATION_DIR;
scaleModelsWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName;
scaleModelsWatcher.Filter = App.SCALE_MODELS_JSON_PATH.Substring(App.SCALE_MODELS_JSON_PATH.LastIndexOf('\\') + 1);
scaleModelsWatcher.Changed += ScaleModelsWatcher_Changed;
scaleModelsWatcher.Deleted += ScaleModelsWatcher_Changed;
scaleModelsWatcher.EnableRaisingEvents = true;
// 监视ScaleModels.json的更改
scaleModelsWatcher.Path = App.APPLICATION_DIR;
scaleModelsWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName;
scaleModelsWatcher.Filter = App.SCALE_MODELS_JSON_PATH.Substring(App.SCALE_MODELS_JSON_PATH.LastIndexOf('\\') + 1);
scaleModelsWatcher.Changed += ScaleModelsWatcher_Changed;
scaleModelsWatcher.Deleted += ScaleModelsWatcher_Changed;
scaleModelsWatcher.EnableRaisingEvents = true;
// 加载设置
txtHotkey.Text = Settings.Default.Hotkey;
// 加载设置
txtHotkey.Text = Settings.Default.Hotkey;
if (Settings.Default.ScaleMode >= cbbScaleMode.Items.Count) {
Settings.Default.ScaleMode = 0;
}
cbbScaleMode.SelectedIndex = Settings.Default.ScaleMode;
cbbInjectMode.SelectedIndex = Settings.Default.InjectMode;
cbbCaptureMode.SelectedIndex = Settings.Default.CaptureMode;
}
if (Settings.Default.ScaleMode >= cbbScaleMode.Items.Count) {
Settings.Default.ScaleMode = 0;
}
cbbScaleMode.SelectedIndex = Settings.Default.ScaleMode;
cbbInjectMode.SelectedIndex = Settings.Default.InjectMode;
cbbCaptureMode.SelectedIndex = Settings.Default.CaptureMode;
}
private void TimerRestore_Tick(object sender, EventArgs e) {
if (!Settings.Default.AutoRestore || !NativeMethods.IsWindow(prevSrcWindow)) {
StopWaitingForRestore();
return;
}
private void TimerRestore_Tick(object sender, EventArgs e) {
if (!Settings.Default.AutoRestore || !NativeMethods.IsWindow(prevSrcWindow)) {
StopWaitingForRestore();
return;
}
if (NativeMethods.GetForegroundWindow() == prevSrcWindow) {
StopWaitingForRestore();
ToggleMagWindow();
return;
}
if (NativeMethods.GetForegroundWindow() == prevSrcWindow) {
ToggleMagWindow();
return;
}
tbCurWndTitle.Text = "当前窗口:" + NativeMethods.GetWindowTitle(prevSrcWindow);
gridAutoRestore.Visibility = Visibility.Visible;
}
tbCurWndTitle.Text = "当前窗口:" + NativeMethods.GetWindowTitle(prevSrcWindow);
gridAutoRestore.Visibility = Visibility.Visible;
}
private void ScaleModelsWatcher_Changed(object sender, FileSystemEventArgs e) {
// 立即读取可能会访问冲突
Thread.Sleep(10);
Dispatcher.Invoke(() => {
LoadScaleModels();
});
}
private void ScaleModelsWatcher_Changed(object sender, FileSystemEventArgs e) {
// 立即读取可能会访问冲突
Thread.Sleep(10);
Dispatcher.Invoke(() => {
LoadScaleModels();
});
}
private void TimerScale_Tick(object sender, EventArgs e) {
if (--countDownNum != 0) {
cmiScale.Header = btnScale.Content = countDownNum.ToString();
return;
}
private void TimerScale_Tick(object sender, EventArgs e) {
if (--countDownNum != 0) {
cmiScale.Header = btnScale.Content = countDownNum.ToString();
return;
}
// 计时结束
StopScaleTimer();
// 计时结束
StopScaleTimer();
ToggleMagWindow();
}
ToggleMagWindow();
}
private void LoadScaleModels() {
try {
string json;
if (File.Exists(App.SCALE_MODELS_JSON_PATH)) {
json = File.ReadAllText(App.SCALE_MODELS_JSON_PATH);
} else {
json = Properties.Resources.BuiltInScaleModels;
File.WriteAllText(App.SCALE_MODELS_JSON_PATH, json);
}
private void LoadScaleModels() {
try {
string json;
if (File.Exists(App.SCALE_MODELS_JSON_PATH)) {
json = File.ReadAllText(App.SCALE_MODELS_JSON_PATH);
} else {
json = Properties.Resources.BuiltInScaleModels;
File.WriteAllText(App.SCALE_MODELS_JSON_PATH, json);
}
scaleModels = JArray.Parse(json)
.Select(t => {
string name = t["name"]?.ToString();
string model = t["model"]?.ToString();
return name == null || model == null ? throw new Exception() : (name, model);
})
.ToArray();
scaleModels = JArray.Parse(json)
.Select(t => {
string name = t["name"]?.ToString();
string model = t["model"]?.ToString();
return name == null || model == null ? throw new Exception() : (name, model);
})
.ToArray();
if (scaleModels.Length == 0) {
throw new Exception();
}
if (scaleModels.Length == 0) {
throw new Exception();
}
// 保留当前选择
int idx = cbbScaleMode.SelectedIndex;
cbbScaleMode.Items.Clear();
foreach ((string Name, string Model) scaleModel in scaleModels) {
_ = cbbScaleMode.Items.Add(scaleModel.Name);
}
// 保留当前选择
int idx = cbbScaleMode.SelectedIndex;
cbbScaleMode.Items.Clear();
foreach ((string Name, string Model) scaleModel in scaleModels) {
_ = cbbScaleMode.Items.Add(scaleModel.Name);
}
if (idx >= cbbScaleMode.Items.Count) {
idx = 0;
}
cbbScaleMode.SelectedIndex = idx;
} catch (Exception) {
scaleModels = null;
if (idx >= cbbScaleMode.Items.Count) {
idx = 0;
}
cbbScaleMode.SelectedIndex = idx;
} catch (Exception) {
scaleModels = null;
cbbScaleMode.Items.Clear();
_ = cbbScaleMode.Items.Add("<解析失败>");
}
}
cbbScaleMode.Items.Clear();
_ = cbbScaleMode.Items.Add("<解析失败>");
}
}
private void BtnOptions_Click(object sender, RoutedEventArgs e) {
if (optionsWindow == null) {
optionsWindow = new OptionsWindow();
optionsWindow.Closed += (object _, EventArgs _1) => {
optionsWindow = null;
};
}
private void BtnOptions_Click(object sender, RoutedEventArgs e) {
if (optionsWindow == null) {
optionsWindow = new OptionsWindow();
optionsWindow.Closed += (object _, EventArgs _1) => {
optionsWindow = null;
};
}
optionsWindow.Show();
_ = optionsWindow.Focus();
}
optionsWindow.Show();
_ = optionsWindow.Focus();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
magWindow.Destory();
Settings.Default.Save();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
magWindow.Destory();
Settings.Default.Save();
}
private void TxtHotkey_TextChanged(object sender, TextChangedEventArgs e) {
keyboardEvents?.Dispose();
keyboardEvents = Hook.GlobalEvents();
private void TxtHotkey_TextChanged(object sender, TextChangedEventArgs e) {
keyboardEvents?.Dispose();
keyboardEvents = Hook.GlobalEvents();
string hotkey = txtHotkey.Text.Trim();
string hotkey = txtHotkey.Text.Trim();
try {
keyboardEvents.OnCombination(new Dictionary<Combination, Action> {{
Combination.FromString(hotkey), () => ToggleMagWindow()
}});
try {
keyboardEvents.OnCombination(new Dictionary<Combination, Action> {{
Combination.FromString(hotkey), () => ToggleMagWindow()
}});
txtHotkey.Foreground = Brushes.Black;
Settings.Default.Hotkey = hotkey;
txtHotkey.Foreground = Brushes.Black;
Settings.Default.Hotkey = hotkey;
cmiHotkey.Header = hotkey;
} catch (ArgumentException) {
txtHotkey.Foreground = Brushes.Red;
}
}
cmiHotkey.Header = hotkey;
} catch (ArgumentException) {
txtHotkey.Foreground = Brushes.Red;
}
}
private void ToggleMagWindow() {
if (scaleModels == null || scaleModels.Length == 0) {
return;
}
private void ToggleMagWindow() {
if (Settings.Default.AutoRestore) {
StopWaitingForRestore();
}
if (magWindow.Status == MagWindowStatus.Running) {
// 通过热键关闭全屏窗口
magWindow.Destory();
prevSrcWindow = IntPtr.Zero;
return;
}
if (scaleModels == null || scaleModels.Length == 0) {
return;
}
if (magWindow.Status == MagWindowStatus.Starting) {
return;
}
if (magWindow.Status == MagWindowStatus.Running) {
// 通过热键关闭全屏窗口
magWindow.Destory();
return;
}
string effectsJson = scaleModels[Settings.Default.ScaleMode].Model;
bool showFPS = Settings.Default.ShowFPS;
int captureMode = Settings.Default.CaptureMode;
if (magWindow.Status == MagWindowStatus.Starting) {
return;
}
magWindow.Create(
effectsJson,
captureMode,
showFPS,
cbbInjectMode.SelectedIndex == 1,
false
);
string effectsJson = scaleModels[Settings.Default.ScaleMode].Model;
bool showFPS = Settings.Default.ShowFPS;
int captureMode = Settings.Default.CaptureMode;
prevSrcWindow = magWindow.SrcWindow;
}
magWindow.Create(
effectsJson,
captureMode,
showFPS,
cbbInjectMode.SelectedIndex == 1,
false
);
private void Window_SourceInitialized(object sender, EventArgs e) {
Handle = new WindowInteropHelper(this).Handle;
prevSrcWindow = magWindow.SrcWindow;
}
HwndSource source = HwndSource.FromHwnd(Handle);
source.AddHook(WndProc);
private void Window_SourceInitialized(object sender, EventArgs e) {
Handle = new WindowInteropHelper(this).Handle;
magWindow = new MagWindow(this);
magWindow.Closed += MagWindow_Closed;
HwndSource source = HwndSource.FromHwnd(Handle);
source.AddHook(WndProc);
// 检查命令行参数
string[] args = Environment.GetCommandLineArgs();
foreach (string arg in args) {
if (arg == "-st") {
// 启动到系统托盘
WindowState = WindowState.Minimized;
break;
}
}
}
magWindow = new MagWindow(this);
magWindow.Closed += MagWindow_Closed;
private void StopWaitingForRestore() {
gridAutoRestore.Visibility = Visibility.Hidden;
tbCurWndTitle.Text = "";
prevSrcWindow = IntPtr.Zero;
timerRestore.Stop();
}
// 检查命令行参数
string[] args = Environment.GetCommandLineArgs();
foreach (string arg in args) {
if (arg == "-st") {
// 启动到系统托盘
WindowState = WindowState.Minimized;
break;
}
}
}
private void MagWindow_Closed() {
if (!Settings.Default.AutoRestore) {
return;
}
private void StopWaitingForRestore() {
gridAutoRestore.Visibility = Visibility.Hidden;
tbCurWndTitle.Text = "";
prevSrcWindow = IntPtr.Zero;
timerRestore.Stop();
}
Dispatcher.Invoke(() => {
if (NativeMethods.IsWindow(prevSrcWindow)) {
timerRestore.Start();
} else {
StopWaitingForRestore();
}
});
}
private void MagWindow_Closed() {
if (!Settings.Default.AutoRestore) {
return;
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
if (msg == NativeMethods.MAGPIE_WM_SHOWME) {
// 收到 WM_SHOWME 激活窗口
if (WindowState == WindowState.Minimized) {
Show();
WindowState = WindowState.Normal;
}
Dispatcher.Invoke(() => {
if (NativeMethods.IsWindow(prevSrcWindow)) {
timerRestore.Start();
} else {
StopWaitingForRestore();
}
});
}
_ = NativeMethods.SetForegroundWindow(Handle);
handled = true;
}
return IntPtr.Zero;
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
if (msg == NativeMethods.MAGPIE_WM_SHOWME) {
// 收到 WM_SHOWME 激活窗口
if (WindowState == WindowState.Minimized) {
Show();
WindowState = WindowState.Normal;
}
private void CbbScaleMode_SelectionChanged(object sender, SelectionChangedEventArgs e) {
Settings.Default.ScaleMode = cbbScaleMode.SelectedIndex;
}
_ = NativeMethods.SetForegroundWindow(Handle);
handled = true;
}
return IntPtr.Zero;
}
private void StartScaleTimer() {
countDownNum = DOWN_COUNT;
cmiScale.Header = btnScale.Content = countDownNum.ToString();
private void CbbScaleMode_SelectionChanged(object sender, SelectionChangedEventArgs e) {
Settings.Default.ScaleMode = cbbScaleMode.SelectedIndex;
}
timerScale.Start();
}
private void StartScaleTimer() {
countDownNum = DOWN_COUNT;
cmiScale.Header = btnScale.Content = countDownNum.ToString();
private void StopScaleTimer() {
timerScale.Stop();
btnScale.Content = cmiScale.Header = "5秒后放大";
}
timerScale.Start();
}
private void ToggleScaleTimer() {
if (timerScale.IsEnabled) {
StopScaleTimer();
} else {
StartScaleTimer();
}
}
private void StopScaleTimer() {
timerScale.Stop();
btnScale.Content = cmiScale.Header = "5秒后放大";
}
private void CbbCaptureMode_SelectionChanged(object sender, SelectionChangedEventArgs e) {
Settings.Default.CaptureMode = cbbCaptureMode.SelectedIndex;
}
private void ToggleScaleTimer() {
if (timerScale.IsEnabled) {
StopScaleTimer();
} else {
StartScaleTimer();
}
}
private void Window_StateChanged(object sender, EventArgs e) {
if (WindowState == WindowState.Minimized) {
Hide();
notifyIcon.Visibility = Visibility.Visible;
} else {
notifyIcon.Visibility = Visibility.Hidden;
}
}
private void CbbCaptureMode_SelectionChanged(object sender, SelectionChangedEventArgs e) {
Settings.Default.CaptureMode = cbbCaptureMode.SelectedIndex;
}
private void CbbInjectMode_SelectionChanged(object sender, SelectionChangedEventArgs e) {
if (cbbInjectMode.SelectedIndex == 2) {
// 启动时注入
if (!openFileDialog.ShowDialog().GetValueOrDefault(false)) {
// 未选择文件,恢复原来的选项
cbbInjectMode.SelectedIndex = Settings.Default.InjectMode;
return;
}
private void Window_StateChanged(object sender, EventArgs e) {
if (WindowState == WindowState.Minimized) {
Hide();
notifyIcon.Visibility = Visibility.Visible;
} else {
notifyIcon.Visibility = Visibility.Hidden;
}
}
magWindow.HookCursorAtStartUp(openFileDialog.FileName);
} else {
// 不保存启动时注入的选项
Settings.Default.InjectMode = cbbInjectMode.SelectedIndex;
}
}
private void CbbInjectMode_SelectionChanged(object sender, SelectionChangedEventArgs e) {
if (cbbInjectMode.SelectedIndex == 2) {
// 启动时注入
if (!openFileDialog.ShowDialog().GetValueOrDefault(false)) {
// 未选择文件,恢复原来的选项
cbbInjectMode.SelectedIndex = Settings.Default.InjectMode;
return;
}
magWindow.HookCursorAtStartUp(openFileDialog.FileName);
} else {
// 不保存启动时注入的选项
Settings.Default.InjectMode = cbbInjectMode.SelectedIndex;
}
}
private void CmiExit_Click(object sender, RoutedEventArgs e) {
Close();
}
private void CmiExit_Click(object sender, RoutedEventArgs e) {
Close();
}
private void CmiMainForm_Click(object sender, RoutedEventArgs e) {
Show();
WindowState = WindowState.Normal;
}
private void CmiMainForm_Click(object sender, RoutedEventArgs e) {
Show();
WindowState = WindowState.Normal;
}
private void CmiScale_Click(object sender, RoutedEventArgs e) {
ToggleScaleTimer();
}
private void CmiScale_Click(object sender, RoutedEventArgs e) {
ToggleScaleTimer();
}
private void BtnScale_Click(object sender, RoutedEventArgs e) {
ToggleScaleTimer();
}
private void BtnScale_Click(object sender, RoutedEventArgs e) {
ToggleScaleTimer();
}
private void CmiOptions_Click(object sender, RoutedEventArgs e) {
BtnOptions_Click(sender, e);
}
private void CmiOptions_Click(object sender, RoutedEventArgs e) {
BtnOptions_Click(sender, e);
}
private void BtnCancelRestore_Click(object sender, RoutedEventArgs e) {
StopWaitingForRestore();
}
}
private void BtnCancelRestore_Click(object sender, RoutedEventArgs e) {
StopWaitingForRestore();
}
}
public class NotifyIconLeftClickCommand : ICommand {
public class NotifyIconLeftClickCommand : ICommand {
#pragma warning disable 67
// 未使用
public event EventHandler CanExecuteChanged;
// 未使用
public event EventHandler CanExecuteChanged;
#pragma warning restore 67
public bool CanExecute(object _) {
return true;
}
public bool CanExecute(object _) {
return true;
}
public void Execute(object parameter) {
MainWindow window = parameter as MainWindow;
window.Show();
window.WindowState = WindowState.Normal;
}
}
public void Execute(object parameter) {
MainWindow window = parameter as MainWindow;
window.Show();
window.WindowState = WindowState.Normal;
}
}
}

View file

@ -5,6 +5,7 @@
#include "pch.h"
#include "MagWindow.h"
#include "Env.h"
#include <spdlog/spdlog.h>
HINSTANCE hInst = NULL;