互联网资源管理器闪烁的子窗口

时间:2011-08-16 12:20:07

标签: c++ internet-explorer winapi atl bho

我正在编写一个浏览器帮助程序对象,并希望在Internet Explorer窗口中显示一个子窗口,以向用户显示一些消息。我使用DS_CONTROL和WS_CHILDWINDOW并希望获得与此图像中的消息类似的行为:enter image description here

我成功插入并显示了一个子窗口,但窗口闪烁,有时它可见,有时网站内容在z坐标的窗口上方。我试图将子窗口设置为最顶层窗口,但这并没有改变任何东西。如何让子窗口在关闭之前始终可见?这是我使用的一些源代码:

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
}

对话类:

#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;
   }
};

呼叫:

CMyDialog &bar=CMyDialog::getInstance();
bar.ShowWindow(SW_SHOWNORMAL);

3 个答案:

答案 0 :(得分:1)

您必须调整MSHTML窗口的大小,以便为您的控件腾出空间。

答案 1 :(得分:1)

尝试通过操作

为控制腾出空间

第二个链接还包含获取选项卡窗口句柄的示例。但我不知道这是否也可以从BHO起作用,或者仅在托管控件的情况下起作用。

答案 2 :(得分:0)

最后我可以解决它(借助我从下面的许多不同答案得到的信息)。

对于那些有同样问题的人,这里解决方案: 我必须缩小显示HTML网站的窗口,所以我自己的窗口不会与它重叠。 为此,我得到了示例here中的当前选项卡。 此选项卡窗口包含html文档窗口和状态栏。 所以我两次调用FindWindowEx来获取这两个窗口的HWND:

FindWindowEx(tab,NULL,_T("Shell DocObject View"),_T("")) //html document window
FindWindowEx(tab,NULL,_T("msctls_statusbar32"),_T("")) //status bar

然后我调整文档窗口的大小,使其填充整个客户区域,除了状态栏占用的位置和对话框占用的位置。下面是代码(webbrowser.getCurrentTabHwnd()是上面提到的示例here的一个实现.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);

现在必须在每个浏览器窗口调整大小和对话框显示/隐藏时调用此代码。