2010-11-16 62 views
1

我正在嘗試爲Internet Explorer 7.0實現自定義菜單。爲此,我只能使用IDocHostUIHandler::ShowContextMenu。直到現在我能夠實現一個基本的上下文菜單有兩個選項。問題是它們默認是禁用的。對於相同的示例代碼:如何使用IDocHostUIHandler :: ShowContextMenu修改Internet Explorer的上下文菜單?

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

回答

0

我想我已經解決了這個問題。在if (SUCCEEDED(pWnd->GetWindow(&hwnd)))中獲得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); 

恢復到原來的PROC處理程序中完成....

樣品

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); 
} 
0

我敢肯定你已經想通了這一點,但在第二個示例中,您正在執行: :: SendMessage(hwnd,WM_COMMAND,myRetVal,NULL);

恢復後: SetWindowLong(hwnd,GWL_WNDPROC,(LONG)g_lpPrevWndProc);

您的回調將永遠不會在返回0上執行;儘管如此,在這個特定樣本中也沒有這種情況。

相關問題