Подтвердить что ты не робот

Excel CustomTaskPane с управлением WebBrowser - проблемы с клавиатурой/фокусом

У меня такая точная проблема https://social.msdn.microsoft.com/Forums/vstudio/en-US/e417e686-032c-4324-b778-fef66c7687cd/excel-customtaskpane-with-webbrowser-control-keyboardfocus-issues?forum=vsto

Также упоминается здесь https://connect.microsoft.com/VisualStudio/feedback/details/521465/the-focus-issue-between-excel-cells-and-excel-customtaskpane-with-webbrowser-control

Я пишу плагин Excel 2010 с помощью Visual Studio Professional 2013. Я создал простую CustomTaskPane с дочерним элементом System.Windows.Forms.WebBrowser. Плагин работает очень хорошо, и я могу перемещаться внутри веб-браузера щелчком и изменять состояние флажков.

enter image description here

Когда я нажимаю на текстовое поле ввода, я получаю фокус, и я вижу, что курсор мигает, но когда я начинаю вводить текст, он отправляется в 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?

EDIT: Хорошо, я сделал еще несколько тестов.. Если я добавлю события в свой TaskPaneView для отслеживания ввода мыши и нажмите, они работают, но только если я удалю дочерний элемент веб-браузера. Значение веб-браузера каким-то образом блокирует эти события и не позволяет TaskPaneView понять, что у него есть фокус. Если бы я также добавил элемент управления текстовыми полями в TaskPaneView вместе с браузером, текстовое поле прекрасно работает, и TaskPaneView понимает, что он имеет фокус, а затем вводит текстовое поле внутри браузера, а затем начинает работу. Если я вызываю метод фокуса непосредственно в веб-браузере, TaskPaneView понимает, что он имеет фокус, и все работает отлично. Настолько ясно, что проблема не в том, что на клавиатуре, но вместо проблемы TaskPaneView не сказано, что она имеет фокус при щелчке браузера, поэтому нажатия клавиш идут в неправильную область. Если я смогу найти способ заставить TaskPaneView понять, что он должен фокусироваться, все должно работать.

4b9b3361

Ответ 1

Хорошо, я смог решить проблему, используя следующий код

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, который является просто UserControl с этим дочерним веб-браузером. У меня нет глубокого понимания того, почему или как это работает, но в основном я думаю, что происходит, я перехватываю WndProc, который является некоторой низкоуровневой функцией, которая обрабатывает сообщения, отправленные в окно. Я использую его, чтобы проверить, является ли сообщение 528, что, я думаю, означает notifyParent. Я не знаю, если это именно то сообщение, которое я должен слушать, но это похоже на работу.

Как только у меня появляется правильное сообщение, я проверяю, имеет ли TaskPaneView фокус, а если нет, я делаю его с помощью функции focus(). Ранее я проводил тестирование, которое показывало, что если бы я вручную вызывал focus на TaskPaneView, все работало нормально. Так что, если у меня нет фокуса, то вручную запросите фокус, и мы все в порядке

Я был бы признателен, если бы кто-то мог дать более подробное объяснение того, почему это работает, чтобы я мог понять это лучше, но, по крайней мере, я решил проблему. Спасибо Jeremy Thompson за то, что он заставил меня по-новому взглянуть на эту проблему.

Ответ 2

Q: Предоставьте более подробное объяснение, почему это работает, чтобы я мог лучше понять его

Рад, что у вас это работает! Чтобы выполнить анализ основных причин, нам нужно будет увидеть, куда отправлено это сообщение 528, и для этого нам понадобится исходный код Microsoft Excel.

Я не думаю, что стоит потратить больше времени на устранение неполадок или почему это происходит, потому что это ОШИБКА! Вход в систему Connect ошибка, помогающая Microsoft исправить это лучшее, что вы можете сделать. Мы можем только обойти это, это проблема в исходном коде.

Очень редко вы обнаруживаете, что эти сценарии в VSTO видят ошибки, и вы наверняка нашли их; где пользователь вводит текстовый ввод в текстовое поле надстройки, и сообщение втекает в ячейку на листе! В моей ситуации; где сообщение не было перекачано в событие Calendars_SelectedChange(). Таким образом, мы можем видеть немного темы поведения, формирующегося здесь, что Ханс объясняет хорошо (цитата из Q & A, с которой я связан в своем комментарии):

Что никогда не проблема (то есть часто бывает проблематично) заключается в том, что вы полагаетесь на насос сообщений в Excel для отправки сообщений Windows, сообщения, которые заставляют эти элементы управления реагировать на ввод. В WPF это происходит не так, как Winforms, у них есть собственный цикл отправки, который фильтрует сообщения до их доставки в окно. Ключевые вещи, которые идут не так, когда их диспетчер не используется , являются такими, как табуляция и короткие нажатия клавиш.

И затем некоторые, такая проблема будет вызвана тем, что Excel делает свою собственную фильтрацию перед отправкой сообщений. Я бы предположил, что функция защиты от вредоносных программ Microsoft навсегда беспокоится о программах, запутанных в приложениях Office.

И не забывайте VSTO WPF Connect с меню, не получающим события кликов. Обходной путь, связанный с использованием DispatcherFrame для накачки сообщений и подписки на GotFocusEvent и LostFocusEvent для меню.

Таким образом, ошибка связана с элементами управления, которые реагируют на ввод, а сообщения void WndProc(ref Message m) неправильно фильтруются или перенаправляются в цикле отправки.