CHtmlView iFrame 绘制

 

 

今天遇到了一个奇怪的问题。

问题重现:

在xp系统上,浏览器版本是IE7,使用CHtmlView控件,也就是WebBrowser2控件 。加载一个html文件,这个html中有一个iframe,这个iframe的内容根据页面的响应加载不同的框架html。  在加载之前会在这个CHtmlView控件之上绘制一个窗口, 通知用户等待。   每次切换iframe的src都会有这个等待窗口。   但是当等待窗口隐藏之后,iframe的上一次显示的页面和这一次显示的页面有问题:  上一次显示的页面在这一次显示的页面之上,重合了。  上次的页面只有画面,不能进行控件操作。   这严重影响了用户体验。

 

过程是在CHtmlView中截获DocumentComplete,根据加载的不同页面给主窗口发送不同的消息,进行数据的获取。 获取完数据再通过调用iframe页面的js进行交互。

 

经过测试,这个问题在Win7上没有。

 

记录一下以下几个方面的测试。

 

经过下面的修改,不会出现这个问题:

a. 将DocumentComplete中的消息发送注释

b.将等待窗口这个功能取消

c.将等待窗口的窗口透明效果取消

 

经过下面的修改,测试无效:

a.将等待窗口放在主线程中.

b.将iframe动态创建, 切换时销毁.

c.强制刷新CHtmlView窗口

 

猜测结果:

由于切换iframe的内容所获取的数据是在主线程里,可能因为CHtmlView的重绘消息被阻塞了,而其重绘消息的优先级很低,所以造成了这个原因。解决方法可能是将主线程的数据获取放到其他线程中去,这个方法没有测试,因为它将修改大量的代码。

 

解决办法:

//在等待窗口隐藏的时候, 查找出Internet Explorer_Server这个窗口,然后强制刷新

 

         CComPtr<IWebBrowser2> web2=NULL;
	m_pBrowserApp->QueryInterface(IID_IWebBrowser2,(void**)&web2);

	if(web2==NULL)
	{
		return;
	}

	HWND handle=NULL;

	CComPtr<IServiceProvider> psp;
	bbb->QueryInterface(IID_IServiceProvider,(void**)&psp);

	CComPtr<IOleWindow> pow;
	psp->QueryService(SID_SShellBrowser,IID_IOleWindow, (void**)&pow);
	if(pow!=NULL)
	{
		//this is “Shell Embedding”.
		pow->GetWindow(&handle);    
	}

	TCHAR szClassName[MAX_PATH];
	HWND hwnd=handle;
	while(true)
	{
		::GetClassName(hwnd,szClassName,MAX_PATH);
		if(::_wcsicmp(L"Internet Explorer_Server",szClassName)==0)
		{
			break;
		}

		//
		hwnd=::GetWindow(hwnd,GW_CHILD);
		if(hwnd==NULL)
			break;
	}

	::InvalidateRect((HWND)hwnd,NULL,FALSE);
         ::UpdateWindow(hwnd);


 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值