[英]Child window for Internet explorer flickering
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.我正在编写一个浏览器助手 object 并想在 Internet Explorer window 中显示一个孩子 window 以向用户显示一些消息。 I use DS_CONTROL and WS_CHILDWINDOW and want to get a behaviour similar to the message in this image:
我使用 DS_CONTROL 和 WS_CHILDWINDOW 并希望获得类似于此图像中消息的行为:
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.我成功插入并显示了一个子 window,但是 window 闪烁,有时它是可见的,有时网站内容在 z 坐标中高于 window。 I tried to set the child window as topmost window, but that didn't change anything.
我试图将子 window 设置为最顶层的 window,但这并没有改变任何东西。 How can I get the child window to be always visible until it is closed?
如何让子 window 在关闭之前始终可见? Here is some source code I use:
这是我使用的一些源代码:
resource.rc:资源.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:对话 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);
You have to resize the MSHTML window to make room for your control.您必须调整 MSHTML window 的大小以便为您的控制腾出空间。
Try making room for your control by manipulating尝试通过操纵为您的控制腾出空间
The second link also contains an example for getting the window handle of tabs.第二个链接还包含一个示例,用于获取选项卡的 window 句柄。 But I don't know if this also works from a BHO or only if hosting the control.
但我不知道这是否也适用于 BHO 或仅在托管控件时有效。
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.对于那些有同样问题的人,这里的解决方案是:我必须缩小显示 HTML 网站的 window,所以我自己的 window 不与它重叠。 For this I get the current tab like in the example here .
为此,我得到了此处示例中的当前选项卡。 This tab window contains the html document window and the status bar.
此选项卡 window 包含 html 文档 window 和状态栏。 So I call FindWindowEx twice to get the HWNDs of those two windows:
所以我调用 FindWindowEx 两次来获取这两个 windows 的 HWND:
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.然后我调整文档 window 的大小,以便它填充整个客户区,除了状态栏占据的位置和我的对话框占据的位置。 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):
这是代码(webbrowser.getCurrentTabHwnd() 是上面提到的示例的实现。isShown 是一个变量,指示是否应该显示我的对话框):
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.现在必须在每个浏览器 window 调整大小和对话框显示/隐藏上调用这段代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.