Is it not possible to add our own menu items on the CHtmlView context menu?

前端 未结 1 743
长情又很酷
长情又很酷 2021-01-29 07:47

So I keep coming back to this article on CodeProject:

https://www.codeproject.com/Articles/4758/How-to-customize-the-context-menus-of-a-WebBrowser

I then realise

1条回答
  •  离开以前
    2021-01-29 08:28

    I have got to the bottom of this. There were a few key things that I learned along the way.

    Concept 1

    I was not away of the CHtmlView::OnShowContextMenu function which I needed to implement:

    HRESULT CChristianLifeMinistryHtmlView::OnShowContextMenu(DWORD dwID, LPPOINT ppt,
        LPUNKNOWN pcmdtReserved, LPDISPATCH pdispReserved)
    {
        return CustomContextMenu(ppt, pcmdtReserved);
    }
    

    In my defence, the IDE in Visual Studio did not offer it in the list as a possibly override. But it existed non-the-less.

    Concept 2

    The menu IDs for all custom menu items fall between IDM_MENUEXT_FIRST__ and IDM_MENUEXT_LAST__ for a maximum of 33 custom commands. In my case I manually create some #define values in my resource.h file:

    #define CUSTOM_MENU_PRINT_PREVIEW       3700
    #define CUSTOM_MENU_EXPORT              3701
    

    Note that I am not happy using literal values. I wish I could use IDM_MENU_EXT_FIRST + 1 etc. for my definitions but I do not know how to do that. Possible?

    Concept 3

    When you design your custom menu you can infill existing commands with the IDM_XXX values too:

    IDR_MENU_HTML_POPUP MENU
    BEGIN
        POPUP "CustomPopup"
        BEGIN
            MENUITEM "Select All",                  31
            MENUITEM SEPARATOR
            MENUITEM "Export",                      CUSTOM_MENU_EXPORT
            MENUITEM SEPARATOR
            MENUITEM "Page Setup",                  2004
            MENUITEM "Print Preview",               CUSTOM_MENU_PRINT_PREVIEW
            MENUITEM SEPARATOR
            MENUITEM "Refresh",                     2300
            MENUITEM SEPARATOR
            MENUITEM "View Source",                 2139
        END
    END
    

    The same note still applies though. I can't work out how to assign the IDM_* constants to my own #defines rather than using literal values.

    Your custom menu items will be greyed out if you don't use the right ID values.

    Concept 4

    Then you have to create the context menu (see original question for that code).

    Concept 5

    This is closely related to item 4. TrackMenuPopup needed to be adjusted in my situation as follows:

    // Show shortcut menu
    iSelection = ::TrackPopupMenu(hPopupMenu,
        TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
        ppt->x,
        ppt->y,
        0,
        hwnd,
        (RECT*)NULL);
    
    // Send selected shortcut menu item command to shell
    if (iSelection != 0)
    {
        if (iSelection == CUSTOM_MENU_PRINT_PREVIEW)
        {
            ::SendMessage(GetParent()->GetSafeHwnd(), WM_COMMAND, ID_FILE_PRINTPREVIEW, NULL);
        }
        else if (iSelection == CUSTOM_MENU_EXPORT)
        {
            ::SendMessage(GetParent()->GetSafeHwnd(), WM_COMMAND, ID_FILE_EXPORT, NULL);
        }
        else
        {
            (void) ::SendMessage(hwnd, WM_COMMAND, iSelection, NULL);
        }
    }
    

    The key was testing the return value of TrackMenuPopup and doing custom handling. In-fact, whilst writing this answer I now realise that my "Print Preview" menu item can be defined as the value of IDM_PRINTPREVIEW and I test again that, like this:

    if (iSelection != 0)
    {
        if (iSelection == IDM_PRINTPREVIEW)
        {
            ::SendMessage(GetParent()->GetSafeHwnd(), WM_COMMAND, ID_FILE_PRINTPREVIEW, NULL);
        }
        else if (iSelection == CUSTOM_MENU_EXPORT)
        {
            ::SendMessage(GetParent()->GetSafeHwnd(), WM_COMMAND, ID_FILE_EXPORT, NULL);
        }
        else
        {
            (void) ::SendMessage(hwnd, WM_COMMAND, iSelection, NULL);
        }
    }
    

    So my only gripe is that my own #define are values are using literal numbers and I would prefer them to be based on the IDM constants if possible. But either way, it all works fine!

    0 讨论(0)
提交回复
热议问题