IDocHostUIHandler::ShowContextMenu添加自定义菜单的另类实现

转载 2012年03月24日 15:19:38

在很久很久以前(其实也就是IE6时代 - -),要实现在IWebBrowser2弹出原始的IE右键菜单,传统的思路是在ShowContextMenu加载SHDOCLC.DLL,读取菜单资源IDR_BROWSE_CONTEXT_MENU来获取菜单句柄,然后InsertMenu插入自己的菜单项 - -。在IE6.0以后的内核版本是没有提供SHDOCLC.DLL来让你加载的。

 

这里有两种另类的实现方式:

第一种是使用SetWindowLong,接管WndProc,一切尽在接管之中。

第二种是在自己的程序中添加相应的菜单ITEM,弹出菜单后,接管一些ITEM点击事件。

第二种方法的详细实现:

 

STDMETHODIMP CMyDocHostUIHandler::ShowContextMenu(DWORD dwID, POINT* ppt, IUnknown* pcmdtReserved, IDispatch* pdispReserved)
{
// 添加扩展菜单
#define SHDVID_ADDMENUEXTENSIONS        53
// 获取编码菜单
#define SHDVID_GETMIMECSETMENU          27

    CMenu menu;
    menu.LoadMenu( IDR_IE_DEFAULT_POPUP );     // 自己山寨的IE菜单

    // 获取菜单子项位置
    int nSubMenuPos = -1;

    switch ( dwID )
    {
        // 默认
    case CONTEXT_MENU_DEFAULT:
        nSubMenuPos = 0;
        break;

        // 图像
    case CONTEXT_MENU_IMAGE:
        nSubMenuPos = 1;
        break;

        // 锚
    case CONTEXT_MENU_ANCHOR:
        nSubMenuPos = 2;
        break;

        // DYNSRC 图像
    case CONTEXT_MENU_IMGDYNSRC:
        nSubMenuPos = 3;
        break;

        // ART 图像
    case CONTEXT_MENU_IMGART:
        nSubMenuPos = 4;
        break;

    default:
        break;
    }

    if ( nSubMenuPos == -1 )
        return S_FALSE;
    // 获取子菜单位置
    CMenuHandle menuHandle = menu.GetSubMenu( nSubMenuPos );
    if ( menuHandle.IsNull() )
        return S_FALSE;

    // 弹出菜单
    HRESULT hr;
    HWND hwnd;
    CComPtr<IOleCommandTarget> spCT;
    CComPtr<IOleWindow> spWnd;

    hr = pcmdtReserved->QueryInterface(IID_IOleCommandTarget, (void**)&spCT);
    if ( FAILED(hr) )
        return S_FALSE;

    hr = pcmdtReserved->QueryInterface(IID_IOleWindow, (void**)&spWnd);
    if ( FAILED(hr) )
        return S_FALSE;

    hr = spWnd->GetWindow(&hwnd);
    if ( FAILED(hr) )
        return S_FALSE;

    // 添加编码
    CComVariant var;
    hr = spCT->Exec(&CGID_ShellDocView, SHDVID_GETMIMECSETMENU, 0, NULL, &var);
    if ( SUCCEEDED(hr) )
    {
        MENUITEMINFO mii = {0};
        mii.cbSize = sizeof(mii);
        mii.fMask = MIIM_SUBMENU;
        mii.hSubMenu = (HMENU) var.byref;

        // 添加语言栏
        menuHandle.SetMenuItemInfo(IDM_LANGUAGE, FALSE, &mii);
    }

    // 从注册表中加载扩展菜单(MenuExt)
    CComVariant var1;
    V_VT(&var1) = VT_INT_PTR;
    V_BYREF(&var1) = (HMENU)menuHandle;

    CComVariant var2;
    V_VT(&var2) = VT_I4;
    V_I4(&var2) = dwID;

    hr = spCT->Exec(&CGID_ShellDocView, SHDVID_ADDMENUEXTENSIONS, 0, &var1, &var2);
    if ( FAILED(hr) )
    {
        // 删除扩展菜单项
        menuHandle.DeleteMenu(IDM_MENUEXT_PLACEHOLDER, MF_BYCOMMAND);
    }

    // 弹出菜单
    int iSelection = menuHandle.TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
        ppt->x, ppt->y, hwnd );
    /************************************************************/
    // iSelection==菜单ITEM ID,对指定的ID项进行特殊处理。咔咔,你懂的。
    /************************************************************/
    // 对菜单进行默认处理
    ::SendMessage(hwnd, WM_COMMAND, iSelection, NULL);

    return S_OK;
}
 

附上山寨的IE右键菜单(用PE Explorer取到的ITEM)

IDR_IE_DEFAULT_POPUP MENU 
BEGIN
    POPUP "默认"
    BEGIN
        MENUITEM "后退(&B)",                      2282
        MENUITEM "前进(&O)",                      2283
        MENUITEM SEPARATOR
        MENUITEM "背景另存为(&S)...",                2263
        MENUITEM "设置为背景(&G)",                   2264
        MENUITEM "复制背景(&C)",                    2265
        MENUITEM "设为桌面项(&D)...",                2278
        MENUITEM SEPARATOR
        MENUITEM "全选(&A)",                      31
        MENUITEM "粘贴(&P)",                      26
        MENUITEM SEPARATOR
        MENUITEM "创建快捷方式(&T)",                  2266
        MENUITEM "添加到收藏夹(&F)...",               2261
        MENUITEM "查看源文件(&V)",                   2139
        MENUITEM SEPARATOR
        MENUITEM "编码(&E)",                      2292
        MENUITEM SEPARATOR
        MENUITEM "打印(&I)",                      27
        MENUITEM "刷新(&R)",                      6042
        MENUITEM ""                      6047
        MENUITEM SEPARATOR
        MENUITEM "属性(&P)",                      28
    END
    POPUP "图像"
    BEGIN
        MENUITEM "打开链接(&O)",                    2136
        MENUITEM "在新窗口中打开链接(&N)",               2137
        MENUITEM "目标另存为(&A)...",                2268
        MENUITEM "打印目标(&P)",                    2273
        MENUITEM SEPARATOR
        MENUITEM "显示图片(&H)",                    2269
        MENUITEM "图片另存为(&S)...",                2270
        MENUITEM "电子邮件图片(&E)...",               2288
        MENUITEM "打印图片(&I)...",                 2289
        MENUITEM "转到图片收藏(&G)",                  2287
        MENUITEM "设置为背景(&G)",                   2264
        MENUITEM "设为桌面项(&D)...",                2278
        MENUITEM SEPARATOR
        MENUITEM "剪切(&T)",                      16
        MENUITEM "复制(&C)",                      15
        MENUITEM "复制快捷方式(&T)",                  2262
        MENUITEM "粘贴(&P)",                      26
        MENUITEM SEPARATOR
        MENUITEM "添加到收藏夹(&F)...",               2261
        MENUITEM ""                      6047
        MENUITEM SEPARATOR
        MENUITEM "属性(&P)",                      28
    END
    POPUP "锚"
    BEGIN
        MENUITEM "打开(&O)",                      2136
        MENUITEM "在新窗口中打开(&N)",                 2137
        MENUITEM "目标另存为(&A)...",                2268
        MENUITEM "打印目标(&P)",                    2273
        MENUITEM SEPARATOR
        MENUITEM "剪切(&T)",                      16
        MENUITEM "复制(&C)",                      15
        MENUITEM "复制快捷方式(&T)",                  2262
        MENUITEM "粘贴(&P)",                      26
        MENUITEM SEPARATOR
        MENUITEM "添加到收藏夹(&F)...",               2261
        MENUITEM ""                      6047
        MENUITEM SEPARATOR
        MENUITEM "属性(&P)",                      28
    END
    POPUP "DYNSRC 图像"
    BEGIN
        MENUITEM "打开链接(&O)",                    2136
        MENUITEM "在新窗口中打开链接(&N)",               2137
        MENUITEM "目标另存为(&A)...",                2268
        MENUITEM "打印目标(&P)",                    2273
        MENUITEM SEPARATOR
        MENUITEM "显示图片(&H)",                    2269
        MENUITEM "图片另存为(&S)...",                2270
        MENUITEM "设置为背景(&G)",                   2264
        MENUITEM "设为桌面项(&D)...",                2278
        MENUITEM SEPARATOR
        MENUITEM "剪切(&T)",                      16
        MENUITEM "复制(&C)",                      15
        MENUITEM "复制快捷方式(&T)",                  2262
        MENUITEM "粘贴(&P)",                      26
        MENUITEM SEPARATOR
        MENUITEM "添加到收藏夹(&F)...",               2261
        MENUITEM ""                      6047
        MENUITEM SEPARATOR
        MENUITEM "播放",                          2271
        MENUITEM "停止",                          2272
        MENUITEM "属性(&R)",                      28
    END
    POPUP "ART 图像"
    BEGIN
        MENUITEM "打开链接(&O)",                    2136
        MENUITEM "在新窗口中打开链接(&N)",               2137
        MENUITEM "目标另存为(&A)...",                2268
        MENUITEM "打印目标(&P)",                    2273
        MENUITEM SEPARATOR
        MENUITEM "显示图片(&H)",                    2269
        MENUITEM "图片另存为(&S)...",                2270
        MENUITEM "设置为背景(&G)",                   2264
        MENUITEM "设为桌面项(&D)...",                2278
        MENUITEM SEPARATOR
        MENUITEM "剪切(&T)",                      16
        MENUITEM "复制(&C)",                      15
        MENUITEM "复制快捷方式(&T)",                  2262
        MENUITEM "粘贴(&P)",                      26
        MENUITEM SEPARATOR
        MENUITEM "添加到收藏夹(&F)...",               2261
        MENUITEM SEPARATOR
        MENUITEM "播放",                          2274
        MENUITEM "停止",                          2275
        MENUITEM "重绕",                          2276
        MENUITEM ""                      6047
        MENUITEM SEPARATOR
        MENUITEM "属性(&P)",                      28
    END
END

相关文章推荐

手动调用ContextMenu的方法

View.showContextMenu(); //这里的View可以是Activity,也可以是具体的button等对象 //控制ContextMenu的方法是覆盖这两个函数: @Overrid...

Android AlertDialog对话框自定义风格的另类实现

在实现 Android 自定义对话框风格的时候,我们往往是通过自定义 布局来实现想要的对话框风格,这里教大家一招,自己不用写布局文件,修改系统自带的对话框布局,来达到想要的效果。

php自定义函数调用全局变量的另类方法

今天在修改网站的网银支付系统时,发现了这种方法。以前写程序时,在php自定义函数里调用全局变量一般都是在函数开头加上global声明一下全 局变量,然后才在函数里使用,但这里提到的这种方法,却不用那...

【小技巧】Select下拉列表覆盖DIV菜单的另类解决方案

最近在工作中接触到了这样一个问题:当把用于选择尺寸的下拉列表(html select标签实现)打开后,不选择,然后移动鼠标到页面头部的菜单栏,此时菜单栏接受onmouseover事件,显示一个DIV实...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)