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

我有这个确切的问题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插件。我用一个System.Windows.Forms.WebBrowser子程序创build了一个简单的CustomTaskPane。 该插件工作正常,我可以通过点击浏览网页浏览器,并改变checkbox的状态。

在这里输入图像描述

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

当function区加载时,我添加自定义任务窗格。

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标题会稍微变暗,并在文本框中捕获文本。

我怎样才能解决这个问题,以便当我点击input文本框文本进入框,而不是Excel?

编辑:好的,我做了一些更多的testing。 如果我添加事件在我的TaskPaneView跟踪鼠标进入并单击他们的工作,但只有当我删除Web浏览器子。 这意味着Web浏览器以某种方式阻止这些事件,并阻止TaskPaneView了解它的重点。 如果我还将一个文本框表单控件添加到浏览器旁边的TaskPaneView中,则该文本框完全正常工作,并且TaskPaneView知道它具有焦点,然后浏览器中的input文本字段将开始工作。 如果我直接在Web浏览器上调用焦点方法,那么TaskPaneView就会明白它具有焦点,而且一切正常。 所以显然这个问题并不是真正的键盘问题,而是一个TaskPaneView的问题,当浏览器被点击时,没有被告知它有焦点,所以击键到了错误的地方。 如果我能find一种方法使TaskPaneView明白它已经聚焦每一个应该工作。

好吧,我能够解决这个问题使用下面的代码

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

我将这个函数添加到我的TaskPaneView中,它只是一个带有该webbrowser子项的UserControl。 我不知道为什么或如何工作,但基本上我认为发生了什么是我拦截WndProc这是一些低级别的function,处理消息发送到窗口。 我用它来检查是否消息是528,我认为这意味着notifyParent。 我不知道这是否是我应该听的那个消息,但是它似乎工作。

一旦我有正确的消息消息,我检查是否有TaskPaneView有焦点,如果没有,我给焦点与focus()函数。 我之前做过testing,显示如果我手动调用focus的TaskPaneView一切工作正常。 所以,如果我没有专注,那么手动请求焦点,我们都很好。

如果有人能够提供更详细的说明,为什么这样做能够更好地理解,我至less会解决这个问题。 感谢Jeremy Thompson让我以新的方式思考这个问题。

问:提供一个更详细的解释,为什么这个工作,所以我可以更好地理解它

真高兴你做到了! 为了执行根本原因分析,我们需要知道528消息的发送位置,我们需要使用Microsoft Excel源代码来完成。

我不认为值得花费时间解决问题,或者为什么会发生这种情况,因为这是一个错误! logging连接错误以帮助Microsoft修复它是您可以做的最好的事情。 我们只能解决它,这是他们的源代码中的一个问题。

在VSTO中发现这些场景很难看到错误,而且你已经find了一个; 用户input文本input到加载项文本框中,并且消息stream入工作表中的单元格! 在我的情况下, 消息未被传送到Calendars_SelectedChange()事件。 所以我们可以看到汉斯在这里形成的一些行为主题(引自我在评论中提到的Q&A)

什么不是问题(即可能经常会有问题)是您依靠Excel中的消息泵来发送Windows消息,这些消息使这些控件响应input。 这在WPF中和WinForms一样错误,他们有自己的调度循环,在消息传递到窗口之前过滤消息。 关键的事情,当他们各自的调度不使用时出现问题,如tabbing和快捷键击

然后一些,这种问题将由Excel在分派消息之前做自己的过滤。 我猜想在一个反恶意软件function,微软永远担心与Office应用程序搞乱的程序。

不要忘记VSTO WPF连接案例菜单不接受点击事件 。 该解决方法涉及使用DispatcherFrame来抽取消息并为菜单订阅GotFocusEvent和LostFocusEvent

所以这个bug就是对input进行响应的控件,以及在调度循环中错误地过滤或redirect的void WndProc(ref Message m)消息。