优化热键相关代码(未完成)

pull/3405/head
chao wan 2023-03-03 18:03:29 +08:00
parent ae17e0c264
commit c40d88d0b6
6 changed files with 175 additions and 77 deletions

1
.gitignore vendored
View File

@ -16,3 +16,4 @@
/v2rayN/v2rayUpgrade/bin/Release
/v2rayN/v2rayUpgrade/obj/
*.user
/.vs/v2rayN

View File

@ -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
}
}
}

View File

@ -343,48 +343,11 @@ namespace v2rayN.Handler
}
}
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();
}
}

View File

@ -1,5 +1,4 @@
using System.Windows.Forms;
using System.Windows.Input;
namespace v2rayN.Mode
{
[Serializable]
@ -144,7 +143,7 @@ namespace v2rayN.Mode
public bool Shift { get; set; }
public Keys? KeyCode { get; set; }
public Key? KeyCode { get; set; }
}

View File

@ -630,27 +630,26 @@ namespace v2rayN.ViewModels
}
}
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)
{

View File

@ -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;
@ -12,37 +13,23 @@ namespace v2rayN.Views
{
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;
@ -63,7 +50,7 @@ namespace v2rayN.Views
{
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;
@ -74,6 +61,18 @@ namespace v2rayN.Views
}
}
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++)