Skip to content

Commit

Permalink
优化热键相关代码(未完成)
Browse files Browse the repository at this point in the history
  • Loading branch information
hvvvvvvv committed Mar 3, 2023
1 parent ae17e0c commit c40d88d
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 77 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
/v2rayN/v2rayUpgrade/bin/Release
/v2rayN/v2rayUpgrade/obj/
*.user
/.vs/v2rayN
137 changes: 137 additions & 0 deletions v2rayN/v2rayN/Handler/HotkeyHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using v2rayN.Mode;
using v2rayN.Resx;

namespace v2rayN.Handler
{
public sealed class HotkeyHandler
{
private static readonly Lazy<HotkeyHandler> _instance = new(() => new());
public static HotkeyHandler Instance = _instance.Value;

private const int WmHotkey = 0x0312;
private Config _config
{
get => LazyConfig.Instance.GetConfig();
}
private Dictionary<int, List<EGlobalHotkey>> _hotkeyTriggerDic;

public bool IsPause { get; private set; } = false;
public event Action<bool, string>? UpdateViewEvent;
public event Action<EGlobalHotkey>? HotkeyTriggerEvent;
public HotkeyHandler()
{
_hotkeyTriggerDic = new();
ComponentDispatcher.ThreadPreprocessMessage += OnThreadPreProcessMessage;
Init();
}

private void Init()
{
_hotkeyTriggerDic.Clear();
if (_config.globalHotkeys == null) return;
foreach(var item in _config.globalHotkeys)
{
if (item.KeyCode != null && item.KeyCode != Key.None)
{
int key = KeyInterop.VirtualKeyFromKey((Key)item.KeyCode);
KeyModifiers modifiers = KeyModifiers.None;
if (item.Control) modifiers |= KeyModifiers.Ctrl;
if (item.Shift) modifiers |= KeyModifiers.Shift;
if (item.Alt) modifiers |= KeyModifiers.Alt;
key = (key << 16) | (int)modifiers;
if (!_hotkeyTriggerDic.ContainsKey(key))
{
_hotkeyTriggerDic.Add(key, new() { item.eGlobalHotkey });
}
else
{
if (!_hotkeyTriggerDic[key].Contains(item.eGlobalHotkey))
_hotkeyTriggerDic[key].Add(item.eGlobalHotkey);
}
}
}
}
public void Load()
{
foreach(var hotkey in _hotkeyTriggerDic.Keys)
{
var _fsModifiers = hotkey & 0xffff;
var _vkey = (hotkey >> 16) & 0xffff;
var hotkeyStr = HotkeyToString(_fsModifiers, _vkey);
bool isSuccess = false;
string msg;

Application.Current.Dispatcher.Invoke(() =>
{
isSuccess = RegisterHotKey(IntPtr.Zero, hotkey, _fsModifiers, _vkey);
});
if (isSuccess)
{
msg = string.Format(ResUI.RegisterGlobalHotkeySuccessfully, $"{hotkeyStr}");
}
else
{
var errInfo = new Win32Exception(Marshal.GetLastWin32Error()).Message;
msg = string.Format(ResUI.RegisterGlobalHotkeyFailed, $"{hotkeyStr}", errInfo);
}
UpdateViewEvent?.Invoke(false, msg);
}
}

public void ReLoad()
{
foreach(var hotkey in _hotkeyTriggerDic.Keys)
{
Application.Current.Dispatcher.Invoke(() =>
{
UnregisterHotKey(IntPtr.Zero, hotkey);
});
}
Init();
Load();
}

private void OnThreadPreProcessMessage(ref MSG msg, ref bool handled)
{
if (msg.message != WmHotkey || IsPause || !_hotkeyTriggerDic.Keys.Contains((int)msg.lParam))
return;
handled = true;
foreach (var keyEvent in _hotkeyTriggerDic[(int)msg.lParam])
{
HotkeyTriggerEvent?.Invoke(keyEvent);
}
}
[DllImport("user32.dll", SetLastError = true)]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);

[DllImport("user32.dll", SetLastError = true)]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
private static string HotkeyToString(int fsModifiers,int vk)
{
var sb = new StringBuilder();
var mdif = (KeyModifiers)fsModifiers;
var key = KeyInterop.KeyFromVirtualKey(vk);
if ((mdif | KeyModifiers.Ctrl) == KeyModifiers.Ctrl) sb.Append($"{KeyModifiers.Ctrl}+");
if ((mdif | KeyModifiers.Alt) == KeyModifiers.Alt) sb.Append($"{KeyModifiers.Alt}+");
if ((mdif | KeyModifiers.Shift) == KeyModifiers.Shift) sb.Append($"{KeyModifiers.Shift}+");
sb.Append(key.ToString());
return sb.ToString();
}
[Flags]
private enum KeyModifiers
{
None = 0x0000,
Alt = 0x0001,
Ctrl = 0x0002,
Shift = 0x0004,
Win = 0x0008,
NoRepeat = 0x4000
}
}
}
45 changes: 4 additions & 41 deletions v2rayN/v2rayN/Handler/MainFormHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -343,48 +343,11 @@ private void UpdateTaskRun(Config config, Action<bool, string> update)
}
}

public void RegisterGlobalHotkey(Config config, EventHandler<HotkeyEventArgs> handler, Action<bool, string> update)
public void RegisterGlobalHotkey(Config config, Action<EGlobalHotkey> handler, Action<bool, string> update)
{
if (config.globalHotkeys == null)
{
return;
}

foreach (var item in config.globalHotkeys)
{
if (item.KeyCode == null)
{
continue;
}

var modifiers = ModifierKeys.None;
if (item.Control)
{
modifiers |= ModifierKeys.Control;
}
if (item.Alt)
{
modifiers |= ModifierKeys.Alt;
}
if (item.Shift)
{
modifiers |= ModifierKeys.Shift;
}

var gesture = new KeyGesture(KeyInterop.KeyFromVirtualKey((int)item.KeyCode), modifiers);
try
{
HotkeyManager.Current.AddOrReplace(((int)item.eGlobalHotkey).ToString(), gesture, handler);
var msg = string.Format(ResUI.RegisterGlobalHotkeySuccessfully, $"{item.eGlobalHotkey}");
update(false, msg);
}
catch (Exception ex)
{
var msg = string.Format(ResUI.RegisterGlobalHotkeyFailed, $"{item.eGlobalHotkey}", ex.Message);
update(false, msg);
Utils.SaveLog(msg);
}
}
HotkeyHandler.Instance.UpdateViewEvent += update;
HotkeyHandler.Instance.HotkeyTriggerEvent += handler;
HotkeyHandler.Instance.Load();
}

}
Expand Down
5 changes: 2 additions & 3 deletions v2rayN/v2rayN/Mode/ConfigItems.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Windows.Forms;

using System.Windows.Input;
namespace v2rayN.Mode
{
[Serializable]
Expand Down Expand Up @@ -144,7 +143,7 @@ public class KeyEventItem

public bool Shift { get; set; }

public Keys? KeyCode { get; set; }
public Key? KeyCode { get; set; }

}

Expand Down
15 changes: 7 additions & 8 deletions v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -630,27 +630,26 @@ private void SetTestResult(string indexId, string delay, string speed)
}
}

private void OnHotkeyHandler(object sender, HotkeyEventArgs e)
private void OnHotkeyHandler(EGlobalHotkey e)
{
switch (Utils.ToInt(e.Name))
switch (e)
{
case (int)EGlobalHotkey.ShowForm:
case EGlobalHotkey.ShowForm:
ShowHideWindow(null);
break;
case (int)EGlobalHotkey.SystemProxyClear:
case EGlobalHotkey.SystemProxyClear:
SetListenerType(ESysProxyType.ForcedClear);
break;
case (int)EGlobalHotkey.SystemProxySet:
case EGlobalHotkey.SystemProxySet:
SetListenerType(ESysProxyType.ForcedChange);
break;
case (int)EGlobalHotkey.SystemProxyUnchanged:
case EGlobalHotkey.SystemProxyUnchanged:
SetListenerType(ESysProxyType.Unchanged);
break;
case (int)EGlobalHotkey.SystemProxyPac:
case EGlobalHotkey.SystemProxyPac:
SetListenerType(ESysProxyType.Pac);
break;
}
e.Handled = true;
}
public void MyAppExit(bool blWindowsShutDown)
{
Expand Down
49 changes: 24 additions & 25 deletions v2rayN/v2rayN/Views/GlobalHotkeySettingWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Windows;
using Microsoft.Win32.TaskScheduler;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using v2rayN.Handler;
Expand All @@ -12,37 +13,23 @@ public partial class GlobalHotkeySettingWindow
{
private static Config _config;
List<KeyEventItem> lstKey;
private Dictionary<object, KeyEventItem> _TextBoxKeyEventItem;

public GlobalHotkeySettingWindow()
{
InitializeComponent();
this.Owner = Application.Current.MainWindow;
_config = LazyConfig.Instance.GetConfig();
_config.globalHotkeys ??= new List<KeyEventItem>();

if (_config.globalHotkeys == null)
_TextBoxKeyEventItem = new()
{
_config.globalHotkeys = new List<KeyEventItem>();
}

foreach (EGlobalHotkey it in Enum.GetValues(typeof(EGlobalHotkey)))
{
if (_config.globalHotkeys.FindIndex(t => t.eGlobalHotkey == it) >= 0)
{
continue;
}

_config.globalHotkeys.Add(new KeyEventItem()
{
eGlobalHotkey = it,
Alt = false,
Control = false,
Shift = false,
KeyCode = null
});
}

lstKey = Utils.DeepCopy(_config.globalHotkeys);

{ txtGlobalHotkey0,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.ShowForm) },
{ txtGlobalHotkey1,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.SystemProxyClear) },
{ txtGlobalHotkey2,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.SystemProxySet) },
{ txtGlobalHotkey3,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.SystemProxyUnchanged)},
{ txtGlobalHotkey4,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.SystemProxyPac)}
};
txtGlobalHotkey0.KeyDown += TxtGlobalHotkey_KeyDown;
txtGlobalHotkey1.KeyDown += TxtGlobalHotkey_KeyDown;
txtGlobalHotkey2.KeyDown += TxtGlobalHotkey_KeyDown;
Expand All @@ -63,7 +50,7 @@ private void TxtGlobalHotkey_KeyDown(object sender, KeyEventArgs e)
{
var txt = ((TextBox)sender);
var index = Utils.ToInt(txt.Name.Substring(txt.Name.Length - 1, 1));
var formsKey = (Forms.Keys)KeyInterop.VirtualKeyFromKey(e.Key == Key.System ? e.SystemKey : e.Key);
var formsKey = e.Key == Key.System ? e.SystemKey : e.Key;

lstKey[index].KeyCode = formsKey;
lstKey[index].Alt = (Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt;
Expand All @@ -74,6 +61,18 @@ private void TxtGlobalHotkey_KeyDown(object sender, KeyEventArgs e)
}
}

private KeyEventItem GetKeyEventItemByEGlobalHotkey(List<KeyEventItem> KELsit,EGlobalHotkey eg)
{
return Utils.DeepCopy(KELsit.Find((it) => it.eGlobalHotkey == eg) ?? new()
{
eGlobalHotkey = eg,
Control = false,
Alt = false,
Shift = false,
KeyCode = null
});

}
private void BindingData(int index)
{
for (int k = 0; k < lstKey.Count; k++)
Expand Down

0 comments on commit c40d88d

Please sign in to comment.