Another way.
Code: Select all
Structure _IDocHostUIHandler
  *vTable
  ref.i
  iDocHostUiHandler.iDocHostUiHandler
EndStructure
;/////////////////////////////////////////////////////////////////////////////////
;Return a HRESULT value (#S_OK if successful).
Procedure.i SetCustomDocHostUIHandler(id, vTableAddress)
  Protected result=#E_FAIL, hWnd, iBrowser.IWebBrowser2, iDispatch.IDispatch, iDocument.IHTMLDocument2, iOLE.IOleObject, iDocHostUIHandler.IDocHostUIHandler
  Protected iCustomDoc.ICustomDoc, iOLEClientSite.IOleClientSite, *this._IDocHostUIHandler
  hWnd = GadgetID(id)
  If hWnd
    iBrowser = GetWindowLong_(hWnd, #GWL_USERDATA)
    If iBrowser
      If iBrowser\get_Document(@iDispatch) = #S_OK
        If iDispatch\QueryInterface(?IID_IHTMLDocument2, @iDocument) = #S_OK
          If iDocument\QueryInterface(?IID_IOleObject, @iOLE) = #S_OK
            If iOLE\GetClientSite(@iOLEClientSite) = #S_OK
              If iOLEClientSite\QueryInterface(?IID_IDocHostUIHandler, @iDocHostUIHandler) = #S_OK
                If iDocument\QueryInterface(?IID_ICustomDoc, @iCustomDoc) = #S_OK
                  *this = AllocateMemory(SizeOf(_IDocHostUIHandler))
                  If *this
                    *this\vTable = vTableAddress
                    *this\iDocHostUiHandler = iDocHostUIHandler
                    iCustomDoc\SetUIHandler(*this)
                    result = #S_OK
                  Else
                    iDocHostUIHandler\Release() 
                  EndIf            
                  iCustomDoc\Release()
                Else
                  iDocHostUIHandler\Release()
                EndIf
              EndIf
              IOleClientSite\Release()
            EndIf
            iOLE\Release()
          EndIf
          iDocument\Release()
        EndIf
        iDispatch\Release()
      EndIf
    EndIf
  EndIf
  ProcedureReturn result
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////
;-TEST CODE.
;/////////////////////////////////////////////////////////////////////////////////
If OpenWindow(0, 0, 0, 600, 300, "WebGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  WebGadget(0, 10, 10, 580, 280, "http://www.purebasic.com")
  
  SetCustomDocHostUIHandler(0, ?IDocHostUIHandlerFunctionTable)
  
  Repeat 
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_CloseWindow
        Break
    EndSelect
  ForEver
EndIf
End
;/////////////////////////////////////////////////////////////////////////////////
;-CUSTOM iDocHostUIHandler IMPLEMENTATION.
;/////////////////////////////////////////////////////////////////////////////////
;iUnknown.
Procedure.i IDocHostUIHandler_QueryInterface(*this._IDocHostUIHandler, riid, *ppObj.INTEGER)
  Protected hResult = #E_NOINTERFACE, iunk.iUnknown
  If *ppObj And riid 
    *ppObj\i = 0
    If CompareMemory(riid, ?IID_IUnknown, SizeOf(IID)) Or CompareMemory(riid, ?IID_IDocHostUIHandler, SizeOf(IID))
      *ppObj\i = *this
      *this\ref+1
      hResult = #S_OK
    EndIf 
  EndIf
  ProcedureReturn hResult
EndProcedure
;iUnknown.
Procedure.i IDocHostUIHandler_AddRef(*this._IDocHostUIHandler)
  *this\ref = *this\ref + 1
  ProcedureReturn *this\ref
EndProcedure
;iUnknown.
Procedure.i IDocHostUIHandler_Release(*this._IDocHostUIHandler)
  Protected refCount
  *this\ref = *this\ref - 1
  refCount = *this\ref
  If *this\ref = 0
    *this\iDocHostUiHandler\Release()
    FreeMemory(*this) 
  EndIf
  ProcedureReturn refCount
EndProcedure
Procedure.i IDocHostUIHandler_ShowContextMenu(*this._IDocHostUIHandler, dwID, ppt, pcmdTarget, pdispReserved)
  ProcedureReturn *this\iDocHostUiHandler\ShowContextMenu(dwID, ppt, pcmdTarget, pdispReserved)
EndProcedure
Procedure.i IDocHostUIHandler_GetHostInfo(*this._IDocHostUIHandler, *pInfo)
  ProcedureReturn *this\iDocHostUiHandler\GetHostInfo(*pInfo)
EndProcedure
Procedure.i IDocHostUIHandler_ShowUI(*this._IDocHostUIHandler, dwID, pActiveObject, pCommandTarget, pFrame, pDoc)
  ProcedureReturn *this\iDocHostUiHandler\ShowUI(dwID, pActiveObject, pCommandTarget, pFrame, pDoc)
EndProcedure
Procedure.i IDocHostUIHandler_HideUI(*this._IDocHostUIHandler)
  ProcedureReturn *this\iDocHostUiHandler\HideUI()
EndProcedure
Procedure.i IDocHostUIHandler_UpdateUI(*this._IDocHostUIHandler)
  ProcedureReturn *this\iDocHostUiHandler\UpdateUI()
EndProcedure
Procedure.i IDocHostUIHandler_EnableModeless(*this._IDocHostUIHandler, fEnable)
  ProcedureReturn *this\iDocHostUiHandler\EnableModeless(fEnable)
EndProcedure
Procedure.i IDocHostUIHandler_OnDocWindowActivate(*this._IDocHostUIHandler, fActivate)
  ProcedureReturn *this\iDocHostUiHandler\OnDocWindowActivate(fActivate)
EndProcedure
Procedure.i IDocHostUIHandler_OnFrameWindowActivate(*this._IDocHostUIHandler, fActivate)
  ProcedureReturn *this\iDocHostUiHandler\OnFrameWindowActivate(fActivate)
EndProcedure
Procedure.i IDocHostUIHandler_ResizeBorder(*this._IDocHostUIHandler, prcBorder, pUIWindow, fFrameWindow)
  ProcedureReturn *this\iDocHostUiHandler\ResizeBorder(prcBorder, pUIWindow, fFrameWindow)
EndProcedure
Procedure.i IDocHostUIHandler_TranslateAccelerator(*this._IDocHostUIHandler, *lpMsg.MSG, pguidCmdGroup, nCmdID)
  
  If *lpMsg And *lpMsg\message = #WM_KEYDOWN
    
;     If GetKeyState_(#VK_CONTROL) & $8000   ;block all Control key combinations except for Ctrl+C
;       Select  *lpMsg\wParam
;         Case #VK_C
;           
;         Default
;           ProcedureReturn #S_OK
;       EndSelect
;       
;     EndIf
    
    If GetKeyState_(#VK_CONTROL) & $8000
      Select  *lpMsg\wParam
        Case #VK_N
          Debug "Ctrl + N"
          ProcedureReturn #S_OK
          
        Case #VK_O
          Debug "Ctrl + O"
          ProcedureReturn #S_OK
          
      EndSelect
      
    EndIf
  EndIf
  
  ProcedureReturn *this\iDocHostUiHandler\TranslateAccelerator(*lpMsg, pguidCmdGroup, nCmdID)
EndProcedure
Procedure.i IDocHostUIHandler_GetOptionKeyPath(*this._IDocHostUIHandler, pchKey, DW)
  ProcedureReturn *this\iDocHostUiHandler\GetOptionKeyPath(pchKey, DW)
EndProcedure
Procedure.i IDocHostUIHandler_GetDropTarget(*this._IDocHostUIHandler, pDropTarget, ppDropTarget)
  ProcedureReturn *this\iDocHostUiHandler\GetDropTarget(pDropTarget, ppDropTarget)
EndProcedure
Procedure.i IDocHostUIHandler_GetExternal(*this._IDocHostUIHandler, ppDispatch.i)
   ProcedureReturn *this\iDocHostUiHandler\GetExternal(ppDispatch.i)
EndProcedure
Procedure.i IDocHostUIHandler_TranslateUrl(*this._IDocHostUIHandler, dwTranslate, pchURLIn, ppchURLOut)
  ProcedureReturn *this\iDocHostUiHandler\TranslateUrl(dwTranslate, pchURLIn, ppchURLOut)
EndProcedure
Procedure.i IDocHostUIHandler_FilterDataObject(*this._IDocHostUIHandler, pDO, ppDORet)
   ProcedureReturn *this\iDocHostUiHandler\FilterDataObject(pDO, ppDORet)
EndProcedure
DataSection
IID_IUnknown: ; 00000000-0000-0000-C000-000000000046
  Data.l $00000000
  Data.w $0000, $0000
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46
IID_IHTMLDocument2: ; 332C4425-26CB-11D0-B483-00C04FD90119
  Data.l $332C4425
  Data.w $26CB, $11D0
  Data.b $B4, $83, $00, $C0, $4F, $D9, $01, $19
IID_IOleObject: ; 00000112-0000-0000-C000-000000000046
  Data.l $00000112
  Data.w $0000, $0000
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46
IID_IDocHostUIHandler: ; BD3F23C0-D43E-11CF-893B-00AA00BDCE1A
  Data.l $BD3F23C0
  Data.w $D43E, $11CF
  Data.b $89, $3B, $00, $AA, $00, $BD, $CE, $1A
IID_ICustomDoc: ; 3050F3F0-98B5-11CF-BB82-00AA00BDCE0B
  Data.l $3050F3F0
  Data.w $98B5, $11CF
  Data.b $BB, $82, $00, $AA, $00, $BD, $CE, $0B
IDocHostUIHandlerFunctionTable:
  Data.i @IDocHostUIHandler_QueryInterface()
  Data.i @IDocHostUIHandler_AddRef()
  Data.i @IDocHostUIHandler_Release()
  Data.i @IDocHostUIHandler_ShowContextMenu()
  Data.i @IDocHostUIHandler_GetHostInfo()
  Data.i @IDocHostUIHandler_ShowUI()
  Data.i @IDocHostUIHandler_HideUI()
  Data.i @IDocHostUIHandler_UpdateUI()
  Data.i @IDocHostUIHandler_EnableModeless()
  Data.i @IDocHostUIHandler_OnDocWindowActivate()
  Data.i @IDocHostUIHandler_OnFrameWindowActivate()
  Data.i @IDocHostUIHandler_ResizeBorder()
  Data.i @IDocHostUIHandler_TranslateAccelerator()
  Data.i @IDocHostUIHandler_GetOptionKeyPath()
  Data.i @IDocHostUIHandler_GetDropTarget()
  Data.i @IDocHostUIHandler_GetExternal()
  Data.i @IDocHostUIHandler_TranslateUrl()
  Data.i @IDocHostUIHandler_FilterDataObject()
EndDataSection
;/////////////////////////////////////////////////////////////////////////////////