BUG: scroll bars and borders appear in framesets when you navigate again in beforenavigateview products that this Article applies.
Article ID |
: |
324419 |
Last Review |
: |
May 12,200 3 |
Revision |
: |
2.0 |
This article was previusly published under q324419on this pagesymptoms
Resolution
Status
More information
Steps to reproduce the behavior
Remove the scroll bar
Remove the border
Symptomsan 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 inBeforenavigateOrBeforenavigate2Event Handler. |
These items shocould not appear in the frame.
Back to the top
Resolutionto 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 toScrollAttribute in the <body> tag. |
• |
AddScrollAttribute dynamically through dynamic HTML (DHTML ). |
• |
Delay the navigation by posting a user-defined message and by locking 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. |
• |
ImplementIdochostuihandlerInterface, and then return dochostuiflag_no3dborder inGethostinfoMethod. |
For more information, see the "More Information" section of this article.
Back to the top
Statusmicrosoft 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 informationsteps to reproduce the behavior
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 clickInsert ActiveX Control. ClickMicrosoft Web browser control. |
7. |
To add a control data member for the webbrowser control, follow these steps:
A. |
Open the Class Wizard, and then clickMember variablesTab. |
B. |
Make sure that the dialog class is selected inClass NameList. |
C. |
ClickIdc_assumer1(Which is the default ID of the webbrowser control), and then clickAdd variable. |
D. |
You receive a message that states that the control has not been inserted into the project. ClickOKTo add the control to the project. ClickOKAgain to accept the defaults forCwebbrowser2Class inConfirm classDialog box. |
E. |
Name your member variable m_webbrowser, and then clickOK. |
F. |
Close the Class Wizard. |
|
8. |
To addBeforenavigate2Event Handler, follow these steps:
A. |
Open the Class Wizard, and then clickMessage mapsTab. |
B. |
Make sure that the dialog class is selected inClass NameList. |
C. |
ClickIdc_assumer1InObject IDSList, and then clickBeforenavigate2InMessagesList. |
D. |
ClickAdd functionTo 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 ofOninitdialogFunction.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
To remove the scroll bar, use one of following methods:
• |
AddScrollAttribute Value of "Auto" or "no" to the framesetchild.htm page as follows:<HTML><body scroll="auto">This is a frame<br></body></HTML>
|
• |
Dynamically AddScrollAttribute 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_MAPON_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
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 addIdochostuihandlerInterface. 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 toDochostuiinfoStucture inDwflagsField forGethostinfoMethod. It is beyond the scope of this article to provide the steps to implementIdochostuihandler. |
Note: The border problem does not appear in an Active Template Library (ATL) container because the ATL class,Caxhostwindow, Already implementsIdochostuihandlerInterface. By default,CaxhostwindowEnables this flag.