Мерцание дочернего окна для Internet Explorer - PullRequest
0 голосов
/ 16 августа 2011

Я пишу объект помощника браузера и хочу показать дочернее окно внутри окна 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 ]

1 голос
/ 16 августа 2011

Попробуйте освободить место для вашего контроля, манипулируя

Вторая ссылка также содержит пример получения дескриптора окна вкладок.Но я не знаю, работает ли это также из BHO или только в случае размещения элемента управления.

1 голос
/ 16 августа 2011

Вы должны изменить размер окна MSHTML, чтобы освободить место для вашего контроля.

0 голосов
/ 21 августа 2011

Наконец-то я смог ее решить (с помощью информации, которую я получил из множества разных ответов ниже).

Для тех из вас, у кого возникла та же проблема, вот решение: я должен уменьшить окноэто отображает веб-сайт HTML, поэтому мое собственное окно не перекрывается с ним.Для этого я получаю текущую вкладку, как в примере здесь .Это вкладка содержит окно 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);

Этот фрагмент кода теперь должен вызываться при каждом изменении размера окна браузера и при отображении / скрытии диалогов.

...