WebBrowser (http://support.microsoft.com/kb/324419)

BUG: Scroll Bars and Borders Appear in Framesets When You Navigate Again in BeforeNavigate

<script type="text/javascript">function loadTOCNode(){}</script>
Article ID:324419
Last Review:May 12, 2003
Revision:2.0
This article was previously published under Q324419
<script type="text/javascript"> var sectionFilter = "type != 'notice' && type != 'securedata' && type != 'querywords'"; var tocArrow = "/library/images/support/kbgraphics/public/en-us/downarrow.gif"; var depthLimit = 10; var depth3Limit = 10; var depth4Limit = 5; var depth5Limit = 3; var tocEntryMinimum = 1; </script> <script src="/common/script/gsfx/kbtoc.js?9" type="text/javascript"></script>

SYMPTOMS

<script type="text/javascript">loadTOCNode(1, 'symptoms');</script>
An empty scroll bar and sometimes a border appear if the following conditions are true:
You display a frameset in an application that hosts the WebBrowser control. -and-

You navigate to a frame in the frameset elsewhere in the BeforeNavigate or the BeforeNavigate2 event handler.
These items should not appear in the frame.

Back to the top

RESOLUTION

<script type="text/javascript">loadTOCNode(1, 'resolution');</script>
To work around the problem with the scroll bar, use one of the following methods:
In the HTML source for the frame page, manually add the "auto" or the "no" value to the scroll attribute in the <body> tag.
Add the scroll attribute dynamically through Dynamic HTML (DHTML).
Delay the navigation by posting a user-defined message and by performing the navigation in the user-defined message handler.
To work around the problem with the border, use one of the following methods:
Post a user-defined message, and then perform the navigation in the user-defined message handler.
Implement the IDocHostUIHandler interface, and then return DOCHOSTUIFLAG_NO3DBORDER in the GetHostInfo method.
For more information, see the "More Information" section of this article.

Back to the top

STATUS

<script type="text/javascript">loadTOCNode(1, 'status');</script>
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

Back to the top

MORE INFORMATION

<script type="text/javascript">loadTOCNode(1, 'moreinformation');</script>

Steps to Reproduce the Behavior

<script type="text/javascript">loadTOCNode(2, 'moreinformation');</script> NOTE: These steps are written for Microsoft Visual C++ 6.0.
1.Use the following code to create the frameset page, and then name the page frameset.htm:
<HTML>
	<FRAMESET rows="100%" cols="33%,33%,34%">
		<FRAME src="framesetChild.htm" frameborder="0" scrolling="0">
		</FRAME>
		<FRAME src="framesetChild.htm" frameborder="0" scrolling="0">
		</FRAME>
		<FRAME src="framesetChild.htm" frameborder="0" scrolling="0">
		</FRAME>
	</FRAMESET>
</HTML>
					
2.Copy frameset.htm to the Web server.
3.Use the following code to create a frame page, and then name the page framesetChild.htm:
<HTML>
	<body>
		This is a frame<br>
	</body>
</HTML>
					
4.Copy framesetChild.htm to the Web server.
5.Create a default Microsoft Foundation Classes (MFC) dialog-based application.
6.Right-click the dialog, and then click Insert ActiveX Control. Click Microsoft Web Browser Control.
7.To add a control data member for the WebBrowser control, follow these steps:
a. Open the Class Wizard, and then click the Member Variables tab.
b. Make sure that the dialog class is selected in the Class name list.
c. Click IDC_EXPLORER1 (which is the default ID of the WebBrowser control), and then click Add Variable.
d. You receive a message that states that the control has not been inserted into the project. Click OK to add the control to the project. Click OK again to accept the defaults for the CWebBrowser2 class in the Confirm Class dialog box.
e. Name your member variable m_webBrowser, and then click OK.
f. Close the Class Wizard.
8.To add the BeforeNavigate2 event handler, follow these steps:
a. Open the Class Wizard, and then click the Message Maps tab.
b. Make sure that the dialog class is selected in the Class name list.
c. Click IDC_EXPLORER1 in the Object IDs list, and then click BeforeNavigate2 in the Messages list.
d. Click Add Function to add the handler.
9.Add the following code:
void CMFCReproDlg::OnBeforeNavigate2Explorer1(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel) 
{
	static int nCount = 0;

	nCount++;
	if (nCount == 2) // this should be the navigate for the first frame in frameset
	{
		IWebBrowser* pWB = NULL;
		HRESULT hr = pDisp->QueryInterface(IID_IWebBrowser, (void**)&pWB);
		COleVariant ve((long)0);
		pWB->Navigate(::SysAllocString(L"http://myserver/mydirectory/framesetChild.htm"), &ve, &ve, &ve, &ve);
		*Cancel = VARIANT_TRUE;
	}
}
					
10.Add the following code to navigate to the frame page in the end of the OnInitDialog function.
BOOL CMFCReproDlg::OnInitDialog()
{
	...
	m_webBrowser.Navigate("http://myserver/mydirectory/frameset.htm", NULL, NULL, NULL, NULL);
					
11.Build the application, and then run it. Notice that the first frame has a scroll bar and a border on the right side.

Back to the top

Remove the Scroll Bar

<script type="text/javascript">loadTOCNode(2, 'moreinformation');</script> To remove the scroll bar, use one of following methods:
Add scroll attribute value of "auto" or "no" to the framesetChild.htm page as follows:
<HTML>
	<body scroll="auto">
		This is a frame<br>
	</body>
</HTML>
					
Dynamically add the scroll attribute value of "auto" or "no" in your code through DHTML as follows:
#include <mshtml.h>
// For brevity, this code adds the attribute to all documents.
void CMFCReproDlg::OnDocumentCompleteExplorer1(LPDISPATCH pDisp, VARIANT FAR* URL) 
{
	HRESULT hr = S_OK;
	IWebBrowser2* pWB = NULL;

	hr = pDisp->QueryInterface(IID_IWebBrowser2, reinterpret_cast<void**>(&pWB));
	
	IDispatch* pDocDisp = NULL;
	hr = pWB->get_Document(&pDocDisp);
	
	if (pDocDisp)
	{
		VARIANT v;
		VariantInit(&v);

		IHTMLDocument2* pDoc = NULL;
		hr = pDocDisp->QueryInterface(IID_IHTMLDocument2, reinterpret_cast<void **>(&pDoc));

		IHTMLElement* pElement = NULL;
		hr = pDoc->get_body(&pElement);

		IHTMLBodyElement* pBodyElement = NULL;
		hr = pElement->QueryInterface(IID_IHTMLBodyElement, (void**)&pBodyElement);

		if (pBodyElement)
		{
			pBodyElement->put_scroll(::SysAllocString(L"auto"));
			pBodyElement->Release();
		}
		pElement->Release();
		pDoc->Release();
		pDocDisp->Release();
	}
	pWB->Release();
}

						
NOTE: These first two options only remove the scroll bar. The border may still persist.
Post a user-defined message, and then perform the navigation in the user-defined message handler to delay the navigation.

Add the following code to the header file:
class CMFCReproDlg : public CDialog
{
...
	afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
};
						
Add the following code to the implementation file:
#define WM_MYMESSAGE (WM_USER + 1)
BEGIN_MESSAGE_MAP(CMFCReproDlg, CDialog)
	//{{AFX_MSG_MAP(CMFCReproDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_MYMESSAGE, OnMyMessage)
END_MESSAGE_MAP()

struct CMyData
{
	IWebBrowser2* m_pWB;
	BSTR m_pUrl;
};

void CMFCReproDlg::OnBeforeNavigate2Explorer1(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel) 
{
	static int nCount = 0;

	nCount++;
	if (nCount == 2) // this should be the navigate for the first frame in frameset
	{
        *Cancel = VARIANT_TRUE;
        CMyData *data = new CMyData;
		HRESULT hr = pDisp->QueryInterface(IID_IWebBrowser2, (void**)(&data->m_pWB));
        data->m_pUrl = ::SysAllocString(L"http://myserver/mydirectory/framesetChild.htm");
		PostMessage(WM_MYMESSAGE, (WPARAM)data, 0);
	}
}
LRESULT CMFCReproDlg::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
    CMyData *data = (CMyData*)wParam;
    COleVariant ve((long)0);
    data->m_pWB->Navigate(data->m_pUrl, &ve, &ve, &ve, &ve);
    delete data;
	return 1;
}
					

Back to the top

Remove the Border

<script type="text/javascript">loadTOCNode(2, 'moreinformation');</script> To remove the borders, use one of following methods:
Post a user-defined message, and then perform the navigation in the user-defined message handler.
Follow the steps in Microsoft Knowledge Base article Q196835 to provide the custom control site in which you can add the IDocHostUIHandler interface. For additional information, click the article number below to view the article in the Microsoft Knowledge Base:
196835 (http://support.microsoft.com/kb/196835/EN-US/) HOWTO: Override the MFC Default Control Containment
After you implement all the functions, you must add DOCHOSTUIFLAG_NO3DBORDER to the DOCHOSTUIINFO stucture in the dwFlags field for the GetHostInfo method. It is beyond the scope of this article to provide the steps to implement IDocHostUIHandler.
NOTE: The border problem does not appear in an Active Template Library (ATL) container because the ATL class, CAxHostWindow, already implements the IDocHostUIHandler interface. By default, CAxHostWindow enables this flag.  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
相关文章《DOS的古董美》 MD DocUmEnT: 3/26/2016 10:26:57 AM by Jimbowhy 当计算机技术越来越先进,越来越快速更新,作为电子FANS,发现这样的现状不仅带给从事这个行业的人更多的便利,还有更多的迷失!而DOS就像是那个本应有活力的游乐园,收集资料的过程中发现,国外确实把DOS当成了计算机世界的大游乐场!国内很多在玩开发板的的同学几乎都不懂得,其实个人电脑才是功能最齐全的“开花板”! - by Jimbowhy 为了混用汇编和C语言进行编程,就需要配套使用微软的C/C++语言编译器,也即是 Visual C++,它的前身是 Microsoft C/C++,最高版本好像是1992年的Microsoft(R) C/C++, Version 7.0,我手上就有MSC70.zip,还有1991年发布的MSC60.zip两个版本。更早的C语言开发工具就是1990年的QuickC(R) Compiler 2.51 Professional。然后就是Visual系列的天下了,最早的一版是1992年发行的Visual C++ 1.0,20张3.5英寸磁盘装,现在能看到的只有磁盘镜像了,镜像中的Link.EX_是SZDD压缩格式。这个版本支持16位和32位开发,集成MFC框架,集成资源编辑器。链接程序为32位 Executable Linker 1.00,同时提供 link.exe 和 link32.exe 两个命令。在 Win PC World 上下载到一个称为 msvc10_32s.iso 的镜像,它包含了 Win32 和 NT两个套开发工具,标明是 Visual C++ 1.0,但感觉不是,像是一个未发布的版本。因为最后一个DOS开发版本是 Dec 5, 1994发行的 Visual C++ 1.52c,也就是从这一套工具开始,链接程序不再叫做 Executable Linker,而是叫做分段模式程序链接器 Segmented Executable Linker,随CD发行的链接程序版本为 5.60.339,这个链接程序也是MASM32中使用的16位程序链接器。直到今天,它仍然具有强大的生命力,一些为MSDOS、Windows 3.1编写16位应用程序的程序员还在使用这个版本,我个人也很喜欢这样小巧的开发工具,因为我只需库文件和编译工具而已,完成编码后剩下的工作就交给make工具而不是IDE。
微软原版解决工具下载 1. 下载FileTool.exe,并解压 2. 打开VC6.0,点击File-Open Workspace,选择刚解压出来的FileTool.dsw,并确定 3. 点击Bulid-Build FileTool.dll,生成FileTool.dll文件 4. 把生成的FileTool.dll文件拷贝到合适的地方(避免误删),在VC6.0中点击Tools-Customize 5. 在出现的“Customize”对话框中,点击Add-Ins and Macro Files标签 6. 点击Browse,在文件类型下选 dll , 定位刚才生成的dll文件,点击确定,然后点击OK保存设置 7. 此时VC中会出现一个上面只有两个图标的工具栏,点击其右上角的“X”按钮将其关闭,然后关闭VC6.0并重新启动程序 将这个dll文件复制到X:\Program Files\Microsoft Visual Studio\Common\MSDev98\AddIns 重新打开VC++6.0,工具->定制->附加项和宏文件,选中FileTool Developer Studio Add-in即可。 此时打开VC6会有一个浮动工具栏(A O),点击A就是添加文件到工程,点击O就是打开文件 8. 还是在VC6.0中点击Tools-Customize 9. 在Customize对话框中点击Keboard标签 10. 从Category的下拉菜单框中选择File 11.在Commands窗口中选择FileOpen 12.在Current keys窗口中选择CTRL+O条目,并点击Remove 13.从Category的下拉菜单框中选择Project 14.在Commands窗口中选择InsertFilesIntoProject,如果之前给它注册了快捷键,则按照上面所说步骤移除之,默认情况下它是没有快捷键的 15.从Category的下拉菜单框中选择Add-Ins

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值