Как я могу гарантировать, что диалог будет модальным при открытии из IE BHO?
-
02-07-2019 - |
Вопрос
У меня есть вспомогательный объект браузера Internet Explorer (BHO), написанный на C#, и в разных местах я открываю формы как модальные диалоги.Иногда это работает, но в некоторых случаях нет.В настоящее время я могу воспроизвести случай, когда IE запускает javascript для открытия других дочерних окон...видимо где-то путаюсь....
Проблема в том, что когда я звоню:
(new MyForm(someParam)).ShowDialog();
форма не модальная, поэтому я могу щелкнуть окно IE, и оно получит фокус.Поскольку IE выполняет мой код, он не обновляется, и поэтому пользователю кажется, что IE зависает.
Есть ли способ гарантировать, что форма будет открыта как модальная, т. е. невозможно скрыть форму за окнами IE.
(Я использую IE7.)
Примечание:это аналогичный вопрос эта почта хотя это использует Java.Я предполагаю, что решение заключается в правильной передаче IWin32Window окна IE, поэтому я изучаю этот вопрос.
Решение 2
Я не собирался отвечать на свой вопрос, но...
Кажется, что если вы передадите правильный IWin32Window методу ShowDialog(), он будет работать нормально.Хитрость в том, как этого добиться.Вот как я это сделал, где siteObject — это объект, переданный в метод SetSite() BHO:
IWebBrowser2 browser = siteObject as IWebBrowser2;
if (browser != null) hwnd = new IntPtr(browser.HWND);
(new MyForm(someParam)).ShowDialog(new WindowWrapper(hwnd));
...
// Wrapper class so that we can return an IWin32Window given a hwnd
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get { return _hwnd; }
}
private IntPtr _hwnd;
}
Благодаря Райан для класса WindowWrapper, хотя я надеялся, что для этого существует встроенный способ?
ОБНОВЛЯТЬ:это не будет работать в IE8 с защищенным режимом, поскольку он обращается к HWND за пределами того, что должно быть.Вместо этого вам придется использовать HWND текущей вкладки (или какое-то другое решение?), например.см. пример .net в эта почта для способа получить это.
Другие советы
Вот более краткая версия кода WindowWrapper Райана/Рори:
internal class WindowWrapper : IWin32Window
{
public IntPtr Handle { get; private set; }
public WindowWrapper(IntPtr hwnd) { Handle = hwnd; }
}