Is there an IE notification box like gBrowser.getNotificationBox() in firefox

末鹿安然 提交于 2020-01-13 06:54:27

问题


A browser helper object I'm writing at the moment needs to alert the user of certain situations. I don't want to use the WinAPI function MessageBox, because it forces the user to click it away. Is there a possibillity to ask the user a question without blocking his workflow? He should be able to just ignore the question, if he isn't interested in it at the moment. Something like gBrowser.getNotificationBox() for firefox extensions would be ideal (example image appended).


回答1:


You can create your own window and use SetWindowPos to move it into the IE window.

If you want to play safe, I suggest you to write a browser band

There is not yet an API to customize the content of information bar aka security band.




回答2:


I finally could solve it. The answer below and the answers in this question did help me. There you can also find some more information about this problem. If someone has the same problem, here is my code. I don't think it will compile without the rest of my projects code, but it should give an idea, how to implement such a dialog box in a browser helper object:

Header:

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

Source:

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

The function webbrowser.getCurrentTabHwnd() returns the current tab window:

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

You also have to call NotificationBar::fitSize() on each resize of the browser window. For this you can use IHTMLWindow3::attachEvent(_T("onresize"),...) in the DocumentComplete event of IE.

Here the way to get an instance of IHTMLWindow3 in the DocumentComplete handler:

  1. IWebBrowser2::getDocument() returns IHTMLDocument2
  2. IHTMLDocument2::get_parentWindow() returns IHTMLWindow2
  3. IHTMLWindow2::QueryInterface(IID_IHTMLWindow3,...) is successful


来源:https://stackoverflow.com/questions/6985725/is-there-an-ie-notification-box-like-gbrowser-getnotificationbox-in-firefox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!