Вспомогательный объект браузера, который я сейчас пишу, должен предупреждать пользователя об определенных ситуациях. Я не хочу использовать функцию WinAPI MessageBox, потому что она заставляет пользователя щелкнуть ее. Есть ли возможность задать вопрос пользователю, не блокируя его рабочий процесс? Он должен иметь возможность просто проигнорировать вопрос, если он не заинтересован в нем в данный момент. Что-то вроде gBrowser.getNotificationBox() для расширений firefox было бы идеальным (пример изображения прилагается).
Есть ли окно уведомлений IE, например gBrowser.getNotificationBox() в firefox?
Ответы (2)
Вы можете создать свое собственное окно и использовать SetWindowPos, чтобы переместить его в окно IE.
Если вы хотите перестраховаться, я предлагаю вам написать группу браузера.
Пока еще нет API для настройки содержимого информационной панели, также известной как полоса безопасности.
Наконец-то я смог это решить. Ответ ниже и ответы в этом вопросе действительно помогли мне. Там же можно найти дополнительную информацию об этой проблеме. Если у кого-то такая же проблема, вот мой код. Я не думаю, что он скомпилируется без остального кода моих проектов, но он должен дать представление о том, как реализовать такое диалоговое окно в вспомогательном объекте браузера:
Заголовок:
#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:
- IWebBrowser2::getDocument() возвращает IHTMLDocument2
- IHTMLDocument2::get_parentWindow() возвращает IHTMLWindow2
- IHTMLWindow2::QueryInterface(IID_IHTMLWindow3,...) выполнен успешно