繁体   English   中英

带有WebBrowser控件的Excel CustomTaskPane - 键盘/焦点问题

[英]Excel CustomTaskPane with WebBrowser control - keyboard/focus issues

我有这个问题https://social.msdn.microsoft.com/Forums/vstudio/en-US/e417e686-032c-4324-b778-fef66c7687cd/excel-customtaskpane-with-webbrowser-control-keyboardfocus-issues?论坛= VSTO

这里也提到https://connect.microsoft.com/VisualStudio/feedback/details/521465/the-focus-issue-between-excel-cells-and-excel-customtaskpane-with-webbrowser-control

我正在使用Visual Studio Professional 2013编写Excel 2010插件。我创建了一个简单的CustomTaskPane,其中包含一个System.Windows.Forms.WebBrowser子文件。 该插件工作正常,我可以通过单击并更改复选框的状态在Web浏览器内导航。

在此输入图像描述

当我点击输入文本框时,我得到焦点,我看到光标闪烁,但是当我开始输入时,文本被发送到Excel并写入单元格而不是浏览器中的文本框。

我在功能区加载时添加自定义任务窗格。

private void Ribbon_Load(object sender, RibbonUIEventArgs e)
{
  TaskPaneView taskPaneView = new TaskPaneView();
  Microsoft.Office.Tools.CustomTaskPane myTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(taskPaneView, "Title");
  myTaskPane.Visible = true;
}

当我点击文本框然后点击F6它可以正常工作。 customtaskpane标题稍微变暗,文本框中会捕获文本。

我如何解决这个问题,以便当我点击输入文本框时,文本进入框而不是Excel?

编辑:好的,我做了一些测试。 如果我在TaskPaneView上添加事件以跟踪鼠标输入并单击它们可以正常工作,但前提是我删除了Web浏览器子项。 这意味着Web浏览器以某种方式阻止这些事件并阻止TaskPaneView理解它具有焦点。 如果我还在浏览器旁边的TaskPaneView中添加了一个文本框表单控件,文本框工作正常,TaskPaneView理解它有焦点,然后浏览器中的输入文本字段开始工作。 如果我直接在Web浏览器上调用焦点方法,则TaskPaneView会理解它具有焦点并且一切正常。 很明显,问题不在于键盘,而是在点击浏览器时没有被告知它有焦点的问题,因此按键会转到错误的区域。 如果我能找到一种方法让TaskPaneView理解它有焦点,那么每个标志都应该有效。

好的我能够使用以下代码解决问题

protected override void WndProc(ref Message m)
{
  const int WM_PARENTNOTIFY = 528;
  if(m.Msg == WM_PARENTNOTIFY && !this.Focused)
  {
    this.Focus();
  }
  base.WndProc(ref m);
}

我将此函数添加到我的TaskPaneView,它只是一个带有该webbrowser子元素的UserControl。 我没有深入理解为什么或如何工作,但基本上我认为发生的事情是我正在拦截WndProc,这是一个处理发送到窗口的消息的低级函数。 我用它来检查消息是否是528,我认为这意味着notifyParent。 我不知道这是否应该是我应该收听的消息,但它似乎有效。

一旦我有正确的消息消息,我检查以查看TaskPaneView是否具有焦点,如果没有,我将焦点focus()函数上。 我之前做过测试表明,如果我手动调用TaskPaneView上的focus ,一切正常。 所以,如果我没有焦点,那么手动请求焦点,我们都很好。

如果有人可以提供更详细的解释,为什么这样可行,以便我能更好地理解它,我将不胜感激,但至少我解决了这个问题。 感谢Jeremy Thompson让我以一种全新的方式思考这个问题。

问:提供更详细的解释,说明为什么这样做,以便我能更好地理解它

真高兴你做到了! 要执行根本原因分析,我们需要查看528消息的发送位置,我们需要Microsoft Excel源代码才能执行此操作。

我不认为它值得花费更多的时间进行故障排除或解决它为什么会发生因为它是一个BUG! 记录Connect错误以帮助Microsoft修复它是您可以做的最好的事情。 我们只能解决它,它的源代码中存在问题。

你很难在VSTO中找到这些场景来查看bug,你肯定找到了一个; 用户将文本输入输入到加载项文本框中,并且消息流入工作表中的单元格! 在我的情况下; 消息未被泵送到Calendars_SelectedChange()事件的位置。 所以我们可以看到Hans在这里形成的行为的一个主题很好(从我在评论中链接的Q&A引用)

什么是永远不是一个问题(即通常可能有问题)是你依靠Excel中的消息泵来分派Windows消息,使这些控件响应输入的消息。 WPF和Winforms一样出错,它们有自己的调度循环,在消息传递到窗口之前过滤消息。 不使用各自调度员时出现问题的关键事项是标签和快捷键击等

然后有些人会在调度消息之前通过Excel进行自己的过滤来引发这种问题。 我猜一个反恶意软件的功能,微软永远担心乱搞Office应用程序。

并且不要忘记VSTO WPF Connect案例,菜单没有收到点击事件 解决方法涉及使用DispatcherFrame来抽取消息并为菜单订阅GotFocusEvent和LostFocusEvent

因此,该错误与响应输入的控件和在调度循环中错误地过滤或重定向的void WndProc(ref Message m)消息有关。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM