Webview2 control - Chromium browser for Purebasic (Windows) [Jan 1, 2024]
Re: Webview2 control - Chromium browser for Purebasic (Windows)
"x64 is the bigger one." Thanks
vmars.us Win11 x64 , Martin Guitar 000-16 (1995)
"All things in moderation , except for love and forgiveness."
"All things in moderation , except for love and forgiveness."
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Hi ,
I tested out KidSafeBrowser quite thoroughly on the same computer used to program it .
Yesterday I had a chance to Test it on two other computers .
And they both gave an Error msg "Unable to create WebView2 environment" .
Does that mean I need to include "Ms Edge WebView Runtime" on all user computers .
Or did I leave a component out ?
I did include KidSafeBrowser.exe.WebView2 , gdiplus , WebView2Loader.lib , WebView2Loader.dll in the download .
Thanks
I tested out KidSafeBrowser quite thoroughly on the same computer used to program it .
Yesterday I had a chance to Test it on two other computers .
And they both gave an Error msg "Unable to create WebView2 environment" .
Does that mean I need to include "Ms Edge WebView Runtime" on all user computers .
Or did I leave a component out ?
I did include KidSafeBrowser.exe.WebView2 , gdiplus , WebView2Loader.lib , WebView2Loader.dll in the download .
Thanks
vmars.us Win11 x64 , Martin Guitar 000-16 (1995)
"All things in moderation , except for love and forgiveness."
"All things in moderation , except for love and forgiveness."
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Yes, the Webview runtime must be installed in every computer:
https://developer.microsoft.com/en-us/m ... /webview2/
https://developer.microsoft.com/en-us/m ... /webview2/
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Thanks
vmars.us Win11 x64 , Martin Guitar 000-16 (1995)
"All things in moderation , except for love and forgiveness."
"All things in moderation , except for love and forgiveness."
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Yay, I can finally use it.
One questions. Is there a way to change (catch) the error message for a missing DLL? And to possibly rename the DLL (if the license permits this)?
I couldn't find the call for the DLL in the code, perhaps it's hidden in some lib file or other.
Since the DLL is necessary even with the installed runtime package, it would be nice to include it in the programm and save to disk in case it was removed.
Thanks![Smile :)](./images/smilies/icon_smile.gif)
btw: any progress in makink this a native "Gadget" in PureBasic, I might have missed?
One questions. Is there a way to change (catch) the error message for a missing DLL? And to possibly rename the DLL (if the license permits this)?
I couldn't find the call for the DLL in the code, perhaps it's hidden in some lib file or other.
Since the DLL is necessary even with the installed runtime package, it would be nice to include it in the programm and save to disk in case it was removed.
Thanks
![Smile :)](./images/smilies/icon_smile.gif)
btw: any progress in makink this a native "Gadget" in PureBasic, I might have missed?
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Hi,
i used the import system to load the dll the code is in WebView2Loader.pbi, to check the error you can try to check the dll existence or maybe use the OpenLibrary() system instead.
With the import system you can change the dll name but you have to generate a .lib with the same name with polib:
polib /MACHINE:X64 /OUT:yourname.lib yourname.dll
Luis made a very good module to load dlls from inside the executable, i haven't tested with this one but with another worked:
https://www.purebasic.fr/english/viewto ... lit=memdll
i used the import system to load the dll the code is in WebView2Loader.pbi, to check the error you can try to check the dll existence or maybe use the OpenLibrary() system instead.
With the import system you can change the dll name but you have to generate a .lib with the same name with polib:
polib /MACHINE:X64 /OUT:yourname.lib yourname.dll
Luis made a very good module to load dlls from inside the executable, i haven't tested with this one but with another worked:
https://www.purebasic.fr/english/viewto ... lit=memdll
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Hi Justin,
I tried your stuff and to make it run I needed to modify the WebView2Loader.pbi:
With the original Import I run into Unresolved externals. No idea why.
Ok, then it was possible to run your examples.
But I needed 2 WebGadgets,
So I implemented a 'real' Gadget:
For the new stuff it was needed to extend WebView2.pbi: (Insert it at line 1512)
Feel free to add it if you want.
But unfortunately I can not use it in production.
I installed the webview2 runtime on different PCs , but I ran into trouble on 50% of the PCs.
So it is not a solution for customers.![Crying or Very sad :cry:](./images/smilies/icon_cry.gif)
I tried your stuff and to make it run I needed to modify the WebView2Loader.pbi:
Code: Select all
; CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
; Import "x64\WebView2Loader.lib"
;
; CompilerElse
; Import "x86\WebView2Loader.lib"
; CompilerEndIf
;
; CreateCoreWebView2Environment(environment_created_handler.i)
; CreateCoreWebView2EnvironmentWithOptions(browserExecutableFolder.s, userDataFolder.s, environmentOptions.i, environment_created_handler.i)
; GetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder.s, versionInfo.i)
; CompareBrowserVersions(version1.s, version2.s, result.i)
; EndImport
Prototype.i Prototype_CreateCoreWebView2Environment(environment_created_handler.i)
Prototype.i Prototype_CreateCoreWebView2EnvironmentWithOptions(browserExecutableFolder.s, userDataFolder.s, environmentOptions.i, environment_created_handler.i)
Prototype.i Prototype_GetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder.s, versionInfo.i)
Prototype.i Prototype_CompareBrowserVersions(version1.s, version2.s, result.i)
Global.i CreateCoreWebView2Environment.Prototype_CreateCoreWebView2Environment
Global.i CreateCoreWebView2EnvironmentWithOptions.Prototype_CreateCoreWebView2EnvironmentWithOptions
Global.i GetAvailableCoreWebView2BrowserVersionString.Prototype_GetAvailableCoreWebView2BrowserVersionString
Global.i CompareBrowserVersions.Prototype_CompareBrowserVersions
Global WebView2DLL.i
WebView2DLL = OpenLibrary(#PB_Any, "WebView2Loader.dll")
If WebView2DLL
CreateCoreWebView2Environment = GetFunction(WebView2DLL, "CreateCoreWebView2Environment")
CreateCoreWebView2EnvironmentWithOptions = GetFunction(WebView2DLL, "CreateCoreWebView2EnvironmentWithOptions")
GetAvailableCoreWebView2BrowserVersionString = GetFunction(WebView2DLL, "GetAvailableCoreWebView2BrowserVersionString")
CompareBrowserVersions = GetFunction(WebView2DLL, "CompareBrowserVersions")
EndIf
Ok, then it was possible to run your examples.
But I needed 2 WebGadgets,
So I implemented a 'real' Gadget:
Code: Select all
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
CompilerEndIf
; https://developer.microsoft.com/de-de/microsoft-edge/webview2/
; https://learn.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.winforms.webview2
IncludeFile "PBWebView2.pb"
Prototype.i Prototype_NavigationCallback(Gadget.i, URL$)
Structure WebView2Gadget_Structure
wvEnvironment.ICoreWebView2Environment
wvController.ICoreWebView2Controller
wvCore.ICoreWebView2_12
wvOptions.ICoreWebView2EnvironmentOptions
wvSettings.ICoreWebView2Settings6
wvDownloadOperation.ICoreWebView2DownloadOperation
*eventNavigationCompleted.WV2_EVENT_HANDLER
*eventNavigationStarting.WV2_EVENT_HANDLER
*eventWebResourceRequested.WV2_EVENT_HANDLER
*eventDocumentTitleChanged.WV2_EVENT_HANDLER
*eventStatusBarTextChanged.WV2_EVENT_HANDLER
*eventContextMenuRequested.WV2_EVENT_HANDLER
*eventDownloadStarting.WV2_EVENT_HANDLER
*eventDownloadBytesReceivedChanged.WV2_EVENT_HANDLER
*eventDownloadStateChanged.WV2_EVENT_HANDLER
Gadget.i
Window.i
UserDataFolder$
URL$
NavigationCallback.Prototype_NavigationCallback
EndStructure
Global NewMap WebView2GadgetMap.WebView2Gadget_Structure()
Procedure WebView2SetgadgetText(Gadget.i, URL$)
Protected *Gadget.WebView2Gadget_Structure
*Gadget = FindMapElement(WebView2GadgetMap(), Str(Gadget))
If *Gadget
*Gadget\URL$ = URL$
*Gadget\wvCore\Navigate(URL$)
EndIf
EndProcedure
Procedure.s WebView2GetgadgetText(Gadget.i)
Protected *Gadget.WebView2Gadget_Structure, Result$
*Gadget = FindMapElement(WebView2GadgetMap(), Str(Gadget))
If *Gadget
Result$ = *Gadget\URL$
EndIf
ProcedureReturn Result$
EndProcedure
Procedure WebView2SetGadgetState(Gadget.i, State.i)
Protected.l CanGoBack, CanGoForward
Protected *Gadget.WebView2Gadget_Structure
*Gadget = FindMapElement(WebView2GadgetMap(), Str(Gadget))
If *Gadget
Select State
Case #PB_Web_Back
*Gadget\wvCore\get_CanGoBack(@CanGoBack)
If CanGoBack
*Gadget\wvCore\GoBack()
EndIf
Case #PB_Web_Forward
*Gadget\wvCore\get_CanGoForward(@CanGoForward)
If CanGoForward
*Gadget\wvCore\GoForward()
EndIf
Case #PB_Web_Stop
*Gadget\wvCore\Stop()
Case #PB_Web_Refresh
*Gadget\wvCore\Reload()
EndSelect
EndIf
EndProcedure
Procedure WebView2SetGadgetItemText(Gadget.i, Entry.i, Text$, Column.i=0)
Protected *Gadget.WebView2Gadget_Structure
*Gadget = FindMapElement(WebView2GadgetMap(), Str(Gadget))
If *Gadget
Select Entry
Case #PB_Web_HtmlCode
*Gadget\wvCore\ExecuteScript(Text$, #Null)
EndSelect
EndIf
EndProcedure
Procedure.s WebView2GetGadgetItemText(Gadget.i, Entry.i, Column.i=0)
Protected *Gadget.WebView2Gadget_Structure, Result$, *Text, Script$, Text$
*Gadget = FindMapElement(WebView2GadgetMap(), Str(Gadget))
If *Gadget
Select Entry
Case #PB_Web_PageTitle
*Gadget\wvCore\get_DocumentTitle(@*Text)
If *Text
Result$ = PeekS(*Text)
CoTaskMemFree_(*Text)
EndIf
Case #PB_Web_StatusMessage
*Gadget\wvCore\get_StatusBarText(@*Text)
If *Text
Result$ = PeekS(*Text)
CoTaskMemFree_(*Text)
EndIf
Case #PB_Web_SelectedText
Script$ = "window.getSelection().toString()"
Text$ = wv2_Core_ExecuteScriptSync(*Gadget\wvCore, Script$)
If Text$
Result$ = json_GetString(Text$)
EndIf
Case #PB_Web_HtmlCode
Script$ = "document.documentElement.outerHTML"
Text$ = wv2_Core_ExecuteScriptSync(*Gadget\wvCore, Script$)
If Text$
Result$ = json_GetString(Text$)
EndIf
EndSelect
EndIf
ProcedureReturn Result$
EndProcedure
Procedure WebView2SetGadgetAttribute(Gadget.i, Attribute.i, Value.i)
Protected *Gadget.WebView2Gadget_Structure
*Gadget = FindMapElement(WebView2GadgetMap(), Str(Gadget))
If *Gadget
Select Attribute
Case #PB_Web_NavigationCallback
*Gadget\NavigationCallback = Value
EndSelect
EndIf
EndProcedure
Procedure.i WebView2GetGadgetAttribute(Gadget.i, Attribute.i, Value.i)
Protected *Gadget.WebView2Gadget_Structure, Result.i
*Gadget = FindMapElement(WebView2GadgetMap(), Str(Gadget))
If *Gadget
Select Attribute
Case #PB_Web_NavigationCallback
Result = *Gadget\NavigationCallback
Case #PB_Web_Progress
*Gadget\wvDownloadOperation\get_BytesReceived(@Result)
Case #PB_Web_ProgressMax
*Gadget\wvDownloadOperation\get_TotalBytesToReceive(@Result)
EndSelect
EndIf
ProcedureReturn Result
EndProcedure
Procedure WebView2Gadget_Resize()
Protected Gadget.i
Protected wvBounds.RECT
Protected *Gadget.WebView2Gadget_Structure
;Debug "WebView2Gadget_Resize"
Gadget = EventGadget()
;Debug "Gadget: " + Str(Gadget)
Gadget = EventGadget()
*Gadget = FindMapElement(WebView2GadgetMap(), Str(Gadget))
If *Gadget
If *Gadget\wvController
BringWindowToTop_(GadgetID(*Gadget\Gadget)) ; else problem if it overlaps an other gGadget
wvBounds\left = 0
wvBounds\top = 0
wvBounds\bottom = wvBounds\top + DesktopScaledY(GadgetHeight(Gadget))
wvBounds\right = wvBounds\left + DesktopScaledX(GadgetWidth(Gadget))
wv2_Controller_put_Bounds(*Gadget\wvController, @wvBounds)
EndIf
EndIf
EndProcedure
Procedure WebView2GadgetNavigationStarting(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationStartingEventArgs)
Protected *Gadget.WebView2Gadget_Structure, *uri
;Debug "WebView2GadgetNavigationStarting"
;Debug "Gadget: " + Str(*this\context)
*Gadget = FindMapElement(WebView2GadgetMap(), Str(*this\context))
If *Gadget
If args\get_uri(@*uri) = #S_OK
*Gadget\URL$ = PeekS(*uri)
CoTaskMemFree_(*uri)
If *Gadget\NavigationCallback
If Not *Gadget\NavigationCallback(*this\context, *Gadget\URL$)
args\put_Cancel(#True)
EndIf
EndIf
EndIf
EndIf
EndProcedure
Procedure WebView2GadgetNavigationCompleted(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
;Debug "WebView2GadgetNavigationCompleted"
;Debug "Gadget: " + Str(*this\context)
EndProcedure
Procedure WebView2GadgetDocumentTitleChanged(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
Protected *Gadget.WebView2Gadget_Structure
;Debug "WebView2GadgetDocumentTitleChanged"
;Debug "Gadget: " + Str(*this\context)
*Gadget = FindMapElement(WebView2GadgetMap(), Str(*this\context))
If *Gadget
PostEvent(#PB_Event_Gadget, *Gadget\Window, *Gadget\Gadget, #PB_EventType_TitleChange)
EndIf
EndProcedure
Procedure WebView2GadgetStatusBarTextChanged(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
Protected *Gadget.WebView2Gadget_Structure
;Debug "WebView2GadgetStatusBarTextChanged"
;Debug "Gadget: " + Str(*this\context)
*Gadget = FindMapElement(WebView2GadgetMap(), Str(*this\context))
If *Gadget
PostEvent(#PB_Event_Gadget, *Gadget\Window, *Gadget\Gadget, #PB_EventType_StatusChange)
EndIf
EndProcedure
Procedure WebView2GadgetDownloadBytesReceivedChanged(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
Protected *Gadget.WebView2Gadget_Structure, BytesReceived.i
Debug "WebView2GadgetBytesReceivedChanged"
Debug "Gadget: " + Str(*this\context)
*Gadget = FindMapElement(WebView2GadgetMap(), Str(*this\context))
If *Gadget
*Gadget\wvDownloadOperation\get_BytesReceived(@BytesReceived)
Debug BytesReceived
PostEvent(#PB_Event_Gadget, *Gadget\Window, *Gadget\Gadget, #PB_EventType_DownloadProgress, BytesReceived)
EndIf
EndProcedure
Procedure WebView2GadgetDownloadStateChanged(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
Protected *Gadget.WebView2Gadget_Structure, State.i
Debug "WebView2GadgetBytesReceivedChanged"
Debug "Gadget: " + Str(*this\context)
*Gadget = FindMapElement(WebView2GadgetMap(), Str(*this\context))
If *Gadget
*Gadget\wvDownloadOperation\get_State(@State)
Select State
Case #COREWEBVIEW2_DOWNLOAD_STATE_IN_PROGRESS
Debug "Progress"
PostEvent(#PB_Event_Gadget, *Gadget\Window, *Gadget\Gadget, #PB_EventType_DownloadProgress)
Case #COREWEBVIEW2_DOWNLOAD_STATE_INTERRUPTED, #COREWEBVIEW2_DOWNLOAD_STATE_COMPLETED
Debug "Interrupted or Completed"
PostEvent(#PB_Event_Gadget, *Gadget\Window, *Gadget\Gadget, #PB_EventType_DownloadEnd)
EndSelect
EndIf
EndProcedure
Procedure WebView2GadgetDownloadStarting(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2DownloadStartingEventArgs)
Protected *Gadget.WebView2Gadget_Structure
Debug "WebView2GadgetDownloadStarting"
Debug "Gadget: " + Str(*this\context)
*Gadget = FindMapElement(WebView2GadgetMap(), Str(*this\context))
If *Gadget
If *Gadget\wvDownloadOperation
*Gadget\wvDownloadOperation\remove_StateChanged(#Null)
*Gadget\wvDownloadOperation\remove_BytesReceivedChanged(#Null)
*Gadget\wvDownloadOperation\Release()
EndIf
args\get_DownloadOperation(@*Gadget\wvDownloadOperation)
*Gadget\eventDownloadBytesReceivedChanged = wv2_EventHandler_New(@WebView2GadgetDownloadBytesReceivedChanged(), *this\context)
*Gadget\wvDownloadOperation\add_BytesReceivedChanged(*Gadget\eventDownloadBytesReceivedChanged, #Null)
*Gadget\eventDownloadStateChanged = wv2_EventHandler_New(@WebView2GadgetDownloadStateChanged(), *this\context)
*Gadget\wvDownloadOperation\add_StateChanged(*Gadget\eventDownloadStateChanged, #Null)
PostEvent(#PB_Event_Gadget, *Gadget\Window, *Gadget\Gadget, #PB_EventType_DownloadStart)
EndIf
EndProcedure
Procedure WebView2GadgetContextMenuRequested(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2DownloadStartingEventArgs)
Protected *Gadget.WebView2Gadget_Structure
Debug "WebView2GadgetDownloadStarting"
Debug "Gadget: " + Str(*this\context)
*Gadget = FindMapElement(WebView2GadgetMap(), Str(*this\context))
If *Gadget
PostEvent(#PB_Event_Gadget, *Gadget\Window, *Gadget\Gadget, #PB_EventType_PopupMenu)
EndIf
EndProcedure
Procedure Webview2Controller_Created(*this.WV2_EVENT_HANDLER, result.l, controller.ICoreWebView2Controller)
Protected *Gadget.WebView2Gadget_Structure, *Get, wvBounds.RECT
Debug "Webview2Controller_Created"
Debug "Gadget: " + Str(*this\context)
*Gadget = FindMapElement(WebView2GadgetMap(), Str(*this\context))
If *Gadget
If result = #S_OK
controller\QueryInterface(?IID_ICoreWebView2Controller, @*Gadget\wvController)
*Gadget\wvController\get_CoreWebView2(@*Gadget\wvCore)
; Setup events
*Gadget\eventNavigationCompleted = wv2_EventHandler_New(@WebView2GadgetNavigationCompleted(), *this\context)
*Gadget\wvCore\add_NavigationCompleted(*Gadget\eventNavigationCompleted, #Null)
*Gadget\eventNavigationStarting = wv2_EventHandler_New(@WebView2GadgetNavigationStarting(), *this\context)
*Gadget\wvCore\add_NavigationStarting(*Gadget\eventNavigationStarting, #Null)
*Gadget\eventDocumentTitleChanged = wv2_EventHandler_New(@WebView2GadgetDocumentTitleChanged(), *this\context)
*Gadget\wvCore\add_DocumentTitleChanged(*Gadget\eventDocumentTitleChanged, #Null)
*Gadget\eventDownloadStarting = wv2_EventHandler_New(@WebView2GadgetDownloadStarting(), *this\context)
*Gadget\wvCore\add_DownloadStarting(*Gadget\eventDownloadStarting, #Null)
*Gadget\eventStatusBarTextChanged = wv2_EventHandler_New(@WebView2GadgetStatusBarTextChanged(), *this\context)
*Gadget\wvCore\add_StatusBarTextChanged(*Gadget\eventStatusBarTextChanged, #Null)
*Gadget\eventContextMenuRequested = wv2_EventHandler_New(@WebView2GadgetContextMenuRequested(), *this\context)
*Gadget\wvCore\add_ContextMenuRequested(*Gadget\eventContextMenuRequested, #Null)
; Settings
; https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2settings
*Gadget\wvCore\get_Settings(@*Gadget\wvSettings)
*Gadget\wvSettings\put_AreBrowserAcceleratorKeysEnabled(#False) ;
*Gadget\wvSettings\put_IsStatusBarEnabled(#False) ; don't show the links t the bottom
*Gadget\wvSettings\put_AreDevToolsEnabled(#False) ; don't allow DevTools
;*Gadget\wvSettings\put_AreDefaultContextMenusEnabled(#False) ; disable browser context popup
*Gadget\wvSettings\put_IsBuiltInErrorPageEnabled(#False)
; Resize it
wvBounds\left = 0
wvBounds\top = 0
wvBounds\bottom = wvBounds\top + DesktopScaledY(GadgetHeight(*this\context))
wvBounds\right = wvBounds\left + DesktopScaledX(GadgetWidth(*this\context))
wv2_Controller_put_Bounds(*Gadget\wvController, @wvBounds)
; Go to startpage
*Gadget\wvCore\Navigate(*Gadget\URL$)
wv2_EventHandler_Release(*this)
*Gadget\wvOptions\get_AdditionalBrowserArguments(@*Get)
Debug PeekS(*Get)
CoTaskMemFree_(*Get)
Else
MessageRequester("Error", "Failed to create WebView2Controller.")
End
EndIf
EndIf
EndProcedure
Procedure WebView2Environment_Created(*this.WV2_EVENT_HANDLER, result.l, environment.ICoreWebView2Environment)
Protected *Gadget.WebView2Gadget_Structure
Debug "WebView2Environment_Created"
Debug "Gadget: " + Str(*this\context)
*Gadget = FindMapElement(WebView2GadgetMap(), Str(*this\context))
If *Gadget
If result = #S_OK
environment\QueryInterface(?IID_ICoreWebView2Environment, @*Gadget\wvEnvironment)
*Gadget\wvEnvironment\CreateCoreWebView2Controller(GadgetID(*Gadget\Gadget), wv2_EventHandler_New(@Webview2Controller_Created(), *this\Context))
wv2_EventHandler_Release(*this)
*Gadget\wvEnvironment\Release()
Else
MessageRequester("Error", "Failed to create WebView2Environment.")
End
EndIf
EndIf
EndProcedure
Procedure WebView2CleanUp()
Protected UserDataFolder$
Debug "WebView2CleanUp"
ForEach WebView2GadgetMap()
WebView2GadgetMap()\wvController\Close()
WebView2GadgetMap()\wvController\Release()
If WebView2GadgetMap()\wvSettings
WebView2GadgetMap()\wvSettings\Release()
EndIf
If WebView2GadgetMap()\wvCore
WebView2GadgetMap()\wvCore\Release()
EndIf
If WebView2GadgetMap()\eventNavigationCompleted
wv2_EventHandler_Release(WebView2GadgetMap()\eventNavigationCompleted)
EndIf
If WebView2GadgetMap()\eventNavigationStarting
wv2_EventHandler_Release(WebView2GadgetMap()\eventNavigationStarting)
EndIf
If WebView2GadgetMap()\eventWebResourceRequested
wv2_EventHandler_Release(WebView2GadgetMap()\eventWebResourceRequested)
EndIf
If WebView2GadgetMap()\eventDocumentTitleChanged
wv2_EventHandler_Release(WebView2GadgetMap()\eventDocumentTitleChanged)
EndIf
If WebView2GadgetMap()\wvOptions
WebView2GadgetMap()\wvOptions\Release()
EndIf
If WebView2GadgetMap()\eventDownloadStarting
wv2_EventHandler_Release(WebView2GadgetMap()\eventDownloadStarting)
EndIf
If WebView2GadgetMap()\eventDownloadBytesReceivedChanged
wv2_EventHandler_Release(WebView2GadgetMap()\eventDownloadBytesReceivedChanged)
EndIf
If WebView2GadgetMap()\eventDownloadStateChanged
wv2_EventHandler_Release(WebView2GadgetMap()\eventDownloadStateChanged)
EndIf
If WebView2GadgetMap()\wvDownloadOperation
WebView2GadgetMap()\wvDownloadOperation\Release()
EndIf
Next
Delay(1000) ; shit, but needed
ForEach WebView2GadgetMap()
Debug "cmd /c " + #DQUOTE$ + "rd /s /q " + WebView2GadgetMap()\UserDataFolder$ + #DQUOTE$
RunProgram("cmd", "/c " + #DQUOTE$ + "rd /s /q " + WebView2GadgetMap()\UserDataFolder$ + #DQUOTE$, "", #PB_Program_Hide)
Next
EndProcedure
Procedure.i WebView2Gadget(Gadget.i, x.i, y.i, width.i, height.i, URL$)
Protected.i Window, InternalGadget, Options$
Debug "WebView2Gadget()"
If WebView2DLL
If wv2_GetBrowserVersion("") <> ""
If Gadget = #PB_Any
InternalGadget = ContainerGadget(Gadget, x, y, width, height, #PB_Container_BorderLess)
If InternalGadget = 0
InternalGadget = -1
EndIf
Else
If ContainerGadget(Gadget, x, y, width, height, #PB_Container_Single)
InternalGadget = Gadget
Else
InternalGadget = -1
EndIf
EndIf
If InternalGadget <> -1
CloseGadgetList()
AddMapElement(WebView2GadgetMap(), Str(InternalGadget))
WebView2GadgetMap()\Gadget = InternalGadget
WebView2GadgetMap()\Window = GetActiveWindow()
WebView2GadgetMap()\URL$ = URL$
BindGadgetEvent(InternalGadget, @WebView2Gadget_Resize(), #PB_EventType_Resize)
Options$ + "--inprivate "
Options$ + "--disable-extensions "
Options$ + "--disable-notifications "
Options$ + "--disable-sync "
Options$ + "--disable-features=Translate "
Options$ + "--enable-features=msEdgeDeleteBrowsingDataOnExit "
Options$ + "--hide-scrollbars "
Options$ + "--no-Default-browser-check "
Options$ + "--no-first-run "
Options$ + "--no-experiments "
Options$ + "--no-pings "
Options$ + "--no-proxy-server "
Options$ + "--noerrdialogs "
Options$ + "--new-window"
WebView2GadgetMap()\wvOptions = wv2_EnvironmentOptions_New()
WebView2GadgetMap()\wvOptions\put_AdditionalBrowserArguments(Options$)
;WebView2GadgetMap()\wvOptions\put_Language("de")
WebView2GadgetMap()\UserDataFolder$ = GetUserDirectory(#PB_Directory_ProgramData) + GetFilePart(ProgramFilename(), #PB_FileSystem_NoExtension) + #PS$ + "WebView_" + Str(Gadget)
CreateCoreWebView2EnvironmentWithOptions("", WebView2GadgetMap()\UserDataFolder$, WebView2GadgetMap()\wvOptions, wv2_EventHandler_New(@WebView2Environment_Created(), InternalGadget))
;CreateCoreWebView2EnvironmentWithOptions("", "", #Null, wv2_EventHandler_New(@WebView2Environment_Created(), InternalGadget))
;CreateCoreWebView2EnvironmentWithOptions("", "", WebView2GadgetMap()\wvOptions, wv2_EventHandler_New(@WebView2Environment_Created(), InternalGadget))
Else
InternalGadget = 0
EndIf
Else
MessageRequester("Error","WebView2 Not installed")
End
EndIf
Else
MessageRequester("Error","WebView2 DLL not loaded")
EndIf
ProcedureReturn InternalGadget
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
;-Demo
Procedure NavigationCallback(Gadget, Url$)
Protected Result.i
Result = #True
If FindString(LCase(Url$), "www.spiderbasic.com")
MessageRequester("Info", "Blocked: " + Url$)
Result = #False
EndIf
ProcedureReturn Result
EndProcedure
Procedure ResizeIt()
ResizeGadget(1, #PB_Ignore, #PB_Ignore, WindowWidth(0) / 2 - 5, WindowHeight(0) - 20)
ResizeGadget(2, WindowWidth(0) / 2 + 5, #PB_Ignore, WindowWidth(0) / 2 - 5, WindowHeight(0) - 20)
EndProcedure
Define Event.i, EventGadget.i
OpenWindow(0, 0, 0, 1230, 820, "WebView2 Gadget", #PB_Window_ScreenCentered|#PB_Window_MinimizeGadget|#PB_Window_SizeGadget)
WebView2Gadget(1, 10, 10, 600, 800, "https://www.purebasic.fr/english")
WebView2Gadget(2, 620, 10, 600, 800, "https://www.purebasic.fr/german")
BindEvent(#PB_Event_SizeWindow, @ResizeIt())
AddWindowTimer(0, 1, 5000)
;-Main loop
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
EventGadget = EventGadget()
Select EventGadget
Case 1, 2
Select EventType()
Case #PB_EventType_TitleChange
Debug "Gadget " + Str(EventGadget) + " TitleChanged"
Debug "Title gadget " + Str(EventGadget) + ": " + WebView2GetGadgetItemText(EventGadget, #PB_Web_PageTitle)
Case #PB_EventType_DownloadStart
Debug "Gadget " + Str(EventGadget) + " download started"
Case #PB_EventType_StatusChange
Debug "Gadget " + Str(EventGadget) + " status changed"
Debug "Status gadget " + Str(EventGadget) + ": " + WebView2GetGadgetItemText(EventGadget, #PB_Web_StatusMessage)
Case #PB_EventType_DownloadStart
Debug "Gadget " + Str(EventGadget) + "download started"
EndSelect
EndSelect
Case #PB_Event_Timer
Select EventTimer()
Case 1
RemoveWindowTimer(0, 1)
Debug "Url gadget 1: " + WebView2GetgadgetText(1)
Debug "Url gadget 2: " + WebView2GetgadgetText(2)
AddWindowTimer(0, 2, 5000)
Case 2
RemoveWindowTimer(0, 2)
Debug "Set URL of gadget 1 to https://www.purebasic.fr"
WebView2SetgadgetText(1, "https://www.purebasic.fr")
AddWindowTimer(0, 3, 5000)
Case 3
RemoveWindowTimer(0, 3)
Debug "Refresh gadget 1"
WebView2SetGadgetState(1, #PB_Web_Refresh)
AddWindowTimer(0, 4, 5000)
Case 4
RemoveWindowTimer(0, 4)
Debug "Back gadget 1"
WebView2SetGadgetState(1, #PB_Web_Back)
AddWindowTimer(0, 5, 5000)
Case 5
RemoveWindowTimer(0, 5)
Debug "Forward gadget 1"
WebView2SetGadgetState(1, #PB_Web_Forward)
AddWindowTimer(0, 6, 5000)
Case 6
RemoveWindowTimer(0, 6)
Debug "Activate NavigationCallback and block spiderbasic"
Debug "Set URL of Gadget 2 to https://www.spiderbasic.com"
WebView2SetgadgetAttribute(2, #PB_Web_NavigationCallback, @NavigationCallback())
WebView2SetgadgetText(2, "https://www.spiderbasic.com")
AddWindowTimer(0, 7, 5000)
Case 7
RemoveWindowTimer(0, 7)
Debug "Remove NavigationCallback"
Debug "Set URL of gadget 2 to https://www.spiderbasic.com"
WebView2SetgadgetAttribute(2, #PB_Web_NavigationCallback, #Null)
WebView2SetgadgetText(2, "https://www.spiderbasic.com")
AddWindowTimer(0, 8, 5000)
Case 8
RemoveWindowTimer(0, 8)
Debug "Get html code from gadget 1"
Debug WebView2GetGadgetItemText(1, #PB_Web_HtmlCode)
;Debug WebView2GetGadgetItemText(1, #PB_Web_SelectedText)
AddWindowTimer(0, 9, 5000)
Case 9
RemoveWindowTimer(0, 9)
Debug "Inject code in gadget 1"
WebView2SetGadgetItemText(1, #PB_Web_HtmlCode, "alert('This demo was presented by infratec');")
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
CloseWindow(0)
WebView2CleanUp()
CompilerEndIf
Code: Select all
;- ICoreWebView2_8
DataSection
IID_ICoreWebView2_8:
Data.l $E9632730
Data.w $6E1E, $43AB
Data.b $B7, $B8, $7B, $2C, $9E, $62, $E0, $94
EndDataSection
Interface ICoreWebView2_8 Extends ICoreWebView2_7
add_IsMutedChanged(*eventHandler, *token)
remove_IsMutedChanged(token.l)
get_IsMuted(*value)
put_IsMuted(value.l)
add_IsDocumentPlayingAudioChanged(*eventHandler, *token)
remove_IsDocumentPlayingAudioChanged(token.l)
get_IsDocumentPlayingAudio(*value)
EndInterface
;- ICoreWebView2_9
DataSection
IID_ICoreWebView2_9:
Data.l $4d7b2eab
Data.w $9fdc, $468d
Data.b $b9, $98, $a9, $26, $0b, $5e, $d6, $51
EndDataSection
Interface ICoreWebView2_9 Extends ICoreWebView2_8
add_IsDefaultDownloadDialogOpenChanged(*handler, *token)
remove_IsDefaultDownloadDialogOpenChanged(token.l)
get_IsDefaultDownloadDialogOpen(*value)
OpenDefaultDownloadDialog()
CloseDefaultDownloadDialog()
get_DefaultDownloadDialogCornerAlignment(*value)
put_DefaultDownloadDialogCornerAlignment(value.l)
get_DefaultDownloadDialogMargin(*value)
put_DefaultDownloadDialogMargin(value.l)
EndInterface
;- ICoreWebView2_10
DataSection
IID_ICoreWebView2_10:
Data.l $b1690564
Data.w $6f5a, $4983
Data.b $8e, $48, $31, $d1, $14, $3f, $ec, $db
EndDataSection
Interface ICoreWebView2_10 Extends ICoreWebView2_9
add_BasicAuthenticationRequested(*eventHandler, *token)
remove_BasicAuthenticationRequested(token.l)
EndInterface
;- ICoreWebView2_11
DataSection
IID_ICoreWebView2_11:
Data.l $0be78e56
Data.w $c193, $4051
Data.b $b9, $43, $23, $b4, $60, $c0, $8b, $db
EndDataSection
Interface ICoreWebView2_11 Extends ICoreWebView2_10
CallDevToolsProtocolMethodForSession(sessionId.p-Unicode, methodName.p-Unicode, parametersAsJson.p-Unicode, *handler)
add_ContextMenuRequested(*eventHandler, *token)
remove_ContextMenuRequested(token.l)
EndInterface
;- ICoreWebView2_12
DataSection
IID_ICoreWebView2_12:
Data.l $35D69927
Data.w $BCFA, $4566
Data.b $93, $49, $6B, $3E, $0D, $15, $4C, $AC
EndDataSection
Interface ICoreWebView2_12 Extends ICoreWebView2_11
add_StatusBarTextChanged(*eventHandler, *token)
remove_StatusBarTextChanged(token.l)
get_StatusBarText(*value)
EndInterface
;- ICoreWebView2_13
DataSection
IID_ICoreWebView2_13:
Data.l $F75F09A8
Data.w $667E, $4983
Data.b $88, $D6, $C8, $77, $3F, $31, $5E, $84
EndDataSection
Interface ICoreWebView2_13 Extends ICoreWebView2_12
get_Profile(*value)
EndInterface
;- ICoreWebView2_14
DataSection
IID_ICoreWebView2_14:
Data.l $6DAA4F10
Data.w $4A90, $4753
Data.b $88, $98, $77, $C5, $DF, $53, $41, $65
EndDataSection
Interface ICoreWebView2_14 Extends ICoreWebView2_13
add_ServerCertificateErrorDetected(*eventHandler, *token)
remove_ServerCertificateErrorDetected(token.l)
ClearServerCertificateErrorActions(*handler)
EndInterface
;- ICoreWebView2_15
DataSection
IID_ICoreWebView2_15:
Data.l $517B2D1D
Data.w $7DAE, $4A66
Data.b $A4, $F4, $10, $35, $2F, $FB, $95, $18
EndDataSection
Interface ICoreWebView2_15 Extends ICoreWebView2_14
add_FaviconChanged(*eventHandler, *token)
remove_FaviconChanged(token.l)
get_FaviconUri(*value)
GetFavicon(format.l, *completedHandler)
EndInterface
Feel free to add it if you want.
But unfortunately I can not use it in production.
I installed the webview2 runtime on different PCs , but I ran into trouble on 50% of the PCs.
So it is not a solution for customers.
![Crying or Very sad :cry:](./images/smilies/icon_cry.gif)
Last edited by infratec on Mon Dec 12, 2022 3:58 pm, edited 9 times in total.
Re: Webview2 control - Chromium browser for Purebasic (Windows)
I tried your example and worked here, i only had to modify the wv2_EventHandler_New() function because the last version uses only 2 parameters i removed the first one.
What kind of errors are you getting on those PCs? Wich OS?
About the import issue try to download the last version and put your code in the examples folder and run it from there it shoud work.
What kind of errors are you getting on those PCs? Wich OS?
About the import issue try to download the last version and put your code in the examples folder and run it from there it shoud work.
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Ups... I thought I downloaded it fresh from git.
All PCs I tried was Win10 x64 22H2 latest available patches installed.
I used your x86 version, because I don't know the windows version of the customers.
On the PCs where it does not work I see no error messages, but the program shows the 'frame' of the first container and nothing happens.
Sometimes the program is 'not reponding' and I have to kill it.
In one case the gadgets were displayed after arround 2 minutes.
All PCs I tried was Win10 x64 22H2 latest available patches installed.
I used your x86 version, because I don't know the windows version of the customers.
On the PCs where it does not work I see no error messages, but the program shows the 'frame' of the first container and nothing happens.
Sometimes the program is 'not reponding' and I have to kill it.
In one case the gadgets were displayed after arround 2 minutes.
Re: Webview2 control - Chromium browser for Purebasic (Windows)
I downloaded now the latest version from Git and adjusted my code above.
But still with this version I can not use your Import in WebView2Loader.pbi.
It results in 2 unresolved externals:
But still with this version I can not use your Import in WebView2Loader.pbi.
It results in 2 unresolved externals:
As written, if I use OpenLibrary() it works.error: Unresolved external symbol '_CreateCoreWebView2EnvironmentWithOptions@16'.
error: Unresolved external symbol '_GetAvailableCoreWebView2BrowserVersionString@8'.
Re: Webview2 control - Chromium browser for Purebasic (Windows)
I extended the WebView2Gadget above with:
Code: Select all
Procedure WebView2SetgadgetText(Gadget.i, URL$)
Procedure.s WebView2GetgadgetText(Gadget.i)
Procedure WebView2SetGadgetState(Gadget.i, State.i)
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Added above:
Code: Select all
Procedure WebView2SetGadgetItemText(Gadget.i, Entry.i, Text$, Column.i=0)
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Added above:
At the moment only for #PB_Web_NavigationCallback
Code: Select all
Procedure WebView2SetgadgetAttribute(Gadget.i, Attribute.i, Value.i)
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Same here with x86 pbcompiler.
with x64 ASM Compiler, your dual WebView2Gadget example works fine, without seeing any specific slowness here.
With the C Backend, I have the following error
Edit: OK, ASM Compiler only VCall.pb is wittren in asm
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Updated the listing above.
Some strange behaviours are fixed now.
Options and Settings are added.
Some strange behaviours are fixed now.
Options and Settings are added.