【问题标题】:Is there an IE notification box like gBrowser.getNotificationBox() in firefoxFirefox 中是否有类似 gBrowser.getNotificationBox() 的 IE 通知框
【发布时间】:2011-08-21 20:29:06
【问题描述】:

我现在正在编写的浏览器帮助对象需要提醒用户某些情况。 我不想使用 WinAPI 函数 MessageBox,因为它会强制用户单击它。 是否有可能在不阻塞工作流程的情况下向用户提问?如果他现在对这个问题不感兴趣,他应该可以忽略这个问题。 诸如 gBrowser.getNotificationBox() 之类的用于 firefox 扩展的东西将是理想的(附加示例图像)。

【问题讨论】:

  • 我知道 IE 有类似的东西(每次显示“Internet Explorer 阻止了 ActiveX [blah]”或其他什么时都会出现该条),但我不记得它是什么调用或如何以编程方式使用它。

标签: internet-explorer bho


【解决方案1】:

您可以创建自己的窗口并使用 SetWindowPos 将其移动到 IE 窗口中。

如果你想安全起见,我建议你写一个browser band

目前还没有一个 API 可以自定义信息栏(也称为安全带)的内容。

【讨论】:

  • 浏览器波段可以通过 IE 菜单显示,因此不适合消息框的需要。所以我认为 SetWindowPos 就是这样。是否有可能说“请自动调整父窗口的大小”或者我必须在 IE 的 OnResize 事件中调整子窗口的大小?我发现了一个有趣的教程 (msdn.microsoft.com/en-us/library/…)。那里的子窗口似乎是我想要的(除了定位在窗口底部而不是顶部),但是作者没有提到,他是怎么做到的。
  • 那个窗口实际上在浏览器之外,BHO 调整了浏览器的大小以便为编辑窗口留出一些空间。在标签式浏览时代,我认为您不应该在 BHO 中这样做。现在一个窗口可能会承载多个 BHO,而您不希望每次用户打开标签时都调整浏览器的大小。
【解决方案2】:

我终于可以解决它了。下面的答案和this 问题中的答案确实对我有所帮助。在那里,您还可以找到有关此问题的更多信息。 如果有人有同样的问题,这是我的代码。我不认为没有我的项目代码的其余部分它会编译,但它应该给出一个想法,如何在浏览器帮助对象中实现这样的对话框:

标题:

#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()。为此,您可以在 IE 的 DocumentComplete 事件中使用 IHTMLWindow3::attachEvent(_T("onresize"),...)。

在 DocumentComplete 处理程序中获取 IHTMLWindow3 实例的方法如下:

  1. IWebBrowser2::getDocument() 返回 IHTMLDocument2
  2. IHTMLDocument2::get_parentWindow() 返回 IHTMLWindow2
  3. IHTMLWindow2::QueryInterface(IID_IHTMLWindow3,...) 成功

【讨论】:

    猜你喜欢
    • 2023-04-02
    • 2012-03-07
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    相关资源
    最近更新 更多