我可以将密钥发送到 GeckoFX扩展浏览器,但现在我想发送组合密钥但代码不能正常工作:
这是我的代码
txtLog.AppendText("Pressing `Ctrl+Enter`...\n");
webBrowser1.Window.DomWindow.Focus();
webBrowser1.Window.WindowUtils.SendKeyEvent("keydown", 17, 0, 0, true);
webBrowser1.Window.WindowUtils.SendKeyEvent("keydown", 13, 0, 0, true);
webBrowser1.Window.WindowUtils.SendKeyEvent("keypress", 13, 0, 0, true);
webBrowser1.Window.WindowUtils.SendKeyEvent("keyup", 13, 0, 0, true);
webBrowser1.Window.WindowUtils.SendKeyEvent("keyup", 17, 0, 0, false);
它不会随时按Ctrl + Enter键。
如何让它发挥作用?
答案 0 :(得分:0)
我从未使用geckofx WindowUtils
,但如果它在Windows窗体应用程序中,您可以使用System.Windows.Forms.SendKeys
类向元素发送击键。您也可以添加组合键。我不确定语法,但可能SendKeys.Send("^({ENTER})")
。参见
https://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys%28v=vs.100%29.aspx
您可能必须先关注浏览器 - geckoWebBrowser1.Focus()
;
答案 1 :(得分:0)
我知道这是一个古老的问题,但这不是GeckoFX论坛或位存储桶项目中的问题第一次被问到,而且因为我只是必须从头开始在互联网上找到该信息,我想我会在这里为那些正在寻找它的人回答,因为此SO帖子实际上在该主题的所有相关搜索中都排在首位。
在问题跟踪器,GFX项目或我所看到的其他任何地方,似乎没有人回答或维护这些查询。
在最新版本的GeckoFX60中,旧的“ SendKeyEvent”界面(如OP的原始问题中所使用)已被弃用,不仅将其标记为已弃用,而且如果尝试使用它,则会出现异常告诉您使用“ nsITextInputProcessorCallback ”界面。
该接口未在示例中,或在项目WiKi或任何地方进行记录,仅存在一些深层的问题,这些问题在“ Mozilla IDL”的项目源代码中提供了有关其用法和C#定义的提示。接口”。
由于我有一个较旧的应用程序要升级,所以我必须自己解决问题,我有一个替换的SendKeyEvent调用,其工作方式如下:
private void SendKeyEvent(int keyCode, bool alt, bool ctrl, bool shift)
{
var instance = Xpcom.CreateInstance<nsITextInputProcessor>("@mozilla.org/text-input-processor;1");
using (var context = new AutoJSContext(_browser.Window))
{
var trans = instance.BeginInputTransaction((mozIDOMWindow)_browser.Document.DefaultView.DomWindow, new TextInputProcessorCallback());
var keyEvent = context.EvaluateScript(
$@"new KeyboardEvent('',
{{ key: '',
code: '',
keyCode: {keyCode},
ctrlKey : {(ctrl ? "true" : "false")},
shiftKey : {(shift ? "true" : "false")},
altKey : {(alt ? "true" : "false")} }});");
var kd = instance.Keydown((nsIDOMEvent)keyEvent.ToObject(), 0, 1);
var ku = instance.Keyup((nsIDOMEvent)keyEvent.ToObject(), 0, 1);
}
Marshal.ReleaseComObject(instance);
}
要进行此项工作,还必须如下定义一个类
public class TextInputProcessorCallback : nsITextInputProcessorCallback
{
//NOTE: This never actually gets called by the input processor shite for doing a simple key press in SendKeyEvent above
//but the nsi processor crashes if you don't create and specify the damn thing!!!! basically, DO NOT REMOVE IT
public bool OnNotify(nsITextInputProcessor aTextInputProcessor, nsITextInputProcessorNotification aNotification)
{
Console.WriteLine("TestCallback:OnNotify");
return true;
}
}
作为我在类状态下的注释,它似乎永远不会被GeckoFX调用或以任何有意义的方式使用,但是,如果您不将其包含在代码中,请在密钥的BeginTransaction调用中使用它按下Mozilla NSI处理器xpcom内核会崩溃和/或变色并导致问题。
要使用它,很简单,keyCode是浏览器的VK_xxxx代码,因此例如,如果要将“ 1”键发送给具有
的浏览器,VK_1 (49)
所以
SendKeyEvent(49, false, false, false)
将导致浏览器看到该按键
注意::新方法仅会生成KeyDown和KeyUp,而不是KeyPress,但是,如果您在DOM键事件类的MDN上阅读了说明,就会看到KeyPress正在已弃用并逐步淘汰。
如果页面中的“ WebCode”仅钩住了javascript中的“ KeyPress”事件,请注意,您的网页将不会选择较新的密钥发送方法,因此您需要调整页面代码查找KeyUp / KeyDown事件。
出于完整性考虑,旧方法(具有兼容的方法签名)已在我的代码中定义如下:
private void SendKeyEvent(int keyCode, bool alt, bool ctrl, bool shift)
{
//TODO: combine modifiers
var modifiers = 0;
_browser.Window.WindowUtils.SendKeyEvent("keydown", keyCode, 0, modifiers, true);
_browser.Window.WindowUtils.SendKeyEvent("keypress", keyCode, 0, modifiers, true);
_browser.Window.WindowUtils.SendKeyEvent("keyup", keyCode, 0, modifiers, true);
}
我仍然需要计算修饰符的标志值/顺序,它会在MDN上的某个地方,但是我现在不需要它,所以我有空的时候会去查找它。
这在我使用的WindowsForms代码中对我有用,请当心它对线程敏感,如果您对事件的响应与持有GeckoFX浏览器控件的UI不在同一线程上,您将得到一个调用时出现异常,但是正确放置Invoke检查并调用将解决该问题。