问题
I am writing a browser helper object and want to show a child window inside the internet explorer window to show the user some messages. I use DS_CONTROL and WS_CHILDWINDOW and want to get a behaviour similar to the message in this image:
I succeeded in inserting and showing a child window, but the window is flickering and sometimes it's visible and sometimes the website content is above the window in the z coordinate. I tried to set the child window as topmost window, but that didn't change anything. How can I get the child window to be always visible until it is closed? Here is some source code I use:
resource.rc:
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"
//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_NOTIFICATIONBAR DIALOG 0, 0, 186, 95
STYLE DS_3DLOOK | DS_CONTROL | DS_MODALFRAME | DS_SYSMODAL | DS_SHELLFONT | WS_VISIBLE | WS_CHILDWINDOW
EXSTYLE WS_EX_TOPMOST
FONT 8, "Ms Shell Dlg"
{
DEFPUSHBUTTON "OK", IDOK, 129, 7, 50, 14
PUSHBUTTON "Cancel", IDCANCEL, 129, 24, 50, 14
LTEXT "Static", IDC_STATIC, 25, 16, 68, 21, SS_LEFT
}
Dialog class:
#include "atlbase.h"
#include "atlwin.h"
#include "resources/resource.h"
class CMyDialog : public CDialogImpl<CMyDialog>
{
public:
enum { IDD = IDD_NOTIFICATIONBAR };
BEGIN_MSG_MAP(CMyDialog)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
COMMAND_HANDLER(IDCANCEL, BN_CLICKED, OnBnClickedCancel)
END_MSG_MAP()
CMyDialog() {Create(::GetActiveWindow());}
~CMyDialog() {DestroyWindow();}
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/,
BOOL& /*bHandled*/)
{
// ::MessageBox(NULL,_T("OnInit"),_T("OnInit"),MB_ICONINFORMATION|MB_OK);
// Do some initialization code
return 1;
}
static CMyDialog &getInstance()
{
static CMyDialog dlg;
return dlg;
}
public:
LRESULT OnBnClickedCancel(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
ShowWindow(SW_HIDE);
return 0;
}
};
Call:
CMyDialog &bar=CMyDialog::getInstance();
bar.ShowWindow(SW_SHOWNORMAL);
回答1:
You have to resize the MSHTML window to make room for your control.
回答2:
Try making room for your control by manipulating
- IWebBrowser2.Top or
- the HWND returned by IWebBrowser2.HWND
The second link also contains an example for getting the window handle of tabs. But I don't know if this also works from a BHO or only if hosting the control.
回答3:
Finally I could solve it (with the help of the information I got from the many different answers below).
For those of you having the same problem, here the solution: I have to shrink the window that is displaying the HTML website, so my own window doesn't overlap with it. For this I get the current tab like in the example here. This tab window contains the html document window and the status bar. So I call FindWindowEx twice to get the HWNDs of those two windows:
FindWindowEx(tab,NULL,_T("Shell DocObject View"),_T("")) //html document window
FindWindowEx(tab,NULL,_T("msctls_statusbar32"),_T("")) //status bar
Then I resize the document window so that it fills the whole client area except for the place taken by the status bar and the place taken by my dialog. Here is the code (webbrowser.getCurrentTabHwnd() is an implementation of the example here mentioned above. isShown is a variable indicating, if my dialog should be shown or not):
CWindow tab(webbrowser.getCurrentTabHwnd());
CWindow child(FindWindowEx(tab,NULL,_T("Shell DocObject View"),_T("")));
CWindow statusbar(FindWindowEx(tab,NULL,_T("msctls_statusbar32"),_T("")));
RECT statusbarrect;
statusbar.GetWindowRect(&statusbarrect);
RECT documentrect;
tab.GetClientRect(&documentrect);
documentrect.bottom-=(statusbarrect.bottom-statusbarrect.top);
if(isShown)
{
//Request document window rect
static const unsigned int DLGHEIGHT=50;
RECT dialogrect=documentrect;
documentrect.top+=DLGHEIGHT;
dialogrect.bottom=dialogrect.top+DLGHEIGHT;
//Shrink document window
MoveWindow(&dialogrect);
}
child.MoveWindow(&documentrect);
This piece of code now has to be called on each browser window resize and on dialog show/hide.
来源:https://stackoverflow.com/questions/7078105/child-window-for-internet-explorer-flickering