diff --git a/STranslate/MainWindow.xaml b/STranslate/MainWindow.xaml index 0a98fe5..5b5223e 100644 --- a/STranslate/MainWindow.xaml +++ b/STranslate/MainWindow.xaml @@ -4,8 +4,8 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:STranslate" - xmlns:vm="clr-namespace:STranslate.ViewModel" xmlns:hc="https://handyorg.github.io/handycontrol" + xmlns:vm="clr-namespace:STranslate.ViewModel" mc:Ignorable="d" Background="Transparent" WindowStartupLocation="CenterScreen" @@ -20,6 +20,9 @@ Height="450" Width="400" Icon="/Images/translate2.ico"> + + + @@ -30,8 +33,7 @@ - + diff --git a/STranslate/MainWindow.xaml.cs b/STranslate/MainWindow.xaml.cs index dd29a7e..461474d 100644 --- a/STranslate/MainWindow.xaml.cs +++ b/STranslate/MainWindow.xaml.cs @@ -12,57 +12,14 @@ namespace STranslate /// public partial class MainWindow : Window { + private MainVM vm; public MainWindow() { InitializeComponent(); - InitHwnd(); - InitTray(); - - this.DataContext = MainVM.Instance; - } - - private void InitHwnd() - { - var helper = new WindowInteropHelper(this); - helper.EnsureHandle(); + vm = (MainVM)this.DataContext; } - /// - /// 初始化托盘 - /// - private void InitTray() - { - //notifyIcon.BalloonTipText = "程序开始运行"; - //notifyIcon.ShowBalloonTip(1000); - notifyIcon.Text = "STranslate"; - notifyIcon.Icon = new System.Drawing.Icon(@"D:\CodePepo\STranslate\STranslate\Images\translate2.ico"); - notifyIcon.Visible = true; - - System.Windows.Forms.MenuItem inputTranslateButton = new System.Windows.Forms.MenuItem("输入翻译"); - inputTranslateButton.Click += new EventHandler(InputTranslate_Click); - - System.Windows.Forms.MenuItem crosswordTranslateButton = new System.Windows.Forms.MenuItem("划词翻译"); - crosswordTranslateButton.Click += new EventHandler(CrosswordTranslate_Click); - - System.Windows.Forms.MenuItem screenshotTranslationButton = new System.Windows.Forms.MenuItem("截图翻译"); - screenshotTranslationButton.Click += new EventHandler(ScreenshotTranslation_Click); - - System.Windows.Forms.MenuItem openMainWinButton = new System.Windows.Forms.MenuItem("显示主窗口"); - openMainWinButton.Click += new EventHandler(OpenMainWin_Click); - - System.Windows.Forms.MenuItem exitButton = new System.Windows.Forms.MenuItem("退出"); - exitButton.Click += new EventHandler(Exit_Click); - - System.Windows.Forms.MenuItem[] childen = new System.Windows.Forms.MenuItem[] { - inputTranslateButton, - crosswordTranslateButton, - screenshotTranslationButton, - openMainWinButton, - exitButton - }; - notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen); - } /// /// 显示主窗口 /// @@ -83,6 +40,7 @@ namespace STranslate { DragMove(); } + /// /// 软件运行时快捷键 /// @@ -94,15 +52,15 @@ namespace STranslate if (e.Key == Key.Escape) { this.Hide(); - MainVM.Instance.InputTxt = string.Empty; - MainVM.Instance.OutputTxt = string.Empty; + vm.InputTxt = string.Empty; + vm.OutputTxt = string.Empty; } //退出 Ctrl+Shift+Q if (e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Control) && e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Shift) && e.Key == Key.Q) { - Exit_Click(null, null); + Environment.Exit(0); } #if false //置顶/取消置顶 Ctrl+T @@ -139,6 +97,7 @@ namespace STranslate } #endif } + /// /// 监听全局快捷键 /// @@ -146,38 +105,10 @@ namespace STranslate protected override void OnSourceInitialized(EventArgs e) { IntPtr handle = new WindowInteropHelper(this).Handle; - HotKeysUtil2.RegisterHotKey(handle); + HotKeysUtil.RegisterHotKey(handle); HwndSource source = HwndSource.FromHwnd(handle); source.AddHook(WndProc); - -#if false - HotkeysUtil.InitialHook(this); - HotkeysUtil.Regist(HotkeyModifiers.MOD_ALT, Key.A, () => - { - this.Show(); - this.Activate(); - this.TextBoxInput.Focus(); - }); - HotkeysUtil.Regist(HotkeyModifiers.MOD_ALT, Key.D, () => - { - //复制内容 - KeyboardUtil.Press(Key.LeftCtrl); - KeyboardUtil.Type(Key.C); - KeyboardUtil.Release(Key.LeftCtrl); - System.Threading.Thread.Sleep(200); - System.Diagnostics.Debug.Print(Clipboard.GetText()); - - //this.Show(); - //this.Activate(); - //this.TextBoxInput.Text = "123"; - - //this.TextBoxInput.Text = Clipboard.GetText(); - //this.TextBoxInput.Focus(); - - //KeyboardUtil.Type(Key.Enter); - }); -#endif } /// /// 热键的功能 @@ -189,17 +120,17 @@ namespace STranslate { case 0x0312: //这个是window消息定义的 注册的热键消息 //Console.WriteLine(wParam.ToString()); - if (wParam.ToString().Equals(HotKeysUtil2.InputTranslateId + "")) + if (wParam.ToString().Equals(HotKeysUtil.InputTranslateId + "")) { - this.InputTranslate_Click(null, null); + this.InputTranslateMenuItem_Click(null, null); } - else if (wParam.ToString().Equals(HotKeysUtil2.CrosswordTranslateId + "")) + else if (wParam.ToString().Equals(HotKeysUtil.CrosswordTranslateId + "")) { - this.CrosswordTranslate_Click(null, null); + this.CrossWordTranslateMenuItem_Click(null, null); } - else if (wParam.ToString().Equals(HotKeysUtil2.ScreenShotTranslateId + "")) + else if (wParam.ToString().Equals(HotKeysUtil.ScreenShotTranslateId + "")) { - this.ScreenshotTranslation_Click(null, null); + this.ScreenshotTranslateMenuItem_Click(null, null); } break; } @@ -217,28 +148,13 @@ namespace STranslate } /// - /// 截图翻译 + /// 清空输入输出框 /// - /// - /// - private void ScreenshotTranslation_Click(object sender, EventArgs e) + private void ClearTextBox() { - MessageBox.Show("开发中"); - } + vm.InputTxt = string.Empty; + vm.OutputTxt = string.Empty; - /// - /// 划词翻译 - /// - /// - /// - private void CrosswordTranslate_Click(object sender, EventArgs e) - { - ClearTextBox(); - var sentence = GetWords.Get(); - this.Show(); - this.Activate(); - this.TextBoxInput.Text = sentence.Trim(); - _ = MainVM.Instance.Translate(); } /// @@ -246,37 +162,36 @@ namespace STranslate /// /// /// - private void InputTranslate_Click(object sender, EventArgs e) + private void InputTranslateMenuItem_Click(object sender, RoutedEventArgs e) { ClearTextBox(); - Show(); - Activate(); + OpenMainWin_Click(null, null); TextBoxInput.Focus(); } /// - /// 退出程序 + /// 划词翻译 /// /// /// - private void Exit_Click(object sender, EventArgs e) + private void CrossWordTranslateMenuItem_Click(object sender, RoutedEventArgs e) { - notifyIcon.Dispose(); - Environment.Exit(0); + ClearTextBox(); + var sentence = GetWords.Get(); + this.Show(); + this.Activate(); + this.TextBoxInput.Text = sentence.Trim(); + _ = vm.Translate(); } /// - /// 清空输入输出框 + /// 截图翻译 /// - private void ClearTextBox() + /// + /// + private void ScreenshotTranslateMenuItem_Click(object sender, RoutedEventArgs e) { - MainVM.Instance.InputTxt = string.Empty; - MainVM.Instance.OutputTxt = string.Empty; - + MessageBox.Show("开发中"); } - /// - /// 托盘图标 - /// - private System.Windows.Forms.NotifyIcon notifyIcon = new System.Windows.Forms.NotifyIcon(); } } \ No newline at end of file diff --git a/STranslate/Model/HotKeys.cs b/STranslate/Model/HotKeys.cs index 9b51bef..739fd81 100644 --- a/STranslate/Model/HotKeys.cs +++ b/STranslate/Model/HotKeys.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using static STranslate.Utils.NativeMethod; namespace STranslate.Model { @@ -10,21 +11,21 @@ namespace STranslate.Model { public static class InputTranslate { - public static byte Modifiers = 1; + public static byte Modifiers = (byte)KeyModifiers.Alt; public static int Key = 65; public static String Text = "A"; public static bool Conflict = false; } public static class CrosswordTranslate { - public static byte Modifiers = 0; - public static int Key = 113; - public static String Text = "F2"; + public static byte Modifiers = (byte)KeyModifiers.Ctrl; + public static int Key = 68; + //public static String Text = "F2"; public static bool Conflict = false; } public static class ScreenShotTranslate { - public static byte Modifiers = 1; + public static byte Modifiers = (byte)KeyModifiers.Alt; public static int Key = 83; public static String Text = "S"; public static bool Conflict = false; diff --git a/STranslate/STranslate.csproj b/STranslate/STranslate.csproj index ac86cf1..a69fdf9 100644 --- a/STranslate/STranslate.csproj +++ b/STranslate/STranslate.csproj @@ -89,9 +89,7 @@ - - diff --git a/STranslate/Utils/HotKeysUtil.cs b/STranslate/Utils/HotKeysUtil.cs index b4cd3c1..671990e 100644 --- a/STranslate/Utils/HotKeysUtil.cs +++ b/STranslate/Utils/HotKeysUtil.cs @@ -1,97 +1,94 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Windows; -using System.Windows.Input; -using System.Windows.Interop; +using STranslate.Model; +using System; namespace STranslate.Utils { - //TODO: 另一个方案: https://www.cnblogs.com/leolion/p/4693514.html - /// - /// 引用自 https://blog.csdn.net/weixin_44879611/article/details/103275347 - /// - internal static class HotkeysUtil + internal class HotKeysUtil { - #region 系统api + public static IntPtr mainFormHandle; - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool RegisterHotKey(IntPtr hWnd, int id, HotkeyModifiers fsModifiers, uint vk); - - [DllImport("user32.dll")] - private static extern bool UnregisterHotKey(IntPtr hWnd, int id); - - #endregion 系统api + public static int InputTranslateId = 854; + public static byte InputTranslateModifiers; + public static int InputTranslateKey; + public static int CrosswordTranslateId = 855; + public static byte CrosswordTranslateModifiers; + public static int CrosswordTranslateKey; + public static int ScreenShotTranslateId = 856; + public static byte ScreenShotTranslateModifiers; + public static int ScreenShotTranslateKey; + public static void RegisterHotKey(IntPtr mainFormHandle) + { + HotKeysUtil.mainFormHandle = mainFormHandle; - public static IntPtr hwnd; + InputTranslateModifiers = HotKeys.InputTranslate.Modifiers; + InputTranslateKey = HotKeys.InputTranslate.Key; + CrosswordTranslateModifiers = HotKeys.CrosswordTranslate.Modifiers; + CrosswordTranslateKey = HotKeys.CrosswordTranslate.Key; + ScreenShotTranslateModifiers = HotKeys.ScreenShotTranslate.Modifiers; + ScreenShotTranslateKey = HotKeys.ScreenShotTranslate.Key; - public static void InitialHook(Window window) - { - hwnd = new WindowInteropHelper(window).Handle; - var _hwndSource = HwndSource.FromHwnd(hwnd); - _hwndSource.AddHook(WndProc); + if (HotKeys.InputTranslate.Key != 0) + { + HotKeys.InputTranslate.Conflict = !NativeMethod.RegisterHotKey(mainFormHandle, InputTranslateId, HotKeys.InputTranslate.Modifiers, HotKeys.InputTranslate.Key); + } + if (HotKeys.CrosswordTranslate.Key != 0) + { + HotKeys.CrosswordTranslate.Conflict = !NativeMethod.RegisterHotKey(mainFormHandle, CrosswordTranslateId, HotKeys.CrosswordTranslate.Modifiers, HotKeys.CrosswordTranslate.Key); + } + if (HotKeys.ScreenShotTranslate.Key != 0) + { + HotKeys.ScreenShotTranslate.Conflict = !NativeMethod.RegisterHotKey(mainFormHandle, ScreenShotTranslateId, HotKeys.ScreenShotTranslate.Modifiers, HotKeys.ScreenShotTranslate.Key); + } } - /// - /// 注册快捷键 - /// - /// 持有快捷键窗口 - /// 组合键 - /// 快捷键 - /// 回调函数 - public static void Regist(HotkeyModifiers fsModifiers, Key key, HotKeyCallBackHanlder callBack) + public static void UnRegisterHotKey() { - int id = keyid++; - - var vk = KeyInterop.VirtualKeyFromKey(key); - if (!RegisterHotKey(hwnd, id, fsModifiers, (uint)vk)) - throw new Exception("regist hotkey fail."); - keymap[id] = callBack; + NativeMethod.UnregisterHotKey(mainFormHandle, InputTranslateId); + NativeMethod.UnregisterHotKey(mainFormHandle, CrosswordTranslateId); + NativeMethod.UnregisterHotKey(mainFormHandle, ScreenShotTranslateId); } - /// - /// 快捷键消息处理 - /// - private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) + public static void ReRegisterHotKey() { - if (msg == WM_HOTKEY) + if (HotKeys.InputTranslate.Key == 0) + { + NativeMethod.UnregisterHotKey(mainFormHandle, InputTranslateId); + } + else if (InputTranslateModifiers != HotKeys.InputTranslate.Modifiers || InputTranslateKey != HotKeys.InputTranslate.Key) { - int id = wParam.ToInt32(); - if (keymap.TryGetValue(id, out var callback)) { - callback(); + NativeMethod.UnregisterHotKey(mainFormHandle, InputTranslateId); + HotKeys.InputTranslate.Conflict = !NativeMethod.RegisterHotKey(mainFormHandle, InputTranslateId, HotKeys.InputTranslate.Modifiers, HotKeys.InputTranslate.Key); } } - return IntPtr.Zero; - } + InputTranslateModifiers = HotKeys.InputTranslate.Modifiers; + InputTranslateKey = HotKeys.InputTranslate.Key; - /// - /// 注销快捷键 - /// - /// 持有快捷键窗口的句柄 - /// 回调函数 - public static void UnRegist(IntPtr hWnd, HotKeyCallBackHanlder callBack) - { - foreach (KeyValuePair var in keymap) + if (HotKeys.CrosswordTranslate.Key == 0) { - if (var.Value == callBack) - UnregisterHotKey(hWnd, var.Key); + NativeMethod.UnregisterHotKey(mainFormHandle, CrosswordTranslateId); } - } - - private const int WM_HOTKEY = 0x312; - private static int keyid = 10; - private static Dictionary keymap = new Dictionary(); - - public delegate void HotKeyCallBackHanlder(); - } + else if (CrosswordTranslateModifiers != HotKeys.CrosswordTranslate.Modifiers || CrosswordTranslateKey != HotKeys.CrosswordTranslate.Key) + { + { + NativeMethod.UnregisterHotKey(mainFormHandle, CrosswordTranslateId); + HotKeys.CrosswordTranslate.Conflict = !NativeMethod.RegisterHotKey(mainFormHandle, CrosswordTranslateId, HotKeys.CrosswordTranslate.Modifiers, HotKeys.CrosswordTranslate.Key); + } + } + CrosswordTranslateModifiers = HotKeys.CrosswordTranslate.Modifiers; + CrosswordTranslateKey = HotKeys.CrosswordTranslate.Key; - internal enum HotkeyModifiers - { - MOD_ALT = 0x1, - MOD_CONTROL = 0x2, - MOD_SHIFT = 0x4, - MOD_WIN = 0x8 + if (HotKeys.ScreenShotTranslate.Key == 0) + { + NativeMethod.UnregisterHotKey(mainFormHandle, ScreenShotTranslateId); + } + else if (ScreenShotTranslateModifiers != HotKeys.ScreenShotTranslate.Modifiers || ScreenShotTranslateKey != HotKeys.ScreenShotTranslate.Key) + { + NativeMethod.UnregisterHotKey(mainFormHandle, ScreenShotTranslateId); + HotKeys.ScreenShotTranslate.Conflict = !NativeMethod.RegisterHotKey(mainFormHandle, ScreenShotTranslateId, HotKeys.ScreenShotTranslate.Modifiers, HotKeys.ScreenShotTranslate.Key); + } + ScreenShotTranslateModifiers = HotKeys.ScreenShotTranslate.Modifiers; + ScreenShotTranslateKey = HotKeys.ScreenShotTranslate.Key; + } } -} \ No newline at end of file +} diff --git a/STranslate/Utils/HotKeysUtil2.cs b/STranslate/Utils/HotKeysUtil2.cs deleted file mode 100644 index ea55568..0000000 --- a/STranslate/Utils/HotKeysUtil2.cs +++ /dev/null @@ -1,94 +0,0 @@ -using STranslate.Model; -using System; - -namespace STranslate.Utils -{ - internal class HotKeysUtil2 - { - public static IntPtr mainFormHandle; - - public static int InputTranslateId = 854; - public static byte InputTranslateModifiers; - public static int InputTranslateKey; - public static int CrosswordTranslateId = 855; - public static byte CrosswordTranslateModifiers; - public static int CrosswordTranslateKey; - public static int ScreenShotTranslateId = 856; - public static byte ScreenShotTranslateModifiers; - public static int ScreenShotTranslateKey; - public static void RegisterHotKey(IntPtr mainFormHandle) - { - HotKeysUtil2.mainFormHandle = mainFormHandle; - - InputTranslateModifiers = HotKeys.InputTranslate.Modifiers; - InputTranslateKey = HotKeys.InputTranslate.Key; - CrosswordTranslateModifiers = HotKeys.CrosswordTranslate.Modifiers; - CrosswordTranslateKey = HotKeys.CrosswordTranslate.Key; - ScreenShotTranslateModifiers = HotKeys.ScreenShotTranslate.Modifiers; - ScreenShotTranslateKey = HotKeys.ScreenShotTranslate.Key; - - if (HotKeys.InputTranslate.Key != 0) - { - HotKeys.InputTranslate.Conflict = !NativeMethod.RegisterHotKey(mainFormHandle, InputTranslateId, HotKeys.InputTranslate.Modifiers, HotKeys.InputTranslate.Key); - } - if (HotKeys.CrosswordTranslate.Key != 0) - { - HotKeys.CrosswordTranslate.Conflict = !NativeMethod.RegisterHotKey(mainFormHandle, CrosswordTranslateId, HotKeys.CrosswordTranslate.Modifiers, HotKeys.CrosswordTranslate.Key); - } - if (HotKeys.ScreenShotTranslate.Key != 0) - { - HotKeys.ScreenShotTranslate.Conflict = !NativeMethod.RegisterHotKey(mainFormHandle, ScreenShotTranslateId, HotKeys.ScreenShotTranslate.Modifiers, HotKeys.ScreenShotTranslate.Key); - } - } - - public static void UnRegisterHotKey() - { - NativeMethod.UnregisterHotKey(mainFormHandle, InputTranslateId); - NativeMethod.UnregisterHotKey(mainFormHandle, CrosswordTranslateId); - NativeMethod.UnregisterHotKey(mainFormHandle, ScreenShotTranslateId); - } - - public static void ReRegisterHotKey() - { - if (HotKeys.InputTranslate.Key == 0) - { - NativeMethod.UnregisterHotKey(mainFormHandle, InputTranslateId); - } - else if (InputTranslateModifiers != HotKeys.InputTranslate.Modifiers || InputTranslateKey != HotKeys.InputTranslate.Key) - { - { - NativeMethod.UnregisterHotKey(mainFormHandle, InputTranslateId); - HotKeys.InputTranslate.Conflict = !NativeMethod.RegisterHotKey(mainFormHandle, InputTranslateId, HotKeys.InputTranslate.Modifiers, HotKeys.InputTranslate.Key); - } - } - InputTranslateModifiers = HotKeys.InputTranslate.Modifiers; - InputTranslateKey = HotKeys.InputTranslate.Key; - - if (HotKeys.CrosswordTranslate.Key == 0) - { - NativeMethod.UnregisterHotKey(mainFormHandle, CrosswordTranslateId); - } - else if (CrosswordTranslateModifiers != HotKeys.CrosswordTranslate.Modifiers || CrosswordTranslateKey != HotKeys.CrosswordTranslate.Key) - { - { - NativeMethod.UnregisterHotKey(mainFormHandle, CrosswordTranslateId); - HotKeys.CrosswordTranslate.Conflict = !NativeMethod.RegisterHotKey(mainFormHandle, CrosswordTranslateId, HotKeys.CrosswordTranslate.Modifiers, HotKeys.CrosswordTranslate.Key); - } - } - CrosswordTranslateModifiers = HotKeys.CrosswordTranslate.Modifiers; - CrosswordTranslateKey = HotKeys.CrosswordTranslate.Key; - - if (HotKeys.ScreenShotTranslate.Key == 0) - { - NativeMethod.UnregisterHotKey(mainFormHandle, ScreenShotTranslateId); - } - else if (ScreenShotTranslateModifiers != HotKeys.ScreenShotTranslate.Modifiers || ScreenShotTranslateKey != HotKeys.ScreenShotTranslate.Key) - { - NativeMethod.UnregisterHotKey(mainFormHandle, ScreenShotTranslateId); - HotKeys.ScreenShotTranslate.Conflict = !NativeMethod.RegisterHotKey(mainFormHandle, ScreenShotTranslateId, HotKeys.ScreenShotTranslate.Modifiers, HotKeys.ScreenShotTranslate.Key); - } - ScreenShotTranslateModifiers = HotKeys.ScreenShotTranslate.Modifiers; - ScreenShotTranslateKey = HotKeys.ScreenShotTranslate.Key; - } - } -} diff --git a/STranslate/Utils/KeyboardUtil.cs b/STranslate/Utils/KeyboardUtil.cs deleted file mode 100644 index cf4959c..0000000 --- a/STranslate/Utils/KeyboardUtil.cs +++ /dev/null @@ -1,538 +0,0 @@ -using System; -using System.ComponentModel; -using System.Linq; -using System.Runtime.InteropServices; -using System.Security; -using System.Security.Permissions; -using System.Windows.Input; - -namespace STranslate.Utils -{ - #region Operate Mouse Keyboard - - //引用自: https://www.cnblogs.com/sixty/archive/2009/08/09/1542210.html - /// - /// Native methods - /// - internal static class NativeMethods - { - //User32 wrappers cover API's used for Mouse input - - #region User32 - - // Two special bitmasks we define to be able to grab - // shift and character information out of a VKey. - internal const int VKeyShiftMask = 0x0100; - - internal const int VKeyCharMask = 0x00FF; - - // Various Win32 constants - internal const int KeyeventfExtendedkey = 0x0001; - - internal const int KeyeventfKeyup = 0x0002; - internal const int KeyeventfScancode = 0x0008; - - internal const int MouseeventfVirtualdesk = 0x4000; - - internal const int SMXvirtualscreen = 76; - internal const int SMYvirtualscreen = 77; - internal const int SMCxvirtualscreen = 78; - internal const int SMCyvirtualscreen = 79; - - internal const int XButton1 = 0x0001; - internal const int XButton2 = 0x0002; - internal const int WheelDelta = 120; - - internal const int InputMouse = 0; - internal const int InputKeyboard = 1; - - // Various Win32 data structures - [StructLayout(LayoutKind.Sequential)] - internal struct INPUT - { - internal int type; - internal INPUTUNION union; - }; - - [StructLayout(LayoutKind.Explicit)] - internal struct INPUTUNION - { - [FieldOffset(0)] - internal MOUSEINPUT mouseInput; - - [FieldOffset(0)] - internal KEYBDINPUT keyboardInput; - }; - - [StructLayout(LayoutKind.Sequential)] - internal struct MOUSEINPUT - { - internal int dx; - internal int dy; - internal int mouseData; - internal int dwFlags; - internal int time; - internal IntPtr dwExtraInfo; - }; - - [StructLayout(LayoutKind.Sequential)] - internal struct KEYBDINPUT - { - internal short wVk; - internal short wScan; - internal int dwFlags; - internal int time; - internal IntPtr dwExtraInfo; - }; - - [Flags] - internal enum SendMouseInputFlags - { - Move = 0x0001, - LeftDown = 0x0002, - LeftUp = 0x0004, - RightDown = 0x0008, - RightUp = 0x0010, - MiddleDown = 0x0020, - MiddleUp = 0x0040, - XDown = 0x0080, - XUp = 0x0100, - Wheel = 0x0800, - Absolute = 0x8000, - }; - - // Importing various Win32 APIs that we need for input - [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] - internal static extern int GetSystemMetrics(int nIndex); - - [DllImport("user32.dll", CharSet = CharSet.Auto)] - internal static extern int MapVirtualKey(int nVirtKey, int nMapType); - - [DllImport("user32.dll", SetLastError = true)] - internal static extern int SendInput(int nInputs, ref INPUT mi, int cbSize); - - [DllImport("user32.dll", CharSet = CharSet.Auto)] - internal static extern short VkKeyScan(char ch); - - #endregion User32 - } - - /// - /// Exposes a simple interface to common mouse operations, allowing the user to simulate mouse input. - /// - /// The following code moves to screen coordinate 100,100 and left clicks. - /// - /** - Mouse.MoveTo(new Point(100, 100)); - Mouse.Click(MouseButton.Left); - */ - - /// - /// - public static class Mouse - { - /// - /// Clicks a mouse button. - /// - /// The mouse button to click. - public static void Click(MouseButton mouseButton) - { - Down(mouseButton); - Up(mouseButton); - } - - /// - /// Double-clicks a mouse button. - /// - /// The mouse button to click. - public static void DoubleClick(MouseButton mouseButton) - { - Click(mouseButton); - Click(mouseButton); - } - - /// - /// Performs a mouse-down operation for a specified mouse button. - /// - /// The mouse button to use. - public static void Down(MouseButton mouseButton) - { - switch (mouseButton) - { - case MouseButton.Left: - SendMouseInput(0, 0, 0, NativeMethods.SendMouseInputFlags.LeftDown); - break; - - case MouseButton.Right: - SendMouseInput(0, 0, 0, NativeMethods.SendMouseInputFlags.RightDown); - break; - - case MouseButton.Middle: - SendMouseInput(0, 0, 0, NativeMethods.SendMouseInputFlags.MiddleDown); - break; - - case MouseButton.XButton1: - SendMouseInput(0, 0, NativeMethods.XButton1, NativeMethods.SendMouseInputFlags.XDown); - break; - - case MouseButton.XButton2: - SendMouseInput(0, 0, NativeMethods.XButton2, NativeMethods.SendMouseInputFlags.XDown); - break; - - default: - throw new InvalidOperationException("Unsupported MouseButton input."); - } - } - - /// - /// Moves the mouse pointer to the specified screen coordinates. - /// - /// The screen coordinates to move to. - public static void MoveTo(System.Drawing.Point point) - { - SendMouseInput(point.X, point.Y, 0, NativeMethods.SendMouseInputFlags.Move | NativeMethods.SendMouseInputFlags.Absolute); - } - - /// - /// Resets the system mouse to a clean state. - /// - public static void Reset() - { - MoveTo(new System.Drawing.Point(0, 0)); - - if (System.Windows.Input.Mouse.LeftButton == MouseButtonState.Pressed) - { - SendMouseInput(0, 0, 0, NativeMethods.SendMouseInputFlags.LeftUp); - } - - if (System.Windows.Input.Mouse.MiddleButton == MouseButtonState.Pressed) - { - SendMouseInput(0, 0, 0, NativeMethods.SendMouseInputFlags.MiddleUp); - } - - if (System.Windows.Input.Mouse.RightButton == MouseButtonState.Pressed) - { - SendMouseInput(0, 0, 0, NativeMethods.SendMouseInputFlags.RightUp); - } - - if (System.Windows.Input.Mouse.XButton1 == MouseButtonState.Pressed) - { - SendMouseInput(0, 0, NativeMethods.XButton1, NativeMethods.SendMouseInputFlags.XUp); - } - - if (System.Windows.Input.Mouse.XButton2 == MouseButtonState.Pressed) - { - SendMouseInput(0, 0, NativeMethods.XButton2, NativeMethods.SendMouseInputFlags.XUp); - } - } - - /// - /// Simulates scrolling of the mouse wheel up or down. - /// - /// The number of lines to scroll. Use positive numbers to scroll up and negative numbers to scroll down. - public static void Scroll(double lines) - { - int amount = (int)(NativeMethods.WheelDelta * lines); - - SendMouseInput(0, 0, amount, NativeMethods.SendMouseInputFlags.Wheel); - } - - /// - /// Performs a mouse-up operation for a specified mouse button. - /// - /// The mouse button to use. - public static void Up(MouseButton mouseButton) - { - switch (mouseButton) - { - case MouseButton.Left: - SendMouseInput(0, 0, 0, NativeMethods.SendMouseInputFlags.LeftUp); - break; - - case MouseButton.Right: - SendMouseInput(0, 0, 0, NativeMethods.SendMouseInputFlags.RightUp); - break; - - case MouseButton.Middle: - SendMouseInput(0, 0, 0, NativeMethods.SendMouseInputFlags.MiddleUp); - break; - - case MouseButton.XButton1: - SendMouseInput(0, 0, NativeMethods.XButton1, NativeMethods.SendMouseInputFlags.XUp); - break; - - case MouseButton.XButton2: - SendMouseInput(0, 0, NativeMethods.XButton2, NativeMethods.SendMouseInputFlags.XUp); - break; - - default: - throw new InvalidOperationException("Unsupported MouseButton input."); - } - } - - /// - /// Sends mouse input. - /// - /// x coordinate - /// y coordinate - /// scroll wheel amount - /// SendMouseInputFlags flags - [PermissionSet(SecurityAction.Assert, Name = "FullTrust")] - private static void SendMouseInput(int x, int y, int data, NativeMethods.SendMouseInputFlags flags) - { - PermissionSet permissions = new PermissionSet(PermissionState.Unrestricted); - permissions.Demand(); - - int intflags = (int)flags; - - if ((intflags & (int)NativeMethods.SendMouseInputFlags.Absolute) != 0) - { - // Absolute position requires normalized coordinates. - NormalizeCoordinates(ref x, ref y); - intflags |= NativeMethods.MouseeventfVirtualdesk; - } - - NativeMethods.INPUT mi = new NativeMethods.INPUT(); - mi.type = NativeMethods.InputMouse; - mi.union.mouseInput.dx = x; - mi.union.mouseInput.dy = y; - mi.union.mouseInput.mouseData = data; - mi.union.mouseInput.dwFlags = intflags; - mi.union.mouseInput.time = 0; - mi.union.mouseInput.dwExtraInfo = new IntPtr(0); - - if (NativeMethods.SendInput(1, ref mi, Marshal.SizeOf(mi)) == 0) - { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - } - - private static void NormalizeCoordinates(ref int x, ref int y) - { - int vScreenWidth = NativeMethods.GetSystemMetrics(NativeMethods.SMCxvirtualscreen); - int vScreenHeight = NativeMethods.GetSystemMetrics(NativeMethods.SMCyvirtualscreen); - int vScreenLeft = NativeMethods.GetSystemMetrics(NativeMethods.SMXvirtualscreen); - int vScreenTop = NativeMethods.GetSystemMetrics(NativeMethods.SMYvirtualscreen); - - // Absolute input requires that input is in 'normalized' coords - with the entire - // desktop being (0,0)...(65536,65536). Need to convert input x,y coords to this - // first. - // - // In this normalized world, any pixel on the screen corresponds to a block of values - // of normalized coords - eg. on a 1024x768 screen, - // y pixel 0 corresponds to range 0 to 85.333, - // y pixel 1 corresponds to range 85.333 to 170.666, - // y pixel 2 correpsonds to range 170.666 to 256 - and so on. - // Doing basic scaling math - (x-top)*65536/Width - gets us the start of the range. - // However, because int math is used, this can end up being rounded into the wrong - // pixel. For example, if we wanted pixel 1, we'd get 85.333, but that comes out as - // 85 as an int, which falls into pixel 0's range - and that's where the pointer goes. - // To avoid this, we add on half-a-"screen pixel"'s worth of normalized coords - to - // push us into the middle of any given pixel's range - that's the 65536/(Width*2) - // part of the formula. So now pixel 1 maps to 85+42 = 127 - which is comfortably - // in the middle of that pixel's block. - // The key ting here is that unlike points in coordinate geometry, pixels take up - // space, so are often better treated like rectangles - and if you want to target - // a particular pixel, target its rectangle's midpoint, not its edge. - x = ((x - vScreenLeft) * 65536) / vScreenWidth + 65536 / (vScreenWidth * 2); - y = ((y - vScreenTop) * 65536) / vScreenHeight + 65536 / (vScreenHeight * 2); - } - } - - /// - /// Exposes a simple interface to common keyboard operations, allowing the user to simulate keyboard input. - /// - /// - /// The following code types "Hello world" with the specified casing, - /// and then types "hello, capitalized world" which will be in all caps because - /// the left shift key is being held down. - /// - /** - Keyboard.Type("Hello world"); - Keyboard.Press(Key.LeftShift); - Keyboard.Type("hello, capitalized world"); - Keyboard.Release(Key.LeftShift); - */ - - /// - /// - public static class KeyboardUtil - { - #region Public Members - - /// - /// Presses down a key. - /// - /// The key to press. - public static void Press(Key key) - { - SendKeyboardInput(key, true); - } - - /// - /// Releases a key. - /// - /// The key to release. - public static void Release(Key key) - { - SendKeyboardInput(key, false); - } - - /// - /// Resets the system keyboard to a clean state. - /// - public static void Reset() - { - foreach (Key key in Enum.GetValues(typeof(Key))) - { - if (key != Key.None && (System.Windows.Input.Keyboard.GetKeyStates(key) & KeyStates.Down) > 0) - { - Release(key); - } - } - } - - /// - /// Performs a press-and-release operation for the specified key, which is effectively equivallent to typing. - /// - /// The key to press. - public static void Type(Key key) - { - Press(key); - Release(key); - } - - /// - /// Types the specified text. - /// - /// The text to type. - public static void Type(string text) - { - foreach (char c in text) - { - // We get the vKey value for the character via a Win32 API. We then use bit masks to pull the - // upper and lower bytes to get the shift state and key information. We then use WPF KeyInterop - // to go from the vKey key info into a System.Windows.Input.Key data structure. This work is - // necessary because Key doesn't distinguish between upper and lower case, so we have to wrap - // the key type inside a shift press/release if necessary. - int vKeyValue = NativeMethods.VkKeyScan(c); - bool keyIsShifted = (vKeyValue & NativeMethods.VKeyShiftMask) == NativeMethods.VKeyShiftMask; - Key key = KeyInterop.KeyFromVirtualKey(vKeyValue & NativeMethods.VKeyCharMask); - - if (keyIsShifted) - { - Type(key, new Key[] { Key.LeftShift }); - } - else - { - Type(key); - } - } - } - - #endregion Public Members - - #region Private Members - - /// - /// Types a key while a set of modifier keys are being pressed. Modifer keys - /// are pressed in the order specified and released in reverse order. - /// - /// Key to type. - /// Set of keys to hold down with key is typed. - private static void Type(Key key, Key[] modifierKeys) - { - foreach (Key modiferKey in modifierKeys) - { - Press(modiferKey); - } - - Type(key); - - foreach (Key modifierKey in modifierKeys.Reverse()) - { - Release(modifierKey); - } - } - - /// - /// Injects keyboard input into the system. - /// - /// Indicates the key pressed or released. Can be one of the constants defined in the Key enum. - /// True to inject a key press, false to inject a key release. - [PermissionSet(SecurityAction.Assert, Name = "FullTrust")] - private static void SendKeyboardInput(Key key, bool press) - { - PermissionSet permissions = new PermissionSet(PermissionState.Unrestricted); - permissions.Demand(); - - NativeMethods.INPUT ki = new NativeMethods.INPUT(); - ki.type = NativeMethods.InputKeyboard; - ki.union.keyboardInput.wVk = (short)KeyInterop.VirtualKeyFromKey(key); - ki.union.keyboardInput.wScan = (short)NativeMethods.MapVirtualKey(ki.union.keyboardInput.wVk, 0); - - int dwFlags = 0; - - if (ki.union.keyboardInput.wScan > 0) - { - dwFlags |= NativeMethods.KeyeventfScancode; - } - - if (!press) - { - dwFlags |= NativeMethods.KeyeventfKeyup; - } - - ki.union.keyboardInput.dwFlags = dwFlags; - - if (ExtendedKeys.Contains(key)) - { - ki.union.keyboardInput.dwFlags |= NativeMethods.KeyeventfExtendedkey; - } - - ki.union.keyboardInput.time = 0; - ki.union.keyboardInput.dwExtraInfo = new IntPtr(0); - - if (NativeMethods.SendInput(1, ref ki, Marshal.SizeOf(ki)) == 0) - { - throw new Win32Exception(Marshal.GetLastWin32Error()); - } - } - - // From the SDK: - // The extended-key flag indicates whether the keystroke message originated from one of - // the additional keys on the enhanced keyboard. The extended keys consist of the ALT and - // CTRL keys on the right-hand side of the keyboard; the INS, DEL, HOME, END, PAGE UP, - // PAGE DOWN, and arrow keys in the clusters to the left of the numeric keypad; the NUM LOCK - // key; the BREAK (CTRL+PAUSE) key; the PRINT SCRN key; and the divide (/) and ENTER keys in - // the numeric keypad. The extended-key flag is set if the key is an extended key. - // - // - docs appear to be incorrect. Use of Spy++ indicates that break is not an extended key. - // Also, menu key and windows keys also appear to be extended. - private static readonly Key[] ExtendedKeys = new Key[] { - Key.RightAlt, - Key.RightCtrl, - Key.NumLock, - Key.Insert, - Key.Delete, - Key.Home, - Key.End, - Key.Prior, - Key.Next, - Key.Up, - Key.Down, - Key.Left, - Key.Right, - Key.Apps, - Key.RWin, - Key.LWin }; - - // Note that there are no distinct values for the following keys: - // numpad divide - // numpad enter - - #endregion Private Members - } - - #endregion Operate Mouse Keyboard -} \ No newline at end of file diff --git a/STranslate/Utils/MVVMUtil.cs b/STranslate/Utils/MVVMUtil.cs index 35d5690..b6604e6 100644 --- a/STranslate/Utils/MVVMUtil.cs +++ b/STranslate/Utils/MVVMUtil.cs @@ -56,25 +56,4 @@ namespace STranslate.Utils _execute(parameter); } } - - /// - /// 单例辅助类 - /// - public abstract class SingletonMode where T : class - { - public static T _Instance; - - public static T Instance() - { - Type type = typeof(T); - lock (type) - { - if (SingletonMode._Instance == null) - { - SingletonMode._Instance = (Activator.CreateInstance(typeof(T), true) as T); - } - return SingletonMode._Instance; - } - } - } } \ No newline at end of file diff --git a/STranslate/ViewModel/MainVM.cs b/STranslate/ViewModel/MainVM.cs index 6ad5123..db0b7d2 100644 --- a/STranslate/ViewModel/MainVM.cs +++ b/STranslate/ViewModel/MainVM.cs @@ -27,7 +27,7 @@ namespace STranslate.ViewModel config = ConfigUtil.ReadConfig(ConfigPath); //复制翻译结果 - CopyTranslateResultCmd = new RelayCommand((_) => + CopyResultCmd = new RelayCommand((_) => { return string.IsNullOrEmpty(OutputTxt) ? false : true; }, (_) => @@ -44,6 +44,8 @@ namespace STranslate.ViewModel await Translate(); }); } + + #region handle public async Task Translate() { try @@ -68,9 +70,11 @@ namespace STranslate.ViewModel OutputTxt = ex.Message; } } + #endregion + #region Params public ICommand TranslateCmd { get; private set; } - public ICommand CopyTranslateResultCmd { get; private set; } + public ICommand CopyResultCmd { get; private set; } private string _InputTxt; public string InputTxt { get => _InputTxt; set => UpdateProperty(ref _InputTxt, value); } @@ -89,8 +93,6 @@ namespace STranslate.ViewModel private string _OutputComboSelected; public string OutputComboSelected { get => _OutputComboSelected; set => UpdateProperty(ref _OutputComboSelected, value); } - - private static readonly MainVM _Instance = new MainVM(); - public static MainVM Instance { get => _Instance; } + #endregion } } \ No newline at end of file diff --git a/STranslate/packages.config b/STranslate/packages.config index 78498af..baae49f 100644 --- a/STranslate/packages.config +++ b/STranslate/packages.config @@ -1,6 +1,6 @@  - - - + + + \ No newline at end of file