Save it as WebViewWebMessageReceivedCallback.pbi
Code: Select all
;
; https://www.purebasic.fr/english/viewtopic.php?p=629641
;
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
CompilerEndIf
CompilerIf Not Defined(IID_IUnknown, #PB_Label)
DataSection
IID_IUnknown:
Data.l $00000000
Data.w $0000, $0000
Data.b $C0, $00, $00, $00, $00, $00, $00, $46
EndDataSection
CompilerEndIf
CompilerIf Not Defined(IUnknownBase_Structure, #PB_Structure)
Structure IUnknownBase_Structure
*pVtable
lRefCount.l
*pQueryInterface
*pAddRef
*pRelease
EndStructure
CompilerEndIf
Prototype.i WebViewWebMessageReceived_Prototype(Message$)
Structure ICoreWebView2WebMessageReceivedEventHandler_Structure Extends IUnknownBase_Structure
*pInvoke
Token.q
*pCallback.WebViewWebMessageReceived_Prototype
EndStructure
Global NewMap WebViewWebMessageReceivedEventHandlerMap.ICoreWebView2WebMessageReceivedEventHandler_Structure()
Procedure.l ICoreWebView2WebMessageReceivedEventHandler_QueryInterface(*this.ICoreWebView2WebMessageReceivedEventHandler_Structure, *riid.IID, *ppvObject.Integer)
Protected Result.l
Debug "WebView WebMessageReceived QueryInterface"
Result = #S_OK
If *ppvObject And *riid
If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID))
*this\lRefCount + 1
*ppvObject\i = *this
Else
*ppvObject\i = 0
Result = #E_NOINTERFACE
EndIf
Else
Result = #E_POINTER
EndIf
ProcedureReturn Result
EndProcedure
Procedure.l ICoreWebView2WebMessageReceivedEventHandler_AddRef(*this.ICoreWebView2WebMessageReceivedEventHandler_Structure)
Debug "WebView WebMessageReceived AddRef"
*this\lRefCount + 1
ProcedureReturn *this\lRefCount
EndProcedure
Procedure.l ICoreWebView2WebMessageReceivedEventHandler_Release(*this.ICoreWebView2WebMessageReceivedEventHandler_Structure)
Debug "WebView WebMessageReceived Release"
*this\lRefCount - 1
ProcedureReturn *this\lRefCount
EndProcedure
Procedure.l ICoreWebView2WebMessageReceivedEventHandler_Invoke(*this.ICoreWebView2WebMessageReceivedEventHandler_Structure, *sender.ICoreWebView2, *args.ICoreWebView2WebMessageReceivedEventArgs)
Protected *ptr, Result.i, Message$
Debug "WebView WebMessageReceived Invoke"
Result = #S_OK
*args\get_webMessageAsJson(@*ptr)
If *ptr
Message$ = PeekS(*ptr)
Result = *this\pCallback(Message$)
CoTaskMemFree_(*ptr)
EndIf
ProcedureReturn Result
EndProcedure
Procedure WebViewRemoveWebMessageReceivedCallback(WebView.i, Core.ICoreWebView2)
If FindMapElement(WebViewWebMessageReceivedEventHandlerMap(), Str(WebView))
If WebViewWebMessageReceivedEventHandlerMap()\Token
If Core
Core\remove_WebMessageReceived(WebViewWebMessageReceivedEventHandlerMap()\Token)
EndIf
EndIf
DeleteMapElement(WebViewWebMessageReceivedEventHandlerMap())
EndIf
EndProcedure
; CompilerIf Not Defined(ICoreWebView2Settings, #PB_Interface)
;
; DataSection
; IID_ICoreWebView2Settings:
; Data.l $E562E4F0
; Data.w $D7FA, $43AC
; Data.b $8D, $71, $C0, $51, $50, $49, $9F, $0
; EndDataSection
;
; Interface ICoreWebView2Settings Extends IUnknown
; get_IsScriptEnabled(IsScriptEnabled.i)
; put_IsScriptEnabled(IsScriptEnabled.l)
; get_IsWebMessageEnabled(IsWebMessageEnabled.i)
; put_IsWebMessageEnabled(IsWebMessageEnabled.l)
; get_AreDefaultScriptDialogsEnabled(AreDefaultScriptDialogsEnabled.i)
; put_AreDefaultScriptDialogsEnabled(AreDefaultScriptDialogsEnabled.l)
; get_IsStatusBarEnabled(IsStatusBarEnabled.i)
; put_IsStatusBarEnabled(IsStatusBarEnabled.l)
; get_AreDevToolsEnabled(AreDevToolsEnabled.i)
; put_AreDevToolsEnabled(AreDevToolsEnabled.l)
; get_AreDefaultContextMenusEnabled(enabled.i)
; put_AreDefaultContextMenusEnabled(enabled.l)
; get_AreHostObjectsAllowed(allowed.i)
; put_AreHostObjectsAllowed(allowed.l)
; get_IsZoomControlEnabled(enabled.i)
; put_IsZoomControlEnabled(enabled.l)
; get_IsBuiltInErrorPageEnabled(enabled.i)
; put_IsBuiltInErrorPageEnabled(enabled.l)
; EndInterface
; CompilerEndIf
Procedure.i WebViewAddWebMessageReceivedCallback(WebView, *Callback.WebViewWebMessageReceived_Prototype)
Protected Result.i
Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
Protected *EventHandler.ICoreWebView2WebMessageReceivedEventHandler_Structure
;Protected Settings.ICoreWebview2Settings
If GadgetType(WebView) = #PB_GadgetType_WebView And *Callback <> #Null
Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
If Controller
If Controller\get_CoreWebView2(@Core) = #S_OK And Core <> #Null
WebViewRemoveWebMessageReceivedCallback(WebView, Core)
; Core\get_Settings(@Settings)
;
; If Settings\get_IsWebMessageEnabled(@Result) = #S_OK
; If Result
; Debug "WebMessageEnabled"
; Else
; If Settings\put_IsWebMessageEnabled(#True) = #S_OK
; Debug "Ok"
; Else
; Debug "NoK"
; EndIf
; EndIf
; EndIf
*EventHandler = AddMapElement(WebViewWebMessageReceivedEventHandlerMap(), Str(WebView))
If *EventHandler
*EventHandler\pVtable = *EventHandler + OffsetOf(IUnknownBase_Structure\pQueryInterface)
*EventHandler\pQueryInterface = @ICoreWebView2WebMessageReceivedEventHandler_QueryInterface()
*EventHandler\pAddRef = @ICoreWebView2WebMessageReceivedEventHandler_AddRef()
*EventHandler\pRelease = @ICoreWebView2WebMessageReceivedEventHandler_Release()
*EventHandler\pInvoke = @ICoreWebView2WebMessageReceivedEventHandler_Invoke()
*EventHandler\Token = 0
*EventHandler\pCallback = *Callback
Result = Core\add_WebMessageReceived(*EventHandler, @*EventHandler\Token)
If Result = #S_OK
;Debug "Token: " + Str(*EventHandler\Token)
Result = #True
Else
WebViewRemoveWebMessageReceivedCallback(WebView, Core)
Result = #False
EndIf
EndIf
Core\Release()
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
Procedure.i WebViewWebMessageReceived(Message$)
Debug Message$
ProcedureReturn #S_OK
EndProcedure
Define Event.i
OpenWindow(0, 100, 100, 400, 100, "Hello", #PB_Window_SystemMenu)
WebViewGadget(0, 0, 0, 400, 100)
SetGadgetItemText(0, #PB_WebView_HtmlCode,
~"<!DOCTYPE html>\n" +
~"<html lang=\"en\">\n" +
~" <head>" +
~" <title>WebMessage</title>" +
~" </head>" +
~" <body>" +
~" After 3 seconds a message will be posted" +
~" </body>" +
~"</html>")
WebViewAddWebMessageReceivedCallback(0, @WebViewWebMessageReceived())
AddWindowTimer(0, 1, 3000)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Timer
If EventTimer() = 1
RemoveWindowTimer(0, 1)
WebViewExecuteScript(0, "window.chrome.webview.postMessage('Hello PureBasic');")
EndIf
EndIf
Until Event = #PB_Event_CloseWindow
CompilerEndIf