public static Settings Init() { var settings = new Settings(); settings.Reload(); bool laptop = LowLevelAdapter.ThisIsLaptop(); if (settings.ConvertLastHotkey.KeyData == Keys.None) { settings.ConvertLastHotkey = new KeyboardEventArgs(laptop ? Keys.End : Keys.Pause, false); } if (settings.ConvertSelectionHotkey.KeyData == Keys.None) { settings.ConvertSelectionHotkey = new KeyboardEventArgs(laptop ? (Keys.End | Keys.Shift) : (Keys.Pause | Keys.Shift), false); } if (settings.ShowTrayIcon == null) { settings.ShowTrayIcon = true; } if (settings.SmartSelection == null) { settings.SmartSelection = false; } if (settings.AutoSwitching == null) { settings.AutoSwitching = true; } if (settings.SwitchDelay < 0) { settings.SwitchDelay = 0; } settings.Save(); return(settings); }
//private int CalculateSwitchingNumber(IntPtr currentLayout, IntPtr detectedLayout) //{ // var switchingNumber = Array.IndexOf(layouts, detectedLayout) - Array.IndexOf(layouts, currentLayout); // if (switchingNumber < 0) // { // switchingNumber = switchingNumber + layouts.Length; // } // return switchingNumber; //} private void RemoveSelection() { ignoreKeyPress = true; LowLevelAdapter.SendKeyPress(Keys.Space); LowLevelAdapter.SendKeyPress(Keys.Back); ignoreKeyPress = false; }
public void Start() { if (IsStarted()) { return; } hookId = LowLevelAdapter.SetHook(LowLevelAdapter.WH_KEYBOARD_LL, keyboardEventHook); }
private void SwitchLayout() { BeginNewSelection(); ignoreKeyPress = true; LowLevelAdapter.ReleasePressedFnKeys(); LowLevelAdapter.SetNextKeyboardLayout(); ignoreKeyPress = false; }
public void Start() { if (IsStarted()) { return; } hookId = LowLevelAdapter.SetHook(LowLevelAdapter.WH_MOUSE_LL, callback); }
public void Stop() { if (!IsStarted()) { return; } LowLevelAdapter.ReleaseHook(hookId); hookId = IntPtr.Zero; }
private IntPtr KeyboardEventHook(int nCode, IntPtr wParam, IntPtr lParam) { bool isHandled; ProcessKeyboardEvent(nCode, wParam, lParam, out isHandled); return(isHandled? new IntPtr(1) : LowLevelAdapter.NextHook(nCode, wParam, lParam)); }
public void AutoSwitchingTest() { var path = AppDomain.CurrentDomain.BaseDirectory; Debug.WriteLine($"Current path is {path}"); var app = Process.Start($"{path}\\..\\Release\\AutoMova.exe"); app.WaitForInputIdle(); var notepad = Process.Start("notepad.exe"); notepad.WaitForInputIdle(); var layouts = LowLevelAdapter.GetLayoutList(); var inputLangCollection = InputLanguage.InstalledInputLanguages; InputLanguage[] langs = new InputLanguage[layouts.Length]; inputLangCollection.CopyTo(langs, 0); Dictionary <IntPtr, string[]> testStrings = new Dictionary <IntPtr, string[]>(); foreach (var lang in langs) { testStrings.Add(layouts[Array.IndexOf(langs, lang)], System.IO.File.ReadAllLines($"{path}\\..\\..\\Test\\data\\{lang.Culture.Name.Substring(0,2)}.txt")); } string expectedString = ""; List <List <Keys> > testKeyCodes = new List <List <Keys> >(); foreach (var layout in testStrings.Keys) { foreach (var str in testStrings[layout]) { expectedString += (str + " "); PressKeys(StringToKeys(str, layout)); } } LowLevelAdapter.SendSelectAll(); LowLevelAdapter.SendCopy(); LowLevelAdapter.SendKeyPress(Keys.Delete); notepad.CloseMainWindow(); notepad.Close(); app.Kill(); var actualString = Clipboard.GetText(); var expectedWords = expectedString.Split(' '); var actualWords = actualString.Split(' '); for (int i = 0; i < expectedWords.Length; i++) { if (expectedWords[i] != actualWords[i]) { Debug.WriteLine($"{expectedWords[i]} -> {actualWords[i]}"); } } Assert.AreEqual(expectedWords, actualWords, "Auto switching error"); }
private void AddToCurrentSelection(KeyboardEventArgs data) { Debug.Write("AddToCurrentSelection() "); currentSelection.Add(data); foreach (var word in lastWord.ToArray()) { lastWord[word.Key] = word.Value + LowLevelAdapter.KeyCodeToUnicode(data.KeyCode, langToIntPtr[word.Key]); } Debug.WriteLine(DictToString(lastWord)); }
private List <Keys> StringToKeys(string str, IntPtr layout) { var keys = new List <Keys>(str.Length + 1); for (var i = 0; i < str.Length; i++) { keys.Add(LowLevelAdapter.ToKey(str[i], layout)); } keys.Add(Keys.Space); return(keys); }
protected override void OnHandleCreated(EventArgs e) { var layouts = LowLevelAdapter.GetLayoutList(); var inputLangCollection = InputLanguage.InstalledInputLanguages; InputLanguage[] inputLangs = new InputLanguage[layouts.Length]; inputLangCollection.CopyTo(inputLangs, 0); foreach (var lang in inputLangs) { textBoxDebug.AppendText(lang.Culture.Name + ' ' + (layouts[Array.IndexOf(inputLangs, lang)]).ToString("x8") + "\n"); } }
private void PressKeys(List <Keys> keys) { foreach (var key in keys) { //Debug.Write(key); if (key != Keys.None) { LowLevelAdapter.SendKeyPress(key, (key & Keys.Shift) != Keys.None); Thread.Sleep(10); } } }
/** * SETTINGS */ void SaveSettings() { settings.Save(); if (settings.AutoStart == true) { LowLevelAdapter.CreateAutorunShortcut(); } else { LowLevelAdapter.DeleteAutorunShortcut(); } }
private IntPtr ProcessMouse(int nCode, IntPtr wParam, IntPtr lParam) { try { if (nCode >= 0) { switch (wParam.ToInt32()) { case LowLevelAdapter.WM_LBUTTONDOWN: case LowLevelAdapter.WM_RBUTTONDOWN: OnMouseEvent(new EventArgs()); break; } } } catch { } return(LowLevelAdapter.NextHook(nCode, wParam, lParam)); }
private void ConvertLast(string lang) { Debug.WriteLine($"ConvertLast to {lang}..."); var fnKeys = LowLevelAdapter.ReleasePressedFnKeys(); // Fix for apps with autocompletion (i.e. omnibox in Google Chrome browser) RemoveSelection(); ignoreKeyPress = true; // Remove last word var backspaceCount = autoSwitchingIsGoing ? (currentSelection.Count - 1) : currentSelection.Count; var backspaces = Enumerable.Repeat <Keys>(Keys.Back, backspaceCount); foreach (var backspace in backspaces) { Thread.Sleep(settings.SwitchDelay); LowLevelAdapter.SendKeyPress(backspace, false); } //Change layout if (lang == "next") { LowLevelAdapter.SetNextKeyboardLayout(); } else { LowLevelAdapter.SetKeyboadLayout(langToLayout[lang]); } // Type last word in new layout foreach (var data in currentSelection) { Thread.Sleep(settings.SwitchDelay); LowLevelAdapter.SendKeyPress(data.KeyCode, data.Shift); } LowLevelAdapter.PressPressedFnKeys(fnKeys); ignoreKeyPress = false; }
static void Main() { if (mutex.WaitOne(TimeSpan.Zero, true)) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var settings = Settings.Init(); var engine = new SwitcherCore(settings); Application.ApplicationExit += (s, a) => { engine.Dispose(); }; var app = new SettingsForm(settings, engine); app.Exit += (s, e) => Application.Exit(); var context = new ApplicationContext(app); Application.Run(context); mutex.ReleaseMutex(); } else { LowLevelAdapter.SendShowSettingsMessage(); } }
private void ConvertSelection() { ignoreKeyPress = true; LowLevelAdapter.BackupClipboard(); var fnKeys = LowLevelAdapter.ReleasePressedFnKeys(); LowLevelAdapter.SendCopy(); var selection = Clipboard.GetText(); LowLevelAdapter.RestoreClipboard(); if (String.IsNullOrEmpty(selection)) { LowLevelAdapter.PressPressedFnKeys(fnKeys); return; } var keys = new List <Keys>(selection.Length); for (var i = 0; i < selection.Length; i++) { keys.Add(LowLevelAdapter.ToKey(selection[i])); } LowLevelAdapter.SetNextKeyboardLayout(); ignoreKeyPress = true; foreach (var key in keys) { Debug.Write(key); if (key != Keys.None) { LowLevelAdapter.SendKeyPress(key, (key & Keys.Shift) != Keys.None); } } Debug.WriteLine(""); LowLevelAdapter.PressPressedFnKeys(fnKeys); ignoreKeyPress = false; }
// returns true if event is handled private void ProcessKeyboardEvent(int nCode, IntPtr wParam, IntPtr lParam, out bool isHandled) { isHandled = false; try { if (nCode < 0) { return; } bool isKeyDownEvent = false; switch (wParam.ToInt32()) { case LowLevelAdapter.WM_KEYDOWN: case LowLevelAdapter.WM_SYSKEYDOWN: isKeyDownEvent = true; goto case LowLevelAdapter.WM_KEYUP; case LowLevelAdapter.WM_KEYUP: case LowLevelAdapter.WM_SYSKEYUP: var keybdinput = (KEYBDINPUT)Marshal.PtrToStructure(lParam, typeof(KEYBDINPUT)); var keyData = (Keys)keybdinput.Vk; keyData |= LowLevelAdapter.KeyPressed(Keys.ControlKey) ? Keys.Control : 0; keyData |= LowLevelAdapter.KeyPressed(Keys.Menu) ? Keys.Alt : 0; keyData |= LowLevelAdapter.KeyPressed(Keys.ShiftKey) ? Keys.Shift : 0; var winPressed = LowLevelAdapter.KeyPressed(Keys.LWin) || LowLevelAdapter.KeyPressed(Keys.RWin); var args = new KeyboardEventArgs(keyData, winPressed, isKeyDownEvent ? KeyboardEventType.KeyDown : KeyboardEventType.KeyUp); OnKeyboardEvent(args); isHandled = args.Handled; break; } } catch { } }
public SwitcherCore(ISettings settings) { this.settings = settings; kbdHook = new KeyboardHook(); kbdHook.KeyboardEvent += ProcessKeyPress; mouseHook = new MouseHook(); mouseHook.MouseEvent += ProcessMousePress; readyToSwitch = false; autoSwitchingIsGoing = false; manualSwitchingIsGoing = false; ignoreKeyPress = false; var layouts = LowLevelAdapter.GetLayoutList(); var inputLangCollection = InputLanguage.InstalledInputLanguages; InputLanguage[] inputLangs = new InputLanguage[layouts.Length]; inputLangCollection.CopyTo(inputLangs, 0); foreach (var lang in inputLangs) { Debug.WriteLine(lang.Culture.Name); Debug.WriteLine((layouts[Array.IndexOf(inputLangs, lang)]).ToString("x8")); if (!langToLayout.ContainsKey(lang.Culture.Name)) { langToLayout.Add(lang.Culture.Name, (uint)(layouts[Array.IndexOf(inputLangs, lang)])); langToIntPtr.Add(lang.Culture.Name, layouts[Array.IndexOf(inputLangs, lang)]); } layoutToLang.Add(layouts[Array.IndexOf(inputLangs, lang)], lang.Culture.Name); } var langs = langToLayout.Keys.ToArray(); foreach (var lang in langs) { lastWord.Add(lang, ""); langStatistics.Add(lang, 0); } layoutDetector = new LayoutDetector(langs); }
private void OnKeyPress(KeyboardEventArgs evtData) { var vkCode = evtData.KeyCode; Debug.WriteLine($"\nOnKeyPress: KeyCode={vkCode.ToString("x")}, KeyData={evtData.KeyData.ToString("x")}, KeyData={evtData.KeyData.ToString()}"); //return; if (evtData.Equals(settings.SwitchLayoutHotkey)) { readyToSwitch = true; return; } readyToSwitch = false; if (evtData.Equals(settings.ConvertLastHotkey)) { Debug.WriteLine("ConvertLastHotkey detected!"); manualSwitchingIsGoing = true; ConvertLast("next"); manualSwitchingIsGoing = false; evtData.Handled = true; return; } if (evtData.Equals(settings.ConvertSelectionHotkey)) { Debug.WriteLine("ConvertSelectionHotkey detected!"); //return; ConvertSelection(); evtData.Handled = true; return; } if (evtData.Equals(settings.ToggleAutoSwitchingHotkey)) { Debug.WriteLine("ToggleAutoSwitchingHotkey detected!"); settings.AutoSwitching = !settings.AutoSwitching; evtData.Handled = true; return; } if (this.KeepTrackingKeys(evtData)) { return; } var notModified = !this.HaveModifiers(evtData); if (vkCode == Keys.Back && notModified) { RemoveLast(); return; } if (IsPrintable(evtData) || (vkCode == Keys.Space && notModified)) { var currentLayout = layoutToLang[LowLevelAdapter.GetCurrentLayout()]; if (WordEnded()) { langStatistics[currentLayout] += 1; } if (settings.SmartSelection == false && GetPreviousVkCode() == Keys.Space) { BeginNewSelection(); } AddToCurrentSelection(evtData); if (IsPunctuation(evtData, currentLayout)) { return; } if (!autoSwitchingIsGoing && !manualSwitchingIsGoing && currentSelection.Count > 1) { var suggestedLayout = SuggestedLang(); if (suggestedLayout == null) { suggestedLayout = currentLayout; } var detectedLayout = layoutDetector.Decision(lastWord, suggestedLayout); Debug.WriteLine($"Current layout: {currentLayout}, detected layout: {detectedLayout}"); if (settings.AutoSwitching == true && detectedLayout != currentLayout) { autoSwitchingIsGoing = true; evtData.Handled = true; ConvertLast(detectedLayout); autoSwitchingIsGoing = false; } } return; } // default: BeginNewSelection(); ClearLangStatistics(); }