I have TEdgeBrowser and I am using ExecuteScript method from the DefaultInterface like this:
EdgeBrowser1->DefaultInterface->ExecuteScript()
ExecuteScript, when called this way takes 2 parameters:
System::WideChar * javaScript and const _di_ICoreWebView2ExecuteScriptCompletedHandler handler
What I want to write is a lambda function (using clang compiler) which gets executed (and destroyed) after a script is executed...
Something like:
EdgeBrowser1->DefaultInterface->(L"alert('Hello World!')",
_di_ICoreWebView2ExecuteScriptCompletedHandler(
new TCppInterfacedObject<TCoreWebView2ExecuteScriptCompletedHandler>(
[](HRESULT errorCode, PCWSTR resultObjectAsJson) -> HRESULT {
if (FAILED(errorCode))
{
ShowMessage("Failed to execute script");
return errorCode;
}
ShowMessage("Script executed successfully");
return S_OK;
})));
However, TCoreWebView2ExecuteScriptCompletedHandler doesn't seem to be defined? What do I need to insert there to make it work?
EDIT:
A few issues I encountered with otherwise excellent reply by @RemyLebeau
- in
WebView2.hppthe second parameter ofInvokeis defined asSystem::WideChar *so I couldn't useLPCWSTRas it reported that the virtual methodInvokeis unimplemented. Also there wasn't a__stdcall. Corrected by using instead:
HRESULT __stdcall Invoke(HRESULT errorCode, System::WideChar* resultObjectAsJson)
is the use of
INTFOBJECT_IMPL_IUNKNOWNreally necessary since the TCppInterfacedObject documentation describes that it already implementsIUnknownmethods likeQueryInterface,AddRef, andRelease? When commented out, there is no warning that those methods are unimplemented, like when it is when I "manually" implement theICoreWebView2ExecuteScriptCompletedHandlerIs it necessary to
Release()the object before it returns S_OK? I know that there is reference counting involved but does theExecuteScriptcall then does that? Basically, after executing the lambda or instance ofICoreWebView2ExecuteScriptCompletedHandler, it is no longer needed to be in memory.
The
TEdgeBrowser::DefaultInterfaceproperty is the rawICoreWebView2*interface pointer provided by Microsoft, just wrapped in theDelphiInterfaceclass (that is what the_di_prefix refers to). Microsoft has no concept of_di_wrapper types.The 2nd parameter of
ICoreWebView2::ExecuteScript()expects a pointer to an object that implements theICoreWebView2ExecuteScriptCompletedHandlerinterface. You can't pass in a lambda where an interface is expected. So, you need to write a class that implementsICoreWebView2ExecuteScriptCompletedHandler, and then pass an object instance of that class toExecuteScript().The way you are trying to use
TCppInterfacedObjectfor that purpose is not correct. Try this instead:If you really want to use a lambda, then you would need something more like this instead:
Alternatively:
And no, you should not call
Release()from inside the handler itself.ExecuteScript()willAddRef()the handler that you pass in if needed, and thenRelease()it when done using it. You should onlyAddRef()/Release()your own references to the handler.