更新:答案:需要两行正常的代码。谢谢诺塞拉蒂奥!
我在键盘上敲了几个小时,比我想在托管的浏览器控制应用程序中模拟 IE 的 Ctrl+N 行为还要多。不幸的是,由于我从下面的代码示例中抽象出来的复杂性,我不能让 IE 自己做 Ctlr+N。所以我必须手动完成。
请记住,我正在运行托管浏览器。因此,通常情况下,在新窗口中打开链接实际上会在我的应用程序中的一个新“选项卡”中打开它(它实际上不是一个选项卡,而是另一个窗口......但从外观上看,它是一个选项卡)。然而,Ctrl+N 是不同的——在这里,一个成熟的 IE 窗口会在按下时启动。
我认为我的问题在于提出问题 - 诚然,我是 WebBrowser 控件的新手,我发现它很讨厌。无论如何,过去一天我已经在 Internet 上进行了搜索,但无法提出一个优雅的解决方案。
基本上,理想的解决方案是在 WebBrowser 控件或其附属库中调用“NewWindow”函数;但是,我只能找到 * On *NewWindow 方法的位置,它们是事件处理程序,而不是事件信号器。据我所知,大多数时候,用户将创建事件......但是程序模拟呢?
我尝试研究一种 SENDMESSAGE 方法,在该方法中我可以使用 OnNewWindow 事件使用的 ID...最终导致崩溃。也许我可以回去让它工作,但我想确认这种方法甚至值得我花时间。
下一个方法应该是最优雅的,但遗憾的是没有成功,如下所示:
Navigate2(GetLocationURL().GetBuffer(), BrowserNavConstants::navOpenInNewWindow);
如果不是因为新窗口会在后台打开并在任务栏中闪烁,它会非常有效。需要单击以将其带到前面。
我试图以多种方式绕过限制,包括获取当前上下文的调度程序,然后使用该 IDispatch 对象调用 OnNewWindow2。然后,我将对 IWebBrowser 控件的调度对象调用 QueryInterface。webBrowser 控件(可能在新窗口的控制下)然后可以导航到原始上下文的页面。然而......这也是一个非常混乱的解决方案,最终会导致崩溃。
最后,我求助于手动调用 JavaScript 来获得所需的行为。真的??对于我的问题,真的没有比下面乱七八糟的代码更优雅的解决方案了吗?
if ((pMsg->wParam == 'N') && (GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_SHIFT) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000))
{
LPDISPATCH pDisp = CHtmlView::GetHtmlDocument();
IHTMLDocument2 *pDoc;
if (SUCCEEDED(pDisp->QueryInterface(IID_IHTMLDocument2, (void **)&pDoc)))
{
IHTMLWindow2* pWnd;
pDoc->get_parentWindow(&pWnd);
BSTR bStrLang = ::SysAllocString(L"JavaScript");
CString sCode(L"window.open(\"");
sCode.Append(GetLocationURL().GetBuffer());
sCode.Append(L"\");");
BSTR bStrCode = sCode.AllocSysString();
COleVariant retVal;
pWnd->execScript(bStrCode, bStrLang, retVal);
::SysFreeString(bStrLang);
::SysFreeString(bStrCode);
pDoc->Release();
}
pDisp->Release();
我很难相信我必须求助于这样的骇客来获得像当用户按下 Ctrl+N 时打开一个新窗口这样简单的东西。
请stackoverflow,请指出我忽略的显而易见的事情。