Click here to Skip to main content
15,895,142 members
Articles / Desktop Programming / MFC
Article

How to Modify/Remove the context menu shown by an IE WebBrowser Control

Rate me:
Please Sign up or sign in to vote.
3.75/5 (4 votes)
16 Jul 20022 min read 111.1K   1.3K   28   12
Here is an easy solution for hiding/Replacing the right click menu on a Web Browser window.

Introduction

Here is an easy solution for hiding/Replacing the right click menu on a Web Browser window.

I had to implement a news group reader and writer. The news reader/writer used the IWebBrowser2 control as the message display/edit window. If you do a right click on it, there is an option View Source and other menu items. If I had an option, I want to act like I implemented everything from scratch. But the Right Click menu put a hole in my plan and revealed that I reused IE control. Besides anyway we didn’t want our users to mess around with HTML source code etc or expose some of them to brain damage from seeing real weird stuff while all they asked for was some news group item. Web browser captures the right click and shows the default IE right click menu. So how do I remove it?

I trap the PreTranslateMessage function of the application class (CWinApp derived class). In case of a right click, I will see if it is a webbrowser control which generated the message, and if so I display our menu. Here is our example.

BOOL CWebBrowserTestApp::PreTranslateMessage(MSG* pMsg)
{
    // We have a right click    
    if (    (WM_RBUTTONDOWN == pMsg->message) ||
        (WM_RBUTTONDBLCLK == pMsg->message))
    {
        // Now verify it is from our web browser
        CWebBrowserTestDlg* pWBDlg = (CWebBrowserTestDlg*)AfxGetMainWnd();
        if(pWBDlg->isThisOurBrowser(pMsg->hwnd))
        {
            // If so show our menu!
            pWBDlg->showOurMenu();
            // mark as handled
            return TRUE;
        }
    }
    return CWinApp::PreTranslateMessage(pMsg);
}

Now that I have trapped the right click, I will have to ask the window that owns the webbrowser control to see if the window, which got the right click, is a webbrowser window. It is a little twitchy here, I will have to specifically go case by case, meaning I will have to check, if not this webbrowser, the other usage instance of webbrowser and other(meaning if a dialog box had three controls which where webbrowsers, I might have a CWnd m_WndBrowser1, CWnd m_WndBrowser2 and CWnd m_WndBrowser3). In attached example I have a dialog with one webbrowser control in it. I have a member variable for the webbrowser window as follows.

CWnd m_WndBrowser

My function will have to do a little bit more than just matching the window handles. Why so? A nested frame inside IE is again an instance of IE. HTMLs having nested frames will return a different window handle for different frames inside the same parent IE Window. So what will be my logic? I will have to traverse via GetParent from a frame to the parent IE window, whose window handle I already know or till I don’t have a parent of type IE. How do we know if its an IE Window? The Window class name will be "Internet Explorer_Server". That’s what the next function does, see if our window is an Internet Explorer, if so we know, the outer shell window will be the parent of doc-view which will be the parent of the IE class window.

// This fn checks if this is a IE type window and returns 
// the outer hosting Shell window handle for it, if it is one! else NULL 
HWND CWebBrowserTestDlg::getParentWebBrowserWnd(HWND hMyWnd)
{
    HWND   hRetWBWnd = NULL;

    static TCHAR tszIEClass[] = "Internet Explorer_Server";
    TCHAR   tszClass[sizeof(tszIEClass)+1];

    // Compare if our window is of type IE class
    ::GetClassName( hMyWnd,tszClass,sizeof(tszClass));
    if(0 == _tcscmp(tszClass, tszIEClass))
    {
         // Then get the Shell which hosts the IE doc view window
         hRetWBWnd = ::GetParent(::GetParent(hMyWnd));
    }
    return hRetWBWnd;
}

// Checks if message window is our WebBrowser control and if so returns TRUE
BOOL CWebBrowserTestDlg::isThisOurBrowser(HWND hMyWnd)
{
    HWND hWndOurWebBrowser = (HWND)m_WndBrowser.GetSafeHwnd();
    // Get the Parent webbrowser window if any
    HWND hParentWBWnd = getParentWebBrowserWnd(hMyWnd);
    
    // Now, we can have nested frames .. 
    // meaning a frame inside a frame is yet another webbrowser
    // So our m_WndBrowser guy can be way up there .. 
    // so we have to iterate up to him through parent frames
    // till we have a match or no more WB type parent
    while(    (NULL != hParentWBWnd) &&
        (hParentWBWnd != hWndOurWebBrowser))
    {
        // Get the Parent of the Webbrowser window I have, recursively
        hParentWBWnd = getParentWebBrowserWnd(::GetParent(hParentWBWnd));
    }
    return (NULL != hParentWBWnd);
}

Now the next function is a normal fn to show a popup menu from resource and I am not going to explain it. People who need an explanation should please read the help.

// This is a trivial fn which gets a submenu from a resource
// and displays it at the current cursor position
void CWebBrowserTestDlg::showOurMenu()
{
    POINT  CurPoint;
    GetCursorPos(&CurPoint);

    CMenu  ReplaceMenu;
    //Make your custom menu here
    ReplaceMenu.LoadMenu(IDR_RIGHTCLICK);
    // Do we have a menu loaded
    if(::IsMenu(ReplaceMenu.m_hMenu))
    {
        // this is my popup menu
        CMenu* pMyPopup = ReplaceMenu.GetSubMenu(0);
        if(NULL != pMyPopup)
        {
            // Show it
            pMyPopup->TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON, 
                                      CurPoint.x, CurPoint.y, this );
            // deleting me and my parent when I am done
            pMyPopup->DestroyMenu();
            ReplaceMenu.DestroyMenu();
        }
    }
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United States United States
I am a software programmer with 17 years of experience working on Microsoft technologies using various tools. Using spare time I play Ping Pong and enjoy music and movies.I come from Trichur, a town in kerala, India. I love code forums and feel obligated to contribute every once in a while.

I think Internet and the information share it provides is mind boggling. Do we ever believe, tomorrow always brings to reality,above and beyond what dreams can glimpse.

Comments and Discussions

 
GeneralApplet in WebBrowser Pin
colin-12312-Sep-06 23:51
colin-12312-Sep-06 23:51 
QuestionCan it be done for PocketPC - Internet Explorer Pin
abhijitv24-Feb-06 1:50
abhijitv24-Feb-06 1:50 
Generalshift+left mouse click Pin
themanlee4-Aug-05 12:02
themanlee4-Aug-05 12:02 
Questionhow to navigate to HTML from resources Pin
george ivanov18-Dec-03 2:27
george ivanov18-Dec-03 2:27 
GeneralThis is how... Pin
Anonymous11-Sep-02 0:14
Anonymous11-Sep-02 0:14 
GeneralRe: This is how... Pin
Anonymous11-Sep-02 0:16
Anonymous11-Sep-02 0:16 
GeneralAnother way Pin
_nalex17-Jul-02 7:13
_nalex17-Jul-02 7:13 
GeneralRe: Another way Pin
Sonny Bob-Manuel6-Aug-02 11:30
Sonny Bob-Manuel6-Aug-02 11:30 
Generalyou both wrong. Pin
Jinhyuck Jung4-Sep-02 4:27
Jinhyuck Jung4-Sep-02 4:27 
GeneralRe: you both wrong. Pin
Anonymous10-Sep-02 23:32
Anonymous10-Sep-02 23:32 
GeneralRe: Another way Pin
Anonymous10-Sep-02 23:31
Anonymous10-Sep-02 23:31 
GeneralRe: Another way Pin
Jim Xochellis18-Aug-03 2:14
Jim Xochellis18-Aug-03 2:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.