Как изменить контекстное меню Internet Explorer, используя IDocHostUIHandler :: ShowContextMenu? - PullRequest
1 голос
/ 16 ноября 2010

Я пытаюсь реализовать пользовательское меню для Internet Explorer 7.0.Для этого я должен использовать только IDocHostUIHandler::ShowContextMenu.До сих пор я могу реализовать основное контекстное меню с двумя вариантами.Проблема в том, что они отключены по умолчанию.Пример кода для того же:

HRESULT CWebEventHandler::ShowContextMenu(DWORD dwID,POINT *ppt, IUnknown *pcmdTarget, IDispatch *pdispObject) 
{
    if (false) // I will put some guard code here. as of now do not consider it
        return S_FALSE;      // Show standard context menus.
    else
    {
        IOleWindow* pWnd = NULL;
        HRESULT hr = pcmdTarget->QueryInterface(IID_IOleWindow,
            (void**) &pWnd);

        if (SUCCEEDED(hr))
        {
            HWND hwnd;

            if (SUCCEEDED(pWnd->GetWindow(&hwnd)))
            {
                HMENU menu = ::CreatePopupMenu();
                ::AppendMenu(menu, MF_STRING, ID_HELLO, L"&Hello" ); // ID_HELLO & ID_WORLD are two menu resource items
                ::AppendMenu(menu, MF_STRING, ID_WORLD, L"&World" );

                long myRetVal = ::TrackPopupMenu(menu, 
                    TPM_RIGHTBUTTON | TPM_LEFTALIGN | TPM_RETURNCMD, 
                    ppt->x, ppt->y, NULL, hwnd, NULL);

                // Send the command to the browser.
                //
                LRESULT myResult = ::SendMessage(hwnd, WM_COMMAND,
                    myRetVal, NULL);
            }

            pWnd->Release();
        }
    }
    return S_OK; 
}

Пожалуйста, подскажите, что не так с этим кодом и почему мои пункты меню отключены ??РЕДАКТИРОВАТЬ

Этот же пост доступен и по этой ссылке (http://social.msdn.microsoft.com/Forums/en/ieextensiondevelopment/thread/13584f76-21bd-4764-b5b7-e81932561574)

Ответы [ 2 ]

0 голосов
/ 07 февраля 2013

Я уверен, что вы уже поняли это, но во втором примере вы делаете: :: SendMessage (hwnd, WM_COMMAND, myRetVal, NULL);

после возврата: SetWindowLong (hwnd, GWL_WNDPROC, (LONG) g_lpPrevWndProc);

Ваш обратный вызов никогда не будет выполнен при возврате 0; путь, хотя и не было такого случая в этом конкретном примере.

0 голосов
/ 16 ноября 2010

Я думаю, что решил проблему. После получения объекта hwnd в if (SUCCEEDED(pWnd->GetWindow(&hwnd))) установите свой собственный CALLBACK для контекстного меню. В обратном вызове

if ((uMsg == WM_INITMENUPOPUP) && (wParam == (WPARAM) menu)) {
        return 0;       
    }

в противном случае позвольте исходному обработчику обработать его.

однажды с

long myRetVal = ::TrackPopupMenu(g_hPubMenu,TPM_RIGHTBUTTON | TPM_LEFTALIGN | TPM_RETURNCMD, 
                    ppt->x, ppt->y, NULL, hwnd, NULL);

вернуться к исходному обработчику процедур ....

Sample

WNDPROC g_lpPrevWndProc = NULL;

HRESULT CWebEventHandler::ShowContextMenu(DWORD dwID, POINT *ppt, IUnknown *pcmdTarget, IDispatch *pdispObject) 
    {


if (false)
        return S_FALSE;      // Show standard context menus.
    else
    {
        IOleWindow* pWnd = NULL;
        HRESULT hr = pcmdTarget->QueryInterface(IID_IOleWindow,
            (void**) &pWnd);

        if (SUCCEEDED(hr))
        {
            HWND hwnd;

            if (SUCCEEDED(pWnd->GetWindow(&hwnd)))
            {
                g_lpPrevWndProc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LONG)CtxMenuWndProc);

                if (g_hPubMenu)
                {
                    DestroyMenu(g_hPubMenu);
                    g_hPubMenu = NULL;
                }
                g_hPubMenu = ::CreatePopupMenu();

                ::AppendMenu(g_hPubMenu, MF_STRING|MF_ENABLED   , ID_HELLO, L"&Hello" );
                ::AppendMenu(g_hPubMenu, MF_STRING|MF_ENABLED   , ID_WORLD, L"&World" );

                long myRetVal = ::TrackPopupMenu(g_hPubMenu, 
                    TPM_RIGHTBUTTON | TPM_LEFTALIGN | TPM_RETURNCMD, 
                    ppt->x, ppt->y, NULL, hwnd, NULL);

                SetWindowLong(hwnd, GWL_WNDPROC, (LONG)g_lpPrevWndProc);

                // Send the command to the browser.
                //

                if (myRetVal == ID_HELLO)
                {
                    box(_T("Hello"));
                }else if(myRetVal == ID_WORLD)
                {
                    box(_T("World"));
                }else{
                        LRESULT myResult = ::SendMessage(hwnd, WM_COMMAND,myRetVal, NULL);
                }

            }

            pWnd->Release();
        }
    }
    return S_OK; 
}


LRESULT CALLBACK CtxMenuWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if ((uMsg == WM_INITMENUPOPUP) && (wParam == (WPARAM) g_hPubMenu)) {
        return 0;       
    }
    return CallWindowProc(g_lpPrevWndProc, hwnd, uMsg, wParam, lParam);
}
...