将一个键组合转换为另一个

编程入门 行业动态 更新时间:2024-10-19 19:40:38
本文介绍了将一个键组合转换为另一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试检测和抑制组合键,而是发送另一个组合键. (带有WPF的C#.) 我找到了两个不错的库,一个用于处理键盘和鼠标挂钩: globalmousekeyhook.codeplex/ [ ^ ] 另一个用于发送虚拟键和鼠标事件: inputsimulator.codeplex/ [ ^ ] 尽管我的问题是理论上的,但可能与的内部运作方式有关 系统. 因此,现在我可以检测和抑制组合键,但是只要发送虚拟 按键,两个模块开始干涉. 假设我要将"Alt + D"转换为"K".我按住上的"Alt"和"D" 键盘,可在应用程序中创建两个KeyDown事件.相关功能是 调用时,将识别该组合,并按下虚拟的"K".但这瞬间 调用KeyDown事件,启动组合检测,现在正在查看Alt + D + K 这不是我们要寻找的组合,所以整个过程都坏了... 在组合检测期间,我可以忽略我刚刚伪造的密钥,但这会破坏 发送的密钥是原始组合的一部分的情况. (例如:"Alt + A"->"Shift + A",组合检测不应忽略"A".) 我尝试在发送击键之前先关闭挂钩,然后再重新启动 以防止我的应用注意到虚拟按键.不幸的是,这也有一个问题:如果应用程序不知道按键,那么它就无法抑制任何按键 因此原始的不需要的组合键会泄漏出去. 我是C#的新手,从没接触过低级的东西(也不想这么做),所以 这个问题对我来说有点不知所措.我会很感激关于如何的任何建议 解决这个问题,任何示例或相关故事...

I''m trying to detect and suppress a key combo and send another instead. (C# with WPF.) I''ve found two nice libraries, one for handling keyboard and mouse hooks: globalmousekeyhook.codeplex/[^] and another for sending virtual key and mouse events: inputsimulator.codeplex/[^] although my problem is theoretical, probably more related to inner workings of the system. So now I can detect and suppress a key combination but as soon as I send a virtual key press, the two modules start to interfere. Let''s say I want to convert "Alt+D" into "K". I press and hold "Alt" and "D" on the keyboard which creates two KeyDown events in the app. The related functions are called, the combo is recognized and a virtual "K" is pressed. But that instantly calls the KeyDown event, starts the combo detection which is now looking at Alt+D+K which is not the combo we are looking for so the whole thing breaks... During combo detection I could ignore the key I''ve just faked but that would break cases where the sent key is part of the original combination. (For example: "Alt+A" -> "Shift+A", combo detection shouldn''t ignore "A".) I tried turning off the hooks before sending the keystroke and back on after that to prevent my app noticing the virtual keypress. Unfortunately that too has a problem: if the app don''t know about keypresses then it can''t suppress any of them so the original, unwanted key combo leaks through. I''m new at C# and have never touched low level stuff (and don''t really want to) so this problem is a bit overwhelming for me. I''d appreciate any suggestions on how to tackle this, any examples or related stories...

推荐答案

这里有几件事可以尝试.您已经提到过一种方法(在发送虚拟按键时关闭全局键盘挂钩),但这似乎不起作用.但是,如果您创建了一个全局变量来跟踪自己在逻辑中的位置,则可能可行.如果您正在发送虚拟按键,则布尔值var或设置为true的字符串之类的东西.另外,您可以尝试使用SendKeys代替inputsimulator.这将要求焦点集中在您将密钥发送到的应用程序上. (您可以使用AppActivate来激活向其发送击键的应用程序)如果检测到Alt + D + K,整体中断"为什么...这不是您要查找的匹配项,所以逻辑应该只是跳过此错误. (也许尝试一下,在这里捕捉语句?).请发布一些代码,以及发送虚拟按键时收到的错误.这可能会进一步说明您遇到的问题.我已经使用了上面提到的globalkeyboardhook,它的运行效果非常好.但是,我正在使用一些win32 api函数调用来移动鼠标光标,并且我正在使用SendKeys将击键发送到应用程序. 想通了一点...我把这段代码与我周围放置的其他代码放在一起了...可能根本不起作用,但可能有一定用处 There are several things to try here. One you have already mentioned (turning off the global keyboard hook while sending virtual key presses), but that does not appear to work. However, it could maybe work if you created a global variable to keep track of where you are in the logic. Something like a boolean var or string set to true if you are in the process of sending a virtual keypress. Also, you could try using SendKeys instead of the inputsimulator. This would require that focus exists on the application you are sending the key to. (You could use AppActivate to activate the application you are sending the keystroke to) Why does the "whole thing break" if it detects Alt+D+K... this is not the match you are looking for, so the logic should just pass over this error. (maybe a try, catch statement here?). Please post some code, and the error that you receive when sending the virtual keypress. This may shed additional light on exactly what problem you are encountering. I have used the globalkeyboardhook mentioned above, and it works beautifully. However, I am using some win32 api function calls to move the mouse cursor, and I am using SendKeys to send keystrokes to an application. Figured I''d take a stab at this... I threw this code together from some other code that I had laying around... may not work at all, but could possibly be of some use //setup boolean variable to keep track of whether or //not you are currently sending a virtualized keyPress public bool sendingVirtualKeyPress = false; //setup background worker to handle the execution of the virtual key press BackgroundWorker bw = new BackgroundWorker(); public Form1() { bw.WorkerReportsProgress = true; bw.WorkerSupportsCancellation = true; bw.DoWork += new DoWorkEventHandler(bw_DoWork); bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); InitializeComponent(); } private void startButton_Click(object sender, EventArgs e) { if (bw.IsBusy != true && childThreadExists == false) { //i am using this boolean variable to control only having //one thread other than the GUI thread childThreadExists = true; startButton.Enabled = false; //test call using defined string with expected result string testString = "A,B,C"; //string testString should cause "CBA" to be printed //to a richtextbox when ran through the Do_Work method bw.RunWorkerAsync(testString); //RunWorkerAsync calls the DoWork method } } //this is whatever method you currently have defined for //detecting global key presses detectInputReceivedEvent() { //adding a boolean check here to ensure that a Virtual //Key Press is not happening elsewhere, will prevent //you from detecting a virtualized key press if(sendingVirtualKeyPress == false) { //get input from global hook string detectedInputFromGlobalHook = ""; //send current keys being pressed to background worker bw.RunWorkerAsync(detectedInputFromGlobalHook); } } void bw_DoWork(object sender, DoWorkEventArgs e) { //determine if keys are a combo that you want //if so, then do two things: //turn on global boolean variable //sendTranslatedVirtualKeyPress(); //else return; BackgroundWorker worker = sender as BackgroundWorker; string keysFromGlobalHook = (string)e.Argument; if ((worker.CancellationPending == true)) { e.Cancel = true; return; } else { //this is where we want to do our work //first translate the string received by the global Keyboard hook //into the key presses that you are wanting string translation = getTranslatedKeys(keysFromGlobalHook); //then send the virtualized keypress sendVirtualizedKeyPress(translation); //worker.ReportProgress((1)); // Perform a time consuming operation and report progress. System.Threading.Thread.Sleep(500); } } private string getTranslatedKeys(string inputKeys) { if(inputKeys.ToUpper() == "A,B,C") { return "CAB"; } } private void sendVirtualizedKeyPress(string inputKeys) { try { System.Windows.Forms.SendKeys.SendWait(keyString); } catch (Exception e) { MessageBox.Show("An Error Occurred With Send Keys..." + "\n\r"); } } private void cancelButton_Click(object sender, EventArgs e) { if (bw.WorkerSupportsCancellation == true) { bw.CancelAsync(); //if you have disabled buttons, etc. when running the //background worker this would be a good place to re-enable them startButton.Enabled = true; } } void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if ((e.Cancelled == true)) { this.richTextBox1.AppendText("Canceled!"); } else if (!(e.Error == null)) { this.richTextBox1.AppendText("Error: " + e.Error.Message); } else { this.richTextBox1.AppendText("BackgroundWorkerCompleted" + "\r\n"); childThreadExists = false; } }

更多推荐

将一个键组合转换为另一个

本文发布于:2023-11-17 02:09:54,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1608425.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:组合   转换为

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!