Как показать собственное контекстное меню в Internet Explorer

Я пишу надстройку для Internet Explorer 9, и мне нужно изменить контекстное меню по умолчанию на свое. Я пишу BHO на C ++ и использую ATL. Мне удалось обработать событие отображения контекстного меню (HTMLDocumentEvents2 :: oncontextmenu), но я не могу отобразить свой собственный. Вот код, запускаемый при нажатии правой кнопки мыши:

VARIANT_BOOL STDMETHODCALLTYPE CSpellCheckerBHO::OnContextMenu( IHTMLEventObj *pEvtObj)
{
    HMENU contextMenu = CreatePopupMenu();

    MENUITEMINFO item_info = { 0 };
    item_info.cbSize = sizeof(MENUITEMINFO);
    item_info.fMask = MIIM_TYPE | MIIM_ID;
    item_info.fType = MFT_STRING;
    item_info.wID = 0;
    item_info.dwTypeData = L"TEST";
    item_info.cch = 4;

    BOOL result = InsertMenuItem(contextMenu, 0, FALSE, &item_info);
    HWND browserHandle = 0;
    HRESULT hr = _webBrowser->get_HWND((LONG_PTR*)&browserHandle);

    result = TrackPopupMenuEx(contextMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, 0,0, browserHandle , NULL);

    return VARIANT_FALSE;
}

_webBrowser - это указатель на объект IWebBrowser2, я получил его из функции SetSite.

Стандартное контекстное меню не отображается (из-за возврата VARIANT_FALSE), но TrackPopupMenuEx ничего не делает и возвращает 0.

Вы знаете, что я делаю не так? Мне нужно простое меню с некоторыми текстовыми элементами.


person Mariusz Pawelski    schedule 30.03.2011    source источник


Ответы (1)


Я понял это. Игорь Тандетник помог мне в IE форум надстройки. HWND был получен из другого процесса, и TrackPopupMenuEx ожидает, что HWND принадлежит вызывающему потоку. Вот код, который работает:

VARIANT_BOOL STDMETHODCALLTYPE CSpellCheckerBHO::OnContextMenu( IHTMLEventObj *pEvtObj)
{
    HMENU contextMenu = CreatePopupMenu();

    MENUITEMINFO item_info = { 0 };
    item_info.cbSize = sizeof(MENUITEMINFO);
    item_info.fMask = MIIM_ID | MIIM_STRING;
    item_info.wID = 0;
    item_info.dwTypeData = L"TEST";
    item_info.cch = 4;

    BOOL result = InsertMenuItem(contextMenu, 0, TRUE, &item_info);

    CComPtr<IDispatch> dispDoc;
    _webBrowser->get_Document(&dispDoc);
    CComQIPtr<IOleWindow> oleWindow = dispDoc;
    HWND browserHandle;
    oleWindow->GetWindow(&browserHandle);


    CComQIPtr<IHTMLEventObj2> htmlEventObj = pEvtObj;
    long x, y;
    htmlEventObj->get_screenX(&x);
    htmlEventObj->get_screenY(&y);  

    result = TrackPopupMenuEx(contextMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, browserHandle , NULL);

    return VARIANT_FALSE;
}
person Mariusz Pawelski    schedule 04.04.2011