Is there an IE notification box like gBrowser.getNotificationBox() in firefox
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 wo开发者_开发百科rkflow? 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).
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.
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:
- IWebBrowser2::getDocument() returns IHTMLDocument2
- IHTMLDocument2::get_parentWindow() returns IHTMLWindow2
- IHTMLWindow2::QueryInterface(IID_IHTMLWindow3,...) is successful
精彩评论