Есть ли окно уведомлений IE, например gBrowser.getNotificationBox() в firefox?

Вспомогательный объект браузера, который я сейчас пишу, должен предупреждать пользователя об определенных ситуациях. Я не хочу использовать функцию WinAPI MessageBox, потому что она заставляет пользователя щелкнуть ее. Есть ли возможность задать вопрос пользователю, не блокируя его рабочий процесс? Он должен иметь возможность просто проигнорировать вопрос, если он не заинтересован в нем в данный момент. Что-то вроде gBrowser.getNotificationBox() для расширений firefox было бы идеальным (пример изображения прилагается). Firefox gBrowser.getNotificationBox()


person Heinzi    schedule 08.08.2011    source источник
comment
Я точно знаю, что в IE есть что-то подобное (эта полоса, которую вы получаете каждый раз, когда он говорит, что Internet Explorer предотвратил ActiveX [blah] или что-то в этом роде), но я не помню, как это называется или как вы будете использовать его программно.   -  person JAB    schedule 08.08.2011


Ответы (2)


Вы можете создать свое собственное окно и использовать SetWindowPos, чтобы переместить его в окно IE.

Если вы хотите перестраховаться, я предлагаю вам написать группу браузера.

Пока еще нет API для настройки содержимого информационной панели, также известной как полоса безопасности.

person Sheng Jiang 蒋晟    schedule 10.08.2011
comment
Полоса браузера будет отображаться через меню IE и, следовательно, не подходит для нужд окна сообщения. Поэтому я думаю, что SetWindowPos - это путь. Есть ли возможность сказать, пожалуйста, автоматически изменять размер вашего родительского окна или мне нужно изменить размер дочернего окна в событии OnResize IE? Я нашел интересное руководство (msdn. microsoft.com/en-us/library/). Дочернее окно вроде бы то, что я хочу (за исключением позиционирования внизу окна, а не вверху), но автор не упоминает, как он это сделал. - person Heinzi; 10.08.2011
comment
Это окно на самом деле находится за пределами браузера, BHO изменил размер браузера, чтобы оставить место для окна редактирования. Я не думаю, что вы должны делать это в BHO в эпоху просмотра вкладок. Теперь в одном окне может быть много BHO, и вы не хотите изменять размер браузера каждый раз, когда пользователь открывает вкладку. - person Sheng Jiang 蒋晟; 10.08.2011

Наконец-то я смог это решить. Ответ ниже и ответы в этом вопросе действительно помогли мне. Там же можно найти дополнительную информацию об этой проблеме. Если у кого-то такая же проблема, вот мой код. Я не думаю, что он скомпилируется без остального кода моих проектов, но он должен дать представление о том, как реализовать такое диалоговое окно в вспомогательном объекте браузера:

Заголовок:

#include "atlbase.h"
#include "atlwin.h"
#include "resources/resource.h"
#include <string>

class NotificationBar : public CDialogImpl<NotificationBar>
{
public:
    NotificationBar();

    enum { IDD = IDD_NOTIFICATIONBAR };

    BEGIN_MSG_MAP(CMyDialog)
        COMMAND_HANDLER(IDC_CANCEL, BN_CLICKED, OnBnClickedCancel)
    END_MSG_MAP()

    void show(const std::string &message);

    void show();

    void fitSize();

    void hide();

    void setText(const std::string &text);

private:

    LRESULT OnBnClickedCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);

    bool isShown;
};

Источник:

#include "NotificationBar.hpp"

NotificationBar::NotificationBar()
    :isShown(false)
{
}

void NotificationBar::show(const std::string &message)
{
    show();
    setText(message);
}

void NotificationBar::show()
{
    if(isShown)
    {
        fitSize();
        return;
    }
    isShown=true;

    WebBrowser webbrowser(BrowserHelperObject::getInstance().getBrowser());
    //Create dialog
    Create(webbrowser.getCurrentTabHwnd());
    //Set dialog size
    fitSize();
    ShowWindow(SW_SHOWNORMAL);
}

void NotificationBar::hide()
{
    if(!isShown) return;
    ShowWindow(SW_HIDE);
    DestroyWindow();
    isShown=false;
    fitSize();
}

void NotificationBar::fitSize()
{
    //This method is highly non portable. I is possible that it will not work in future versions of
    //Internet explorer. It is dependend on the layout of the IE window and on the class names
    //of its child windows (status bar, document view, ...).
    //If the plugin gets some strange layout on future versions of IE or doesn't show a message at all,
    //check and change this function.

    WebBrowser webbrowser(BrowserHelperObject::getInstance().getBrowser());
    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);
}

LRESULT NotificationBar::OnBnClickedCancel(WORD, WORD, HWND , BOOL&)
{
    hide();
    return 0;
}

void NotificationBar::setText(const std::string &text)
{
    if(0==SetDlgItemText(IDC_TEXT, CA2W(text.c_str())))
        ieaddon::util::bho::BrowserHelperObject::getInstance().ErrorMessageBox("Error",ieaddon::util::cast::IntToStr(GetLastError()));
}

Функция webbrowser.getCurrentTabHwnd() возвращает окно текущей вкладки:

HWND WebBrowser::getCurrentTabHwnd()
{
    CComPtr<IServiceProvider> pServiceProvider;
    if (!SUCCEEDED(_browser->QueryInterface(IID_PPV_ARGS(&pServiceProvider))))
        throw std::exception("QueryInterface for IID_IServiceProvider failed in WebBrowser::getCurrentTabHwnd()");

    CComPtr<IOleWindow> pWindow;
    if (!SUCCEEDED(pServiceProvider->QueryService(SID_SShellBrowser, IID_PPV_ARGS(&pWindow))))
        throw std::exception("QueryService for SID_SShellBrowser, IID_IOleWindow failed in WebBrowser::getCurrentTabHwnd()");

    HWND hwndBrowser = NULL;
    if (!SUCCEEDED(pWindow->GetWindow(&hwndBrowser)))
        throw std::exception("GetWindow failed in WebBrowser::getCurrentTabHwnd()");

    return hwndBrowser;
}

Вы также должны вызывать NotificationBar::fitSize() при каждом изменении размера окна браузера. Для этого вы можете использовать IHTMLWindow3::attachEvent(_T("onresize"),...) в событии DocumentComplete IE.

Вот способ получить экземпляр IHTMLWindow3 в обработчике DocumentComplete:

  1. IWebBrowser2::getDocument() возвращает IHTMLDocument2
  2. IHTMLDocument2::get_parentWindow() возвращает IHTMLWindow2
  3. IHTMLWindow2::QueryInterface(IID_IHTMLWindow3,...) выполнен успешно
person Heinzi    schedule 21.08.2011