2011-08-08 60 views
1

我正在寫的瀏覽器幫助對象需要提醒用戶某些情況。 我不想使用WinAPI函數MessageBox,因爲它強制用戶點擊它。 是否有可能在不阻礙工作流程的情況下向用戶提出問題?如果他目前對此不感興趣,他應該能夠忽略這個問題。 像gBrowser.getNotificationBox()爲firefox擴展將是理想的(附加示例圖像)。 Firefox gBrowser.getNotificationBox()在Firefox中是否有像IE瀏覽器通知框gBrowser.getNotificationBox()

+0

我知道一個事實,即IE瀏覽器有類似的東西(你每次都會看到它表示「Internet Explorer阻止了一個Activ eX [blah]「或其他),但我不記得它是什麼,或者你會如何以編程方式使用它。 – JAB

回答

0

我終於可以解決它。下面的答案和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」)...)。

這裏得到IHTMLWindow3的實例中的DocumentComplete處理方式:

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

這不適用於所有請求。特別是AJAX .. –

0

您可以創建自己的窗口並使用SetWindowPos將其移動到IE窗口中。

如果你要玩的安全,我建議你寫一個browser band

目前還沒有自定義信息欄的安全又名帶內容的API。

+0

瀏覽器樂隊可通過IE菜單顯示,因此不適合消息框的需要。所以我認爲SetWindowPos就是這樣。是否有可能說「請自動調整您的父窗口大小」還是必須調整IE的OnResize事件中的子窗口?我找到了一個有趣的教程(http://msdn.microsoft.com/en-us/library/bb250436%28v=VS.85%29.aspx#bho_lifecycle)。孩子的窗口似乎是我想要的(除了窗口底部而不是頂部的位置),但作者並未提及他是如何做到的。 – Heinzi

+0

這個窗口實際上是在瀏覽器之外,BHO調整了瀏覽器的大小,爲編輯窗口留下了一些空間。在標籤瀏覽時代,我認爲你不應該在BHO中這樣做。現在,一個窗口可能會承載許多BHO,並且您不希望每次用戶打開選項卡時調整瀏覽器的大小。 –

相關問題