diff --git a/src/SoulSplitter/Hotkeys/GlobalHotKey.cs b/src/SoulSplitter/Hotkeys/GlobalHotKey.cs
index 567c327..073eb00 100644
--- a/src/SoulSplitter/Hotkeys/GlobalHotKey.cs
+++ b/src/SoulSplitter/Hotkeys/GlobalHotKey.cs
@@ -22,99 +22,100 @@
using System.Windows.Input;
using SoulSplitter.Native;
-namespace SoulSplitter.Hotkeys;
-
-public static class GlobalHotKey
+namespace SoulSplitter.Hotkeys
{
- private static readonly List<(int id, ModifierKeys modifier, Key key, Action action)> Hotkeys = [];
- private static readonly ManualResetEvent WindowReadyEvent = new(false);
- public static volatile HotkeyForm? HotkeyForm;
- public static volatile IntPtr Handle;
- private static int _currentId;
-
- static GlobalHotKey()
+ public static class GlobalHotKey
{
- var messageLoopThread = new Thread(delegate ()
- {
- Application.Run(new HotkeyForm(WindowReadyEvent));
- });
- messageLoopThread.Name = "MessageLoopThread";
- messageLoopThread.IsBackground = true;
- messageLoopThread.Start();
- }
+ private static readonly List<(int id, Hotkey hotkey, Action action)> Hotkeys = new List<(int, Hotkey, Action)>();
+ private static readonly ManualResetEvent WindowReadyEvent = new ManualResetEvent(false);
+ public static volatile HotkeyForm HotkeyForm = null!;
+ public static volatile IntPtr Handle;
+ private static int _currentId;
- public static void OnHotkeyPressed(ModifierKeys modifier, Key key)
- {
- Hotkeys.ForEach(x =>
+ static GlobalHotKey()
{
- if (modifier == x.modifier && key == x.key)
+ var messageLoopThread = new Thread(delegate ()
{
- x.action();
- }
- });
- }
-
- public static int RegisterHotKey(ModifierKeys modifier, Key key, Action action)
- {
- WindowReadyEvent.WaitOne(); //wait for hotkey window to have initialized
+ Application.Run(new HotkeyForm(WindowReadyEvent));
+ });
+ messageLoopThread.Name = "MessageLoopThread";
+ messageLoopThread.IsBackground = true;
+ messageLoopThread.Start();
+ }
- var virtualKeyCode = (Keys)KeyInterop.VirtualKeyFromKey(key);
- int id = Interlocked.Increment(ref _currentId);
+ public static void OnHotkeyPressed(Hotkey hotkey)
+ {
+ Hotkeys.ForEach(x =>
+ {
+ if (hotkey.Modifiers == x.hotkey.Modifiers && hotkey.Key == x.hotkey.Key)
+ {
+ x.action();
+ }
+ });
+ }
- Delegate register = (Action)(() =>
+ public static int RegisterHotKey(Hotkey hotkey, Action action)
{
- User32.RegisterHotkey(
- Handle,
- id,
- (uint)modifier | 0x4000, //no repeat
- (uint)virtualKeyCode);
- });
+ WindowReadyEvent.WaitOne(); //wait for hotkey window to have initialized
- HotkeyForm?.Invoke(register);
- Hotkeys.Add((id, modifier, key, action));
- return id;
- }
+ var virtualKeyCode = (Keys)KeyInterop.VirtualKeyFromKey(hotkey.Key);
+ int id = Interlocked.Increment(ref _currentId);
- public static void UnregisterHotKey(int id)
- {
- if (Hotkeys.All(i => i.id != id))
- {
- return;
+ Delegate register = (Action)(() =>
+ {
+ User32.RegisterHotkey(
+ Handle,
+ id,
+ (uint)hotkey.Modifiers | 0x4000, //no repeat
+ (uint)virtualKeyCode);
+ });
+
+ HotkeyForm.Invoke(register);
+ Hotkeys.Add((id, hotkey, action));
+ return id;
}
- Delegate unregister = (Action)(() =>
+ public static void UnregisterHotKey(int id)
{
- User32.UnregisterHotkey(Handle, id);
- });
+ if (Hotkeys.All(i => i.id != id))
+ {
+ return;
+ }
- HotkeyForm?.Invoke(unregister);
- Hotkeys.Remove(Hotkeys.Find(i => i.id == id));
- }
-}
+ Delegate unregister = (Action)(() =>
+ {
+ User32.UnregisterHotkey(Handle, id);
+ });
-public class HotkeyForm : Form
-{
- public HotkeyForm(ManualResetEvent windowReadyEvent)
- {
- GlobalHotKey.Handle = Handle;
- GlobalHotKey.HotkeyForm = this;
- windowReadyEvent.Set();
+ HotkeyForm.Invoke(unregister);
+ Hotkeys.Remove(Hotkeys.Find(i => i.id == id));
+ }
}
- protected override void WndProc(ref Message windowMessage)
+ public class HotkeyForm : Form
{
- base.WndProc(ref windowMessage);
+ public HotkeyForm(ManualResetEvent windowReadyEvent)
+ {
+ GlobalHotKey.Handle = Handle;
+ GlobalHotKey.HotkeyForm = this;
+ windowReadyEvent.Set();
+ }
- if (windowMessage.Msg == 0x0312) //0x0312 is the hotkey message
+ protected override void WndProc(ref Message windowMessage)
{
- var key = KeyInterop.KeyFromVirtualKey((int)windowMessage.LParam >> 16 & 0xFFFF);
- var modifier = (ModifierKeys)((int)windowMessage.LParam & 0xFFFF);
- GlobalHotKey.OnHotkeyPressed(modifier, key);
+ base.WndProc(ref windowMessage);
+
+ if (windowMessage.Msg == 0x0312) //0x0312 is the hotkey message
+ {
+ var key = KeyInterop.KeyFromVirtualKey((int)windowMessage.LParam >> 16 & 0xFFFF);
+ var modifier = (ModifierKeys)((int)windowMessage.LParam & 0xFFFF);
+ GlobalHotKey.OnHotkeyPressed(new Hotkey(){Modifiers = modifier, Key = key});
+ }
}
- }
- protected override void SetVisibleCore(bool value)
- {
- base.SetVisibleCore(false);
+ protected override void SetVisibleCore(bool value)
+ {
+ base.SetVisibleCore(false);
+ }
}
}
diff --git a/src/SoulSplitter/Hotkeys/Hotkey.cs b/src/SoulSplitter/Hotkeys/Hotkey.cs
new file mode 100644
index 0000000..39ac277
--- /dev/null
+++ b/src/SoulSplitter/Hotkeys/Hotkey.cs
@@ -0,0 +1,31 @@
+// This file is part of the SoulSplitter distribution (https://github.com/FrankvdStam/SoulSplitter).
+// Copyright (c) 2022 Frank van der Stam.
+// https://github.com/FrankvdStam/SoulSplitter/blob/main/LICENSE
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 3.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Input;
+
+namespace SoulSplitter.Hotkeys
+{
+ public class Hotkey
+ {
+ public ModifierKeys Modifiers { get; set; }
+ public Key Key { get; set; }
+ }
+}
diff --git a/src/SoulSplitter/UI/Converters/HotkeyToStringConverter.cs b/src/SoulSplitter/UI/Converters/HotkeyToStringConverter.cs
new file mode 100644
index 0000000..e684259
--- /dev/null
+++ b/src/SoulSplitter/UI/Converters/HotkeyToStringConverter.cs
@@ -0,0 +1,59 @@
+// This file is part of the SoulSplitter distribution (https://github.com/FrankvdStam/SoulSplitter).
+// Copyright (c) 2022 Frank van der Stam.
+// https://github.com/FrankvdStam/SoulSplitter/blob/main/LICENSE
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 3.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+using SoulSplitter.Hotkeys;
+using SoulSplitter.UI.EldenRing;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+using System.Windows.Input;
+
+namespace SoulSplitter.UI.Converters
+{
+ public class HotkeyToStringConverter : IValueConverter
+ {
+ private static List _modifiers = Enum.GetValues(typeof(ModifierKeys)).Cast().Where(i => i != ModifierKeys.None).ToList();
+
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is Hotkey hotkey)
+ {
+ var sb = new StringBuilder();
+ foreach (var modifier in _modifiers)
+ {
+ if (hotkey.Modifiers.HasFlag(modifier))
+ {
+ sb.Append(modifier);
+ sb.Append(" + ");
+ }
+ }
+ sb.Append(hotkey.Key);
+ return sb.ToString();
+ }
+
+ throw new ArgumentException($"{value} is not a {nameof(Hotkey)}", nameof(value));
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ return "";
+ }
+ }
+}
diff --git a/src/SoulSplitter/UI/EldenRing/EldenRingControl.xaml b/src/SoulSplitter/UI/EldenRing/EldenRingControl.xaml
index a1e16d5..0a9d012 100644
--- a/src/SoulSplitter/UI/EldenRing/EldenRingControl.xaml
+++ b/src/SoulSplitter/UI/EldenRing/EldenRingControl.xaml
@@ -45,6 +45,7 @@
+
@@ -94,462 +95,558 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Immediate
-
-
-
-
- OnLoading
-
-
-
-
- OnBlackscreen
-
-
-
-
-
-
-
-
-
- Boss
-
-
-
-
-
- Grace
-
-
-
-
-
- ItemPickup
-
-
-
-
-
- KnownFlag
-
-
-
-
-
- Position
-
-
-
-
-
- Flag
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+ Width="205"
+ Height="30"
+ SelectedValuePath="Tag"
+ SelectedValue="{Binding NewSplitTimingType}"
+ materialDesign:HintAssist.HelperText="when">
+
+
+
+ Immediate
+
+
+
+
+ OnLoading
+
+
+
+
+ OnBlackscreen
+
+
+
+
+
+
+
+
+
+ Boss
+
+
+
+
+
+ Grace
+
+
+
+
+
+ ItemPickup
+
+
+
+
+
+ KnownFlag
+
+
+
+
+
+ Position
+
+
+
+
+
+ Flag
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/SoulSplitter/UI/EldenRing/EldenRingViewModel.cs b/src/SoulSplitter/UI/EldenRing/EldenRingViewModel.cs
index d5b5de1..22b177c 100644
--- a/src/SoulSplitter/UI/EldenRing/EldenRingViewModel.cs
+++ b/src/SoulSplitter/UI/EldenRing/EldenRingViewModel.cs
@@ -18,8 +18,10 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
+using System.Windows.Input;
using System.Xml.Serialization;
using SoulMemory.EldenRing;
+using SoulSplitter.Hotkeys;
using SoulSplitter.Splits.EldenRing;
using SoulSplitter.UI.Generic;
@@ -29,6 +31,9 @@ public class EldenRingViewModel : ICustomNotifyPropertyChanged
{
public EldenRingViewModel()
{
+ Hotkeys.Add(new FpsPatchHotkey(){ Action = FpsPatchHotkeyAction.SetFpsValue, Hotkey = new Hotkey(){ Key = Key.A, Modifiers = ModifierKeys.Control }, Fps = 33});
+ Hotkeys.Add(new FpsPatchHotkey(){ Action = FpsPatchHotkeyAction.SetFpsValue, Hotkey = new Hotkey(){ Key = Key.B, Modifiers = ModifierKeys.Shift }, Fps = 24});
+ Hotkeys.Add(new FpsPatchHotkey(){ Action = FpsPatchHotkeyAction.RemoveFpsPatch, Hotkey = new Hotkey(){ Key = Key.C, Modifiers = ModifierKeys.Alt }});
}
public bool StartAutomatically
@@ -438,14 +443,29 @@ public void RestoreHierarchy()
#endregion
+ #region Fps hotkeys
- public ObservableCollection Splits { get; set; }= [];
-
- //source lists
- public static ObservableCollection Bosses { get; set; } = new(Enum.GetValues(typeof(Boss)).Cast().Select(i => new BossViewModel(i)));
- public static ObservableCollection Graces { get; set; } = new(Enum.GetValues(typeof(Grace)).Cast().Select(i => new GraceViewModel(i)));
- public static ObservableCollection ItemPickups { get; set; } = new(Enum.GetValues(typeof(ItemPickup)).Cast().Select(i => new ItemPickupViewModel(i)));
- public static ObservableCollection KnownFlags { get; set; } = new(Enum.GetValues(typeof(KnownFlag)).Cast().Select(i => new KnownFlagViewModel(i)));
+ [XmlIgnore]
+ public int NewFpsValue
+ {
+ get => _newFpsValue;
+ set => this.SetField(ref _newFpsValue, value);
+ }
+ private int _newFpsValue = 30;
+
+ public ObservableCollection Hotkeys { get; set; } = new ObservableCollection();
+
+
+
+
+ #endregion
+ public ObservableCollection Splits { get; set; }= new ObservableCollection();
+
+ //source lists
+ public static ObservableCollection Bosses { get; set; } = new ObservableCollection(Enum.GetValues(typeof(Boss)).Cast().Select(i => new BossViewModel(i)));
+ public static ObservableCollection Graces { get; set; } = new ObservableCollection(Enum.GetValues(typeof(Grace)).Cast().Select(i => new GraceViewModel(i)));
+ public static ObservableCollection ItemPickups { get; set; } = new ObservableCollection(Enum.GetValues(typeof(ItemPickup)).Cast().Select(i => new ItemPickupViewModel(i)));
+ public static ObservableCollection KnownFlags { get; set; } = new ObservableCollection(Enum.GetValues(typeof(KnownFlag)).Cast().Select(i => new KnownFlagViewModel(i)));
#region ICustomNotifyPropertyChanged
diff --git a/src/SoulSplitter/UI/EldenRing/FpsPatchHotkey.cs b/src/SoulSplitter/UI/EldenRing/FpsPatchHotkey.cs
new file mode 100644
index 0000000..62d1e15
--- /dev/null
+++ b/src/SoulSplitter/UI/EldenRing/FpsPatchHotkey.cs
@@ -0,0 +1,39 @@
+// This file is part of the SoulSplitter distribution (https://github.com/FrankvdStam/SoulSplitter).
+// Copyright (c) 2022 Frank van der Stam.
+// https://github.com/FrankvdStam/SoulSplitter/blob/main/LICENSE
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 3.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Input;
+using SoulSplitter.Hotkeys;
+
+namespace SoulSplitter.UI.EldenRing
+{
+ public enum FpsPatchHotkeyAction
+ {
+ SetFpsValue,
+ RemoveFpsPatch,
+ }
+
+ public class FpsPatchHotkey
+ {
+ public int Fps { get; set; }
+ public Hotkey Hotkey { get; set; } = null!;
+ public FpsPatchHotkeyAction Action { get; set; }
+ }
+}
diff --git a/src/SoulSplitter/UI/Generic/HotkeyPicker.xaml b/src/SoulSplitter/UI/Generic/HotkeyPicker.xaml
new file mode 100644
index 0000000..fb10904
--- /dev/null
+++ b/src/SoulSplitter/UI/Generic/HotkeyPicker.xaml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/SoulSplitter/UI/Generic/HotkeyPicker.xaml.cs b/src/SoulSplitter/UI/Generic/HotkeyPicker.xaml.cs
new file mode 100644
index 0000000..065d4ad
--- /dev/null
+++ b/src/SoulSplitter/UI/Generic/HotkeyPicker.xaml.cs
@@ -0,0 +1,130 @@
+// This file is part of the SoulSplitter distribution (https://github.com/FrankvdStam/SoulSplitter).
+// Copyright (c) 2022 Frank van der Stam.
+// https://github.com/FrankvdStam/SoulSplitter/blob/main/LICENSE
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 3.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+using System.Collections.Generic;
+using System.Globalization;
+using System.Windows.Forms;
+using System.Windows.Input;
+using SoulSplitter.UI.EldenRing;
+using KeyEventArgs = System.Windows.Input.KeyEventArgs;
+using TextBox = System.Windows.Controls.TextBox;
+using UserControl = System.Windows.Controls.UserControl;
+
+namespace SoulSplitter.UI.Generic
+{
+ ///
+ /// Interaction logic for HotkeyPicker.xaml
+ ///
+ public partial class HotkeyPicker : UserControl
+ {
+ public HotkeyPicker()
+ {
+ InitializeComponent();
+ }
+
+ public class HotkeyCompletedParameter
+ {
+ public object Sender { get; set; } = null!;
+ public ModifierKeys ModifierKeys;
+ public Key Key;
+ }
+
+ public RelayCommand HotkeyCompletedCommand { get; set; } = null!;
+
+ private bool _isActive = false;
+ private ModifierKeys _modifierKeys = ModifierKeys.None;
+ private Key _key = Key.None;
+ private void OnPreviewKeyDown(object sender, KeyEventArgs e)
+ {
+ if (_isActive)
+ {
+ if (e.IsDown && sender is TextBox textBox)
+ {
+ //Get modifier key and remember state
+ if (_modifierKeysLookup.TryGetValue(e.Key, out ModifierKeys modifierKeys))
+ {
+ if (!_modifierKeys.HasFlag(modifierKeys))
+ {
+ if (!string.IsNullOrWhiteSpace(textBox.Text))
+ {
+ textBox.Text += " + ";
+ }
+
+ textBox.Text += modifierKeys;
+ _modifierKeys |= modifierKeys;
+ }
+ }
+ else //get regular key, end listening for keypresses, invoke command
+ {
+ if (!string.IsNullOrWhiteSpace(textBox.Text))
+ {
+ textBox.Text += " + ";
+ }
+
+ textBox.Text += e.Key;
+ _key = e.Key;
+
+ HotkeyCompletedCommand?.Execute(new HotkeyCompletedParameter
+ {
+ Sender = this,
+ Key = _key,
+ ModifierKeys = _modifierKeys
+ });
+ _isActive = false;
+ }
+
+ var converter = new ModifierKeysConverter();
+ e.Handled = true;
+ }
+ }
+ }
+
+ private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
+ {
+ if (!_isActive && sender is TextBox textBox)
+ {
+ _isActive = true;
+ _key = Key.None;
+ _modifierKeys = ModifierKeys.None;
+ textBox.Text = "";
+ }
+ }
+
+ private static Dictionary _modifierKeysLookup = new Dictionary()
+ {
+ { Key.LeftAlt, ModifierKeys.Alt },
+ { Key.RightAlt, ModifierKeys.Alt },
+ { Key.System, ModifierKeys.Alt },
+ { Key.LeftCtrl, ModifierKeys.Control },
+ { Key.RightCtrl, ModifierKeys.Control },
+ { Key.LeftShift, ModifierKeys.Shift },
+ { Key.RightShift, ModifierKeys.Shift },
+ { Key.LWin, ModifierKeys.Windows },
+ { Key.RWin, ModifierKeys.Windows },
+ };
+
+ private void OnPreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
+ {
+ if (_isActive && sender is TextBox textBox)
+ {
+ _isActive = false;
+ _key = Key.None;
+ _modifierKeys = ModifierKeys.None;
+ textBox.Text = "";
+ }
+ }
+ }
+}
diff --git a/src/cli/Program.cs b/src/cli/Program.cs
index 3eccfbe..d86778a 100644
--- a/src/cli/Program.cs
+++ b/src/cli/Program.cs
@@ -42,9 +42,19 @@ internal class Program
static void Main(string[] args)
{
- GlobalHotKey.RegisterHotKey(ModifierKeys.Alt, Key.A, () =>{ Debug.WriteLine("A"); });
- GlobalHotKey.RegisterHotKey(ModifierKeys.Alt, Key.S, () =>{ Debug.WriteLine("S"); });
- GlobalHotKey.RegisterHotKey(ModifierKeys.Alt, Key.D, () =>{ Debug.WriteLine("D"); });
+ TestUi();
+
+ GameLoop((e) =>
+ {
+ var saveSlot = e.GetCurrentSaveSlot();
+ var pos = e.GetPosition();
+ var igtElapsed = TimeSpan.FromMilliseconds(e.GetInGameTimeMilliseconds());
+ Console.WriteLine($"IGT: {igtElapsed} slot: {saveSlot} pos: {pos}");
+ });
+
+ //GlobalHotKey.RegisterHotKey(ModifierKeys.Alt, Key.A, () =>{ Debug.WriteLine("A"); });
+ //GlobalHotKey.RegisterHotKey(ModifierKeys.Alt, Key.S, () =>{ Debug.WriteLine("S"); });
+ //GlobalHotKey.RegisterHotKey(ModifierKeys.Alt, Key.D, () =>{ Debug.WriteLine("D"); });
//TestUi();