2016-10-10 11 views
1

JavaScript에 내장 된 IE11 컨트롤에 외부 개체를 제공하기 위해 IDocHostUIHandler 구현을 작성했습니다. 하나의 클래스는 IUnknown, IDispatch 및 IDocHostUIHandler의 구현을 제공합니다. IDispatch 인터페이스는 외부 개체로 GetExternal에 반환됩니다. 원래 처리기로 GetExternal 호출을 제외한 IDocHostUIHandler에 대한 모든 호출. HideUI 같이 구현 예HideUI를 호출 한 후 mshtml이 FAST_FAIL_INCORRECT_STACK과 함께 실패합니다.

:

동일한 패턴이다 GetExternal 제외한 다른 모든 방법에 사용되는
HRESULT STDMETHODCALLTYPE mtQtWebBrowserDocHandler::HideUI(void) 
{ 
    qDebug("Calling HideUI"); 
    if(m_defaultDocHostUIHandler) 
    { 
     HRESULT hr = m_defaultDocHostUIHandler->HideUI(); 
     qDebug("Called HideUI"); 
     return hr; 
    } 
    return E_NOTIMPL; 
} 

: 자바 스크립트

HRESULT STDMETHODCALLTYPE mtQtWebBrowserDocHandler::GetExternal(IDispatch **ppDispatch) 
{ 
    qDebug("Calling GetExternal"); 
    *ppDispatch = (IDispatch*)this; 
    return S_OK; 
} 

난 다음 실행 :

var r1 = window.external.Test1(); 

이렇게하면 다음과 같은 디버그 출력이 출력됩니다.

'2016-10-10 11:09:19' DEBUG Calling GetHostInfo 
'2016-10-10 11:09:19' DEBUG Called GetHostInfo 
'2016-10-10 11:09:19' DEBUG mtQtWebBrowserDocHandler Release (ref now = 2) 
'2016-10-10 11:09:19' DEBUG mtQtWebBrowserDocHandler AddRef (ref now = 3) 
'2016-10-10 11:09:19' DEBUG Calling GetHostInfo 
'2016-10-10 11:09:19' DEBUG Called GetHostInfo 
'2016-10-10 11:09:19' DEBUG mtQtWebBrowserDocHandler Release (ref now = 2) 
'2016-10-10 11:09:19' DEBUG Calling GetExternal 
'2016-10-10 11:09:21' DEBUG mtQtWebBrowserDocHandler - IDispatch requested 
'2016-10-10 11:09:21' DEBUG mtQtWebBrowserDocHandler AddRef (ref now = 3) 
'2016-10-10 11:09:21' DEBUG mtQtWebBrowserDocHandler Release (ref now = 2) 
'2016-10-10 11:09:21' DEBUG Calling ShowUI 
'2016-10-10 11:09:21' DEBUG Called ShowUI 
'2016-10-10 11:09:21' DEBUG Calling HideUI 
'2016-10-10 11:09:21' DEBUG Called HideUI 

마지막으로 HideUI에서 복귀하면 ecx = FAST_FAIL_INCORRECT_STACK으로 INT 29h 오류가 발생합니다. 예상되는 스택은 0x18D9C4이고 실제 스택은 0x18D9A4이며 0x20의 불일치입니다.

나는 완전히 신비화되었습니다. 내 인터페이스에 대한 다른 호출은 올바르게 작동하며 HideUI 구현에서 E_NOTIMPL을 반환하면 아무런 차이가 없습니다. 아마도 스택의 불균형이 될 수 있습니까?

답변

0

대답은 mshtml이 WebBrowser 컨트롤에 의해 호스팅 될 때 브라우저 문서에서 ICustomDoc을 사용하고있는 것으로 보입니다. 이것은 분명히 좋은 생각이 아닙니다! 대신 WebBrowser 컨트롤에서 제공하는 기존 사이트를 사용해야합니다. 여기에 IDocHostUI를 구현하는 올바른 방법의 예가 있습니다. https://github.com/FastSpring/FsprgEmbeddedStoreWinMFC 매우 유용했습니다.

+0

이것을 허용 된 대답으로 표시해야합니다. –

2

함수에서 나중에 참조 횟수가 일치하지 않게되는 참조 계수를 증가시키지 않고 인터페이스 포인터를 반환합니다. 더 나은 구현은 다음과 같습니다 :

HRESULT STDMETHODCALLTYPE mtQtWebBrowserDocHandler::GetExternal(IDispatch **ppDispatch) 
{ 
    qDebug("Calling GetExternal"); 
    *ppDispatch = (IDispatch*)this; 
    this->AddRef(); 
    return S_OK; 
} 

또는 여기에 QueryInterface을 사용하십시오. 이것이 ATL 인 경우 InternalQueryInterface. 나는 이것이 AddRef 호출보다 더 많은 Release 호출로 인해 아마도 파괴 된 객체에 대한 참조를 가지고 있기 때문에 이것이 여러분의 오류의 원인이라고 생각합니다.

+0

저는 COM 전문가가 아니지만 이것이 사실이 아니라고 확신합니다. 참조는 GetExternal()을 호출 한 mshtml.dll에서 가져온 후 AddRef가 될 수 있도록 소유하고 있으므로 참조가 완료되면 Release가됩니다. –

+2

예, COM 전문가가 아닌 것에 대해서는 맞습니다. COM에서 포인터를 얻을 때마다 호출자가 Release()를 호출 할 때 모든 것이 균형을 유지하도록 Addleef() 인터페이스를 호출해야합니다. –

+0

Microsoft는 귀하에게 동의하지 않는 것으로 보입니다. https://msdn.microsoft.com/en-us/library/aa770041(v=vs.85).aspx –