2011-05-05 5 views
3

내 C++ 프로그램 내에 웹 페이지를 임베드하고 있습니다. 내가 실행중인 문제는 포함 된 페이지의 javascript 내에서 onkeypress를 캡처 할 수 있지만 onkeydown 및 onkeyup은 실행되지 않는다는 것입니다.임베디드 웹 컨트롤 (IWebBrowser2), 자바 스크립트의 onkeydown 및 onkeyup이 포함되지 않음

테스트 HTML을 내장되지 않은 IE (또는 Chrome) 창에서 보면 완벽하게 작동합니다. Internet Explorer 컨트롤에 포함 된 경우에만 문제가됩니다.

IE 윈도우 (또는 Spy ++ 사용)에 WndProc를 연결하면 WM_KEYDOWN, WM_CHAR 및 WM_KEYUP 메시지가 확실히 창에 표시됩니다.

나는 가능한 예제 코드로 최소한 만들려고 - 오류 검사를 많이 제거, 청소 등

IE의 제어를 준비 할 때 저는 누락 된 일부 설정이 있습니까? 아니면 내장 된 IE를 사용할 때와 같은 방법입니까? 나는 설치가 없다면 모든 입력을 얻지 못할 것이라고 생각할 것이다.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
    <head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
    <script type="text/javascript" language="javascript"> 
      var n = 0; 
      document.onkeydown = function() 
      { 
       var output=document.getElementById("output"); 
       output.innerHTML = n++ + " onkeydown<br>" + output.innerHTML; 
       return true; 
      }; 
      document.onkeypress = function() 
      { 
       var output=document.getElementById("output"); 
       output.innerHTML = n++ + " onkeypress<br>" + output.innerHTML; 
       return true; 
      }; 
      document.onkeyup = function() 
      { 
       var output=document.getElementById("output"); 
       output.innerHTML = n++ + " onkeyup<br>" + output.innerHTML; 
       return true; 
      }; 
     </script> 
    </head> 
    <body> 
     This is some testing text. 
     <input/> 
     <br> 
     <div id="output" style="border-style:solid; border-width:1; "></div> 
    </body> 
</html> 

그리고 파일을 포함하는 C++ 코드 :

다음은 HTML 테스트 파일의 난이 다소 오래된 스레드 알고

#include <stdio.h> 
#include <Windows.h> 
#include <string> 
#include <atlbase.h> // for CComPtr<> 
#include <Exdisp.h> 
#include <comdef.h> // for variant_t 

namespace 
{ 
    const int MAIN_WINDOW_WIDTH = 800; 
    const int MAIN_WINDOW_HEIGHT = 600; 

    const int HTML_WINDOW_WIDTH = 640; 
    const int HTML_WINDOW_HEIGHT = 480; 
} 

//------------------------------------------------------------------------------ 

void FatalError(std::string _report) 
{ 
    ::MessageBox(nullptr, _report.c_str(), "Error", MB_OK); 
    ::ExitProcess(1); 
} 

//------------------------------------------------------------------------------ 

class EmbeddedBrowser : 
    public IOleClientSite, 
    public IOleInPlaceSite, 
    public IStorage 
{ 
public: 
    EmbeddedBrowser(HWND _mainWindow) 
    { 
     m_comRefCount = 0; 
     ::SetRect(&m_objectRect, -300, -300, 300, 300); 
     m_mainWindow = _mainWindow; 

     CreateBrowserObject(); 

     ::ShowWindow(GetControlWindow(), SW_SHOW); 

     variant_t flags((UINT)0); 
     m_webBrowser->Navigate(L"about:blank", 
      &flags, nullptr, nullptr, nullptr); 
    } 


    void CreateBrowserObject() 
    { 
     HRESULT hr = ::OleCreate(CLSID_WebBrowser, 
      IID_IOleObject, OLERENDER_DRAW, 0, this, this, (void**)&m_oleObject); 
     if(FAILED(hr)) 
      FatalError("OleCreate() failed"); 

     hr = m_oleObject->SetClientSite(this); 
     hr = OleSetContainedObject(m_oleObject, TRUE); 

     RECT posRect; 
     ::SetRect(&posRect, -300, -300, 300, 300); 
     hr = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, 
      NULL, this, -1, m_mainWindow, &posRect); 
     if(FAILED(hr)) 
      FatalError("DoVerb(OLEIVERB_INPLACEACTIVATE) failed"); 

     hr = m_oleObject.QueryInterface(&m_webBrowser); 
     if(FAILED(hr)) 
      FatalError("QueryInterface(IWebBrowser) failed"); 
    } 


    virtual void Navigate(std::wstring _url) 
    { 
     bstr_t url(_url.c_str()); 
     variant_t flags(0x02u); // navNoHistory; 
     HRESULT hr = m_webBrowser->Navigate(url, 
      &flags, nullptr, nullptr, nullptr); 
    } 


    RECT PixelToHiMetric(const RECT& _rc) 
    { 
     static bool s_initialized = false; 
     static int s_pixelsPerInchX, s_pixelsPerInchY; 
     if(!s_initialized) 
     { 
      HDC hdc = ::GetDC(nullptr); 
      s_pixelsPerInchX = ::GetDeviceCaps(hdc, LOGPIXELSX); 
      s_pixelsPerInchY = ::GetDeviceCaps(hdc, LOGPIXELSY); 
      ::ReleaseDC(nullptr, hdc); 
      s_initialized = true; 
     } 

     RECT rc; 
     rc.left = MulDiv(2540, _rc.left, s_pixelsPerInchX); 
     rc.top = MulDiv(2540, _rc.top, s_pixelsPerInchY); 
     rc.right = MulDiv(2540, _rc.right, s_pixelsPerInchX); 
     rc.bottom = MulDiv(2540, _rc.bottom, s_pixelsPerInchY); 
     return rc; 
    } 


    virtual void SetRect(const RECT& _rc) 
    { 
     m_objectRect = _rc; 

     { 
      RECT hiMetricRect = PixelToHiMetric(m_objectRect); 
      SIZEL sz; 
      sz.cx = hiMetricRect.right - hiMetricRect.left; 
      sz.cy = hiMetricRect.bottom - hiMetricRect.top; 
      m_oleObject->SetExtent(DVASPECT_CONTENT, &sz); 
     } 

     if(m_oleInPlaceObject != nullptr) 
     { 
      m_oleInPlaceObject->SetObjectRects(&m_objectRect, &m_objectRect); 
     } 
    } 

    // ----- IUnknown ----- 

    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void**ppvObject) override 
    { 
     if(riid == __uuidof(IUnknown)) 
     { (*ppvObject) = static_cast<IOleClientSite*>(this); } 
     else if(riid == __uuidof(IOleInPlaceSite)) 
     { (*ppvObject) = static_cast<IOleInPlaceSite*>(this); } 
     else 
     { 
      return E_NOINTERFACE; 
     } 

     AddRef(); // implicit AddRef() 
     return S_OK; 
    } 

    virtual ULONG STDMETHODCALLTYPE AddRef(void) override 
    { 
     m_comRefCount++; 
     return m_comRefCount; 
    } 


    virtual ULONG STDMETHODCALLTYPE Release(void) override 
    { 
     m_comRefCount--; 
     return m_comRefCount; 
    } 

    // ---------- IOleWindow ---------- 

    virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE GetWindow( 
     /* [out] */ __RPC__deref_out_opt HWND *phwnd) override 
    { 
     (*phwnd) = m_mainWindow; 
     return S_OK; 
    } 

    virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp( 
     /* [in] */ BOOL fEnterMode) override 
    { 
     return E_NOTIMPL; 
    } 

    // ---------- IOleInPlaceSite ---------- 

    virtual HRESULT STDMETHODCALLTYPE CanInPlaceActivate(void) override 
    { 
     return S_OK; 
    } 

    virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivate(void) override 
    { 
     OleLockRunning(m_oleObject, TRUE, FALSE); 
     m_oleObject.QueryInterface(&m_oleInPlaceObject); 
     m_oleInPlaceObject->SetObjectRects(&m_objectRect, &m_objectRect); 

     return S_OK; 
    } 

    virtual HRESULT STDMETHODCALLTYPE OnUIActivate(void) override 
    { 
     return S_OK; 
    } 

    virtual HRESULT STDMETHODCALLTYPE GetWindowContext( 
     /* [out] */ __RPC__deref_out_opt IOleInPlaceFrame **ppFrame, 
     /* [out] */ __RPC__deref_out_opt IOleInPlaceUIWindow **ppDoc, 
     /* [out] */ __RPC__out LPRECT lprcPosRect, 
     /* [out] */ __RPC__out LPRECT lprcClipRect, 
     /* [out][in] */ __RPC__inout LPOLEINPLACEFRAMEINFO lpFrameInfo) override 
    { 
     HWND hwnd = m_mainWindow; 

     (*ppFrame) = NULL; 
     (*ppDoc) = NULL; 
     (*lprcPosRect).left = m_objectRect.left; 
     (*lprcPosRect).top = m_objectRect.top; 
     (*lprcPosRect).right = m_objectRect.right; 
     (*lprcPosRect).bottom = m_objectRect.bottom; 
     *lprcClipRect = *lprcPosRect; 

     lpFrameInfo->fMDIApp = false; 
     lpFrameInfo->hwndFrame = hwnd; 
     lpFrameInfo->haccel = NULL; 
     lpFrameInfo->cAccelEntries = 0; 

     return S_OK; 
    } 

    virtual HRESULT STDMETHODCALLTYPE Scroll( 
     /* [in] */ SIZE scrollExtant) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE OnUIDeactivate( 
     /* [in] */ BOOL fUndoable) override 
    { 
     return S_OK; 
    } 

    virtual HWND GetControlWindow() 
    { 
     if(m_controlWindow != nullptr) 
      return m_controlWindow; 

     if(m_oleInPlaceObject == nullptr) 
      return nullptr; 

     m_oleInPlaceObject->GetWindow(&m_controlWindow); 
     return m_controlWindow; 
    } 

    virtual HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate(void) override 
    { 
     m_controlWindow = nullptr; 
     m_oleInPlaceObject = nullptr; 

     return S_OK; 
    } 

    virtual HRESULT STDMETHODCALLTYPE DiscardUndoState(void) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE DeactivateAndUndo(void) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE OnPosRectChange( 
     /* [in] */ __RPC__in LPCRECT lprcPosRect) override 
    { 
     return E_NOTIMPL; 
    } 

    // ---------- IOleClientSite ---------- 

    virtual HRESULT STDMETHODCALLTYPE SaveObject(void) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE GetMoniker( 
     /* [in] */ DWORD dwAssign, 
     /* [in] */ DWORD dwWhichMoniker, 
     /* [out] */ __RPC__deref_out_opt IMoniker **ppmk) override 
    { 
     if((dwAssign == OLEGETMONIKER_ONLYIFTHERE) && 
      (dwWhichMoniker == OLEWHICHMK_CONTAINER)) 
      return E_FAIL; 

     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE GetContainer( 
     /* [out] */ __RPC__deref_out_opt IOleContainer **ppContainer) override 
    { 
     return E_NOINTERFACE; 
    } 

    virtual HRESULT STDMETHODCALLTYPE ShowObject(void) override 
    { 
     return S_OK; 
    } 

    virtual HRESULT STDMETHODCALLTYPE OnShowWindow( 
     /* [in] */ BOOL fShow) override 
    { 
     return S_OK; 
    } 

    virtual HRESULT STDMETHODCALLTYPE RequestNewObjectLayout(void) override 
    { 
     return E_NOTIMPL; 
    } 

    // ----- IStorage ----- 

    virtual HRESULT STDMETHODCALLTYPE CreateStream( 
     /* [string][in] */ __RPC__in_string const OLECHAR *pwcsName, 
     /* [in] */ DWORD grfMode, 
     /* [in] */ DWORD reserved1, 
     /* [in] */ DWORD reserved2, 
     /* [out] */ __RPC__deref_out_opt IStream **ppstm) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual /* [local] */ HRESULT STDMETHODCALLTYPE OpenStream( 
     /* [string][in] */ const OLECHAR *pwcsName, 
     /* [unique][in] */ void *reserved1, 
     /* [in] */ DWORD grfMode, 
     /* [in] */ DWORD reserved2, 
     /* [out] */ IStream **ppstm) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE CreateStorage( 
     /* [string][in] */ __RPC__in_string const OLECHAR *pwcsName, 
     /* [in] */ DWORD grfMode, 
     /* [in] */ DWORD reserved1, 
     /* [in] */ DWORD reserved2, 
     /* [out] */ __RPC__deref_out_opt IStorage **ppstg) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE OpenStorage( 
     /* [string][unique][in] */ __RPC__in_opt_string const OLECHAR *pwcsName, 
     /* [unique][in] */ __RPC__in_opt IStorage *pstgPriority, 
     /* [in] */ DWORD grfMode, 
     /* [unique][in] */ __RPC__deref_opt_in_opt SNB snbExclude, 
     /* [in] */ DWORD reserved, 
     /* [out] */ __RPC__deref_out_opt IStorage **ppstg) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual /* [local] */ HRESULT STDMETHODCALLTYPE CopyTo( 
     /* [in] */ DWORD ciidExclude, 
     /* [size_is][unique][in] */ const IID *rgiidExclude, 
     /* [annotation][unique][in] */ 
     __RPC__in_opt SNB snbExclude, 
     /* [unique][in] */ IStorage *pstgDest) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE MoveElementTo( 
     /* [string][in] */ __RPC__in_string const OLECHAR *pwcsName, 
     /* [unique][in] */ __RPC__in_opt IStorage *pstgDest, 
     /* [string][in] */ __RPC__in_string const OLECHAR *pwcsNewName, 
     /* [in] */ DWORD grfFlags) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE Commit( 
     /* [in] */ DWORD grfCommitFlags) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE Revert(void) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual /* [local] */ HRESULT STDMETHODCALLTYPE EnumElements( 
     /* [in] */ DWORD reserved1, 
     /* [size_is][unique][in] */ void *reserved2, 
     /* [in] */ DWORD reserved3, 
     /* [out] */ IEnumSTATSTG **ppenum) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE DestroyElement( 
     /* [string][in] */ __RPC__in_string const OLECHAR *pwcsName) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE RenameElement( 
     /* [string][in] */ __RPC__in_string const OLECHAR *pwcsOldName, 
     /* [string][in] */ __RPC__in_string const OLECHAR *pwcsNewName) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE SetElementTimes( 
     /* [string][unique][in] */ __RPC__in_opt_string const OLECHAR *pwcsName, 
     /* [unique][in] */ __RPC__in_opt const FILETIME *pctime, 
     /* [unique][in] */ __RPC__in_opt const FILETIME *patime, 
     /* [unique][in] */ __RPC__in_opt const FILETIME *pmtime) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE SetClass( 
     /* [in] */ __RPC__in REFCLSID clsid) override 
    { 
     return S_OK; 
     //return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE SetStateBits( 
     /* [in] */ DWORD grfStateBits, 
     /* [in] */ DWORD grfMask) override 
    { 
     return E_NOTIMPL; 
    } 

    virtual HRESULT STDMETHODCALLTYPE Stat( 
     /* [out] */ __RPC__out STATSTG *pstatstg, 
     /* [in] */ DWORD grfStatFlag) override 
    { 
     return E_NOTIMPL; 
    } 

private: 
protected: 
    CComPtr<IOleObject> m_oleObject; 
    LONG m_comRefCount; 
    HWND m_mainWindow; 
    RECT m_objectRect; 
    CComPtr<IWebBrowser2> m_webBrowser; 
    CComPtr<IOleInPlaceObject> m_oleInPlaceObject; 
    HWND m_controlWindow; 
}; 

//------------------------------------------------------------------------------ 

void EventLoop(HWND _mainWindow) 
{ 
    while(IsWindow(_mainWindow)) 
    { 
     MSG msg; 
     if(GetMessage(&msg, nullptr, 0, 0) <= 0) 
      break; 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
} 


int main(int argc, char* argv[]) 
{ 
    OleInitialize(nullptr); 

    WNDCLASS wc; 
    memset(&wc, 0, sizeof(wc)); 
    wc.lpszClassName = "MyWindowClass"; 
    wc.lpfnWndProc = DefWindowProc; 
    wc.hCursor = ::LoadCursor(nullptr, IDC_ARROW); 
    RegisterClass(&wc); 

    HWND mainWindow = CreateWindow("MyWindowClass", 
     "My Window", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, 
     CW_USEDEFAULT, MAIN_WINDOW_WIDTH, MAIN_WINDOW_HEIGHT, nullptr, 
     nullptr, nullptr, nullptr); 

    RECT rc; 
    rc.left = (MAIN_WINDOW_WIDTH - HTML_WINDOW_WIDTH)/2; 
    rc.top = (MAIN_WINDOW_HEIGHT - HTML_WINDOW_HEIGHT)/2; 
    rc.right = rc.left + HTML_WINDOW_WIDTH; 
    rc.bottom = rc.top + HTML_WINDOW_HEIGHT; 

    wchar_t navUrl[MAX_PATH]; 
    ::GetCurrentDirectoryW(MAX_PATH, navUrl); 
    wcscat_s(navUrl, L"\\test.html"); 

    EmbeddedBrowser* browser = new EmbeddedBrowser(mainWindow); 
    browser->SetRect(rc); 
    browser->Navigate(navUrl); 

    EventLoop(mainWindow); 

    ExitProcess(0); 

    return 0; 
} 
+0

IWebBrowser는 복합 창입니다. Spy ++에서 본 메시지 중 어느 창입니까? 그리고 브라우저 창에서 명시 적으로 포커스를 활성화/설정해야한다고 생각합니다. –

+0

초점 창을 명시 적으로 설정하지 않고 놀았습니다. 또한 키 누르기 이벤트가 발생하기 때문에 초점 문제가 될 것 같지 않습니다. – Aaron

답변

1

을하지만, 나는 정확히 같은 문제가 있었다.

내 경우에는 Dialog 클래스에서 PreTranslateMessage()를 덮어 썼다가 CDialog :: PretranslateMessage()를 호출하는 대신 CWnd :: PretranslateMessage()를 호출했습니다.

관련 문제