宇宙火星
非常火狐
非常火狐
  • UID182
  • 注册日期2004-11-26
  • 最后登录2006-04-19
  • 发帖数660
  • 经验10枚
  • 威望0点
  • 贡献值0点
  • 好评度0点
阅读:6409回复:0

IETab插件的改进

楼主#
更多 发布于:2005-09-13 16:51
原创贴见:
http://forum.moztw.org/viewtopic.php?t=9664
毕竟目前来说,时不时还是要用IE一下.特别是国内众多的影音站点,短期内是难有什么改变.这个插件将IE核心集成在FF内,对于偶尔需要IE应付一下的情况,刚刚好.作者发布后,没人进一步完善.其实我对网页和FF的插件开发都是不甚了了,为了自己方便也只好赶鸭子上架.这里把自己的一点收获说一下,以便更多人将其继续完善.

这"套"插件有3部分,ieview扩展,ietab插件的两个文件ieview.dll和npieview.dll。
ieview扩展的主要函数是ievielauch。当你选择用ie浏览的时候,这个函数会将地址转换为"chrome://ieview/content/reloaded.html?url=" +要浏览地址。reloaded.html是在ieview扩展包里面的一个文件。里面的代码嵌入了ietab插件,就像嵌入flash插件一样,所以打开这个页面会调用ietab插件,并将要浏览的地址传给插件。
npieview.dll相当于一个壳(或者桥),真正的实现代码都在ieview.dll里面。ieview.dll相当于一个以ie为内核的微型浏览器,内有一个对话框和一个ie浏览器控件。reloaded.html调用插件后,会执行函数createiewindow完成浏览。问题在于很多时候会点击链接打开新窗口。IE控件打开新窗口会触发两个事件,newwindow2和OnBeforeNavigate2,多页面浏览和弹出广告的拦截都是通过这对两个事件的处理完成的。
void CIEDlg::OnNewWindow2(LPDISPATCH FAR* ppDisp, BOOL FAR* Cancel) 
{
	m_TempIE = new CWebBrowser2;
	CRect rc(0, 0, 0, 0);
	m_TempIE->Create( NULL, WS_CHILD, rc, this, IDC_IE2 );
	m_TempIE->ShowWindow(SW_HIDE);

	*ppDisp = m_TempIE->GetApplication();
}

void CIEDlg::OnBeforeNavigate2(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel) 
{
	CString url = V_BSTR(URL);
	*Cancel = TRUE;

	HMODULE hmod = GetModuleHandle(NULL);
	CString moz_path;
	GetModuleFileName( hmod, moz_path.GetBuffer(MAX_PATH), MAX_PATH);
	ShellExecute( NULL, "open", moz_path, url, NULL, SW_SHOWNORMAL );

	if( m_TempIE )
	{
		m_TempIE->DestroyWindow();	// delete is done in CWebBrowser::PostNCdestroy();
		m_TempIE = NULL;
	}
}

我觉得这里的实现比较不自然。大概意思就是,在OnNewWindow2事件里用一个不显示的窗口来接手打开新窗口的请求,在接下来的OnBeforeNavigate2事件里得到url,把隐藏的那个窗口销毁,调用ShellExecute来完成对url地址的浏览。
调用ShellExecute的结果是FF打开新tab(或窗口),也就是这个时候不再是用IE内核浏览。如果你在ieview扩展的设置里,设置了整个网站都用IE浏览的话(比如http://*.sina.com.cn),IEView扩展会监视到,于是在FF下载这个页面的过程中,ieview扩展会用reloaded.html页面重新浏览这个页面。过程就跟前面一样了。这里打开一个页面重复了2次。一个是造成浏览缓慢。更严重的是会丢失session,也就是你上一个页面是登录的,在这个页面就可能是未登录状态。有的网站就仍然能保持session,这里头的原理不清楚,可能跟服务器对session的管理方法有关系。
感觉这个实现过程是比较古怪的。插件需要调用ShellExecute来发送一个浏览请求,ShellExecute是微软的开发包提供的功能,按说FF应该有提供直接的功能吧。更主要的是,正常直接的方式应该是,直接创建含IE控件的新窗口,来完成打开新窗口。不知道是不是做不到这样的方式。大概翻了一下Mozilla的资料,没看出个所以然。暂时只能先做些小修改完善一下。

我想了两办法。一个是在OnBeforeNavigate2事件里,直接将url设成"chrome://ieview/content/reloaded.html?url=" +要浏览地址  的方式。不过ShellExecute不支持。于是将reload.html解包出来,改成“file///:/c:/reloaded.html?url=" +要浏览地址。这样改后,就不会再浏览两次了,速度正常。我原来一个打开新窗口播放电影的网站也正常了。用ie浏览的页面打开的新窗口都会继续用ie打开,不用设置IEView扩展。bt2站点仍然下载不了种子。还有一个电影站点叫我不要通过其他站点访问它:)
另一个方法,我还没试。也是在OnBeforeNavigate2里,强制原来窗口浏览,也就是不打开新窗口了。这样估计session和其他问题都能解决。但是限制一个tab,不够方便。还有要判断页面下载完成,以跳过一些广告,不然可能要浏览的窗口会被后来的广告窗口冲掉。
游客

返回顶部