Webview2 control - Chromium browser for Purebasic (Windows) [Jan 1, 2024]
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Update February 19, 2022
Awaitable events.
Changed the system to wait for asynchronous events to complete. So it is possible for example to execute scripts synchronously.
The previous method was a dirty hack that spawned an event loop and could not be used inside window binded events.
The new method is much better, it uses the api wait functions.
There is a new EventHandlerWaitable object for that, look at wv2_Core_ExecuteScriptSync() in WebView2_Helper.pb for details if you are interested.
The method is used in the bootstrap.pb example in menu_GetPassword_Click().
Also in basic_browser_sync.pb it's used to create webview environment and controller synchronously.
This is very good because one of the biggest problems i saw with Webview2 was that scripts were executed asynchronously, with a language that does not have an await system it's a total mess, now is solved.
wv2_EventHandler_New() parameters have changed, you will have to update your code if you are using it.
Awaitable events.
Changed the system to wait for asynchronous events to complete. So it is possible for example to execute scripts synchronously.
The previous method was a dirty hack that spawned an event loop and could not be used inside window binded events.
The new method is much better, it uses the api wait functions.
There is a new EventHandlerWaitable object for that, look at wv2_Core_ExecuteScriptSync() in WebView2_Helper.pb for details if you are interested.
The method is used in the bootstrap.pb example in menu_GetPassword_Click().
Also in basic_browser_sync.pb it's used to create webview environment and controller synchronously.
This is very good because one of the biggest problems i saw with Webview2 was that scripts were executed asynchronously, with a language that does not have an await system it's a total mess, now is solved.
wv2_EventHandler_New() parameters have changed, you will have to update your code if you are using it.
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Hello ,
02/20/22 I downloaded newest version from here:
https://github.com/omegakode/PBWebview2
Compiled it and now I get this error:
[17:02:33] [COMPILER] Line 818: wv2_EventHandler_New(): Incorrect number of parameters.
[17:05:26] [COMPILER] Line 818: wv2_EventHandler_New(): Incorrect number of parameters.
Line 818 :
*browser\evNavigationStarting = wv2_EventHandler_New(?IID_ICoreWebView2NavigationStartingEventHandler, @core_NavigationStaring(), *browser)
And the same msg for 820 , 822 , 824 , 826 , 829 , 1096
Then: The procedure 'wv2_EventHandler_Free()' has been declared but not defined
My line numbers may be off by about 40 , because of some changes I have made to add a 'Approved-Links-File' .
Much Thanks to you :
Here is what I am working on: https://sourceforge.net/projects/kidsafebrowser-us/
Thanks
02/20/22 I downloaded newest version from here:
https://github.com/omegakode/PBWebview2
Compiled it and now I get this error:
[17:02:33] [COMPILER] Line 818: wv2_EventHandler_New(): Incorrect number of parameters.
[17:05:26] [COMPILER] Line 818: wv2_EventHandler_New(): Incorrect number of parameters.
Line 818 :
*browser\evNavigationStarting = wv2_EventHandler_New(?IID_ICoreWebView2NavigationStartingEventHandler, @core_NavigationStaring(), *browser)
And the same msg for 820 , 822 , 824 , 826 , 829 , 1096
Then: The procedure 'wv2_EventHandler_Free()' has been declared but not defined
My line numbers may be off by about 40 , because of some changes I have made to add a 'Approved-Links-File' .
Code: Select all
+
Else
; *browser\core\Navigate("about:blank")
*browser\core\Navigate("http://kidsafebrowser.us/KidSafeBrowserHome.html")
; *browser\core\Navigate("file:///C:/Users/vmars/vmars.us/SafeBrowser/KidSafeBrowserHome.html")
EndIf
+Procedure browser_GoHome(*browser.BROWSER)
If *browser And *browser\core
; *browser\core\Navigate("https://duckduckgo.com")
*browser\core\Navigate("http://kidsafebrowser.us/KidSafeBrowserHome.html")
; *browser\core\Navigate("file:///C:/Users/vmars/vmars.us/SafeBrowser/KidSafeBrowserHome.html")
EndIf
EndProcedure
+
Procedure IfThisSiteOk(Passed_suri$)
; Check If LinkEnteredEditor link is in ThisSite List
ThisSiteItemOk = #False
ResetList(ThisSiteList())
While NextElement(ThisSiteList())
; MessageRequester("If This Site Ok() = " , "In this String " + Passed_suri$ +Chr(13)+Chr(10)+
; " Find This " + CurrentElementContent$ )
CurrentElementContent$ = ThisSiteList()
; Debug "IfThisSiteOk CurrentElementContent$ = " + CurrentElementContent$
Position = FindString(Passed_suri$, CurrentElementContent$ , 0 )
If Position > 0
; Debug "FOUND_ONE IfThisSiteOk = " + Passed_suri$
ThisSiteItemOk = #True
Break
EndIf ; Greater than 0
Wend
; If ThisSiteItemOk = #False
; IfThisLinkOk(Passed_suri$)
; EndIf
EndProcedure ; IfThisSiteOk()
; ==============================
Procedure IfThisLinkOk(Passed_suri$)
; Check If LinkEnteredEditor link is in ThisLinkList()
ThisLinkItemOk = #False
; Check If LinkEnteredEditor link is in ThisLinkList()
ResetList(ThisLinkList())
While NextElement(ThisLinkList())
; MessageRequester("If This Link Ok() = " , "In this String " + Passed_suri$ +Chr(13)+Chr(10)+
; " Find This " + CurrentElementContent$ )
CurrentElementContent$ = ThisLinkList()
; Debug "IfThisLinkOk CurrentElementContent$" + CurrentElementContent$
Position = FindString(Passed_suri$, CurrentElementContent$ , 0 )
If Position > 0
; Debug "IfThisLinkOk() = " + Passed_suri$
ThisLinkItemOk = #True
; Debug "FOUND_ONE IfThisLinkOk = " + Passed_suri$
EndIf ; Greater than 0 == Yes a Hit
Wend
If ThisLinkItemOk = #False
MessageRequester("Site Not Approved" , Passed_suri$ + Chr(13) + Chr(10) +
Chr(13) + Chr(10) + "This Site Not yet Approved." + Chr(13) + Chr(10) +
Chr(13) + Chr(10) + "NAVIGATION CANCELLED ." + Chr(13) + Chr(10) +
Chr(13) + Chr(10) + "Please make a Request to System Administrator ." )
EndIf
EndProcedure ; IfThisLinkOk()
;
Procedure ThisLinkIsGo(Passed_suri$)
MessageRequester("ThisLinkIsGo() = " , "Passed_suri$ = " + Passed_suri$ )
EndProcedure ; ThisLinkIsGo()
; ==============================
;-
Procedure core_NavigationStaring(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationStartingEventArgs)
Protected.i uri
Protected.s suri
Protected.BROWSER *browser
; Debug "Event NavigationStarting " + Passed_suri$
If FirstTimeThru
If ReadFile(0, "SakerPlats.swd") ; read NEXT FILE ~ 1.TXT
While Eof(0) = 0
AddElement(ThisSiteList())
ThisSiteList() = ReadString(0)
; Debug ThisSiteList()
Wend
CloseFile(0)
Else
MessageRequester("Information","Couldn't open SakerPlats.swd file!")
EndIf
; ==============================
If ReadFile(0, "SakerLank.swd")
While Eof(0) = 0
AddElement(ThisLinkList())
ThisLinkList() = ReadString(0)
; Debug ThisLinkList()
Wend
CloseFile(0)
Else
MessageRequester("Information","Couldn't open SakerLank.swd file!")
EndIf
FirstTimeThru = #False
EndIf ; End of FirstTimeThru
If args\get_uri(@uri) = #S_OK
suri = PeekS(uri)
CoTaskMemFree_(uri)
Passed_suri$ = suri
; MessageRequester("CancelNavigation Or NOT" , Passed_suri$)
; If LCase(StringField(GetURLPart(suri, #PB_URL_Site), 2, ".")) = "google"
; MessageRequester("Purebasic", "Sorry google is banned.")
; args\put_Cancel(#True)
; EndIf
IfThisSiteOk(Passed_suri$)
If ThisSiteItemOk = #False
IfThisLinkOk(Passed_suri$)
EndIf
If ThisSiteItemOk = #True
Goto DontCancel
EndIf
YesCancel:
If ThisLinkItemOk = #False
; MessageRequester("NEXT STEP NAVIGATION CANCELLED " , Passed_suri$)
args\put_Cancel(#True)
EndIf
DontCancel:
EndIf
LockMutex(*this\mutex)
*browser = *this\context
UnlockMutex(*this\mutex)
EndProcedure
+
Here is what I am working on: https://sourceforge.net/projects/kidsafebrowser-us/
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 vmars316,
Like i said wv2_EventHandler_New() has changed but it's easy to adapt,
The constructor parameters have changed:
1st parameter is the event callback, second it's a context value, you can pass 0 if you don't need it. Passing the iid it's no longer needed.
You will have to change it in your code.
Events are declared as an interface:
instead of:
in the event callback you have to declare it also as an interface:
You free it through the interface:
instead of:
And that's it. Look at the examples they are all updated.
Like i said wv2_EventHandler_New() has changed but it's easy to adapt,
The constructor parameters have changed:
Code: Select all
wv2_EventHandler_New(invokeHandler.wv2_EventHandler_Invoke, context.i)
You will have to change it in your code.
Events are declared as an interface:
Code: Select all
eventNavigationCompleted.IWV2EventHandler
Code: Select all
*eventNavigationCompleted.WV2_EVENT_HANDLER
Code: Select all
Procedure wvCore_NavigationCompleted(this.IWV2EventHandler, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
EndProcedure
You free it through the interface:
Code: Select all
this\Release()
Code: Select all
wv2_EventHandler_Free(*this)
Re: Webview2 control - Chromium browser for Purebasic (Windows)
"Look at the examples they are all updated."
Incredible , Thank you very much !
Incredible , Thank you very much !
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)
Justin ,
I gotta say , I am so happy that I can Dump 'Electron' in favor of
your 'Chromium browser for Purebasic (Windows)' .
In my opinion , Purebasic is up there with the big boys now .
Is there a Donation page somewhere ?
Thanks again .
I gotta say , I am so happy that I can Dump 'Electron' in favor of
your 'Chromium browser for Purebasic (Windows)' .
In my opinion , Purebasic is up there with the big boys now .
Is there a Donation page somewhere ?
Thanks again .
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)
Done , 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)
Thank you, it helps to keep the motivation.
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Wow, best thing ever!!! You did a greate job mate! Nevertheless maybe I am too dump. But in the old Webgadget or CEF_SHARP is a possibility to save the content of a webpage. i.e. GetGadgetItemText(#BROWSER, #PB_Web_HtmlCode). Or in CEF_SHARP ... GetWebGadgetExItemText(1, #PB_Web_HtmlCode, @Output$, @ErrorOutput$)
So far I couldn't find any solution with Webview2.
Sample taken from the basic_browser_sync.pb
Maybe anyone can help? Would appreciate it. Thank you in advance.
So far I couldn't find any solution with Webview2.
Sample taken from the basic_browser_sync.pb
Code: Select all
Procedure main()
Protected.i ev
If wv2_GetBrowserVersion("") = ""
MessageRequester("Error", "MS Edge not found, install MS Edge Runtime.")
End
EndIf
app\window = OpenWindow(#PB_Any, 10, 10, 600, 400, "PBWebView2 - Basic Browser Synchronous Creation", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
SetWindowCallback(@window_Proc(), app\window)
BindEvent(#PB_Event_SizeWindow, @window_Resize())
app\wvEnvironment = wv2_CreateCoreWebView2EnvironmentWithOptionsSync("", "", #Null)
If app\wvEnvironment = 0
MessageRequester("Error", "Failed to create WebView2Environment.")
End
EndIf
Debug "Environment created"
app\wvController = wv2_Environment_CreateCoreWebView2ControllerSync(app\wvEnvironment, WindowID(app\window))
If app\wvController = 0
MessageRequester("Error", "Failed to create WebView2Controller.")
End
EndIf
Debug "Controller created"
app\wvController\get_CoreWebView2(@app\wvCore)
window_Resize()
app\wvCore\Navigate("https://duckduckgo.com/")
app\wvEnvironment\Release()
WHAT TO DO HERE TO GET HTML CONTENT TO STRING???
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
EndProcedure
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Sounds great:
WIll this add "Source Code" option to 'DropDown Menu' ?
If so I would like to add this to my work .
https://sourceforge.net/projects/kidsafebrowser-us/
Thanks
WIll this add "Source Code" option to 'DropDown Menu' ?
If so I would like to add this to my work .
https://sourceforge.net/projects/kidsafebrowser-us/
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,
in webview2 you get the html executing javascript "document.documentElement.outerHTML", there is no direct api as far as i know.
but you have to wait until the page is loaded.
One thing i forgot to say about the wv2_Core_ExecuteScriptSync() helper is that you can use it everywhere execpt in a webview2 event handler, this is because webview2 events are serialized you don't recieve a new event until the current event is consumed, if you use wv2_Core_ExecuteScriptSync() inside a webview2 event handler it will block since it waits for the script executed event and never arrives because you have not exited the current event.
But it's easy to fix, simply forward the webview2 event to the window message loop using PostEvent() and you can use wv2_Core_ExecuteScriptSync() there.
You can also pass the event arguments using the event data, but you have to add a reference to them to keep them alive args\AddRef() otherwise webview2 frees them when exiting the event.
Another option is to create a wv2_Navigate_Sync() helper that will block until the navigation is completed and then call wv2_Core_ExecuteScriptSync().
See example:
in webview2 you get the html executing javascript "document.documentElement.outerHTML", there is no direct api as far as i know.
but you have to wait until the page is loaded.
One thing i forgot to say about the wv2_Core_ExecuteScriptSync() helper is that you can use it everywhere execpt in a webview2 event handler, this is because webview2 events are serialized you don't recieve a new event until the current event is consumed, if you use wv2_Core_ExecuteScriptSync() inside a webview2 event handler it will block since it waits for the script executed event and never arrives because you have not exited the current event.
But it's easy to fix, simply forward the webview2 event to the window message loop using PostEvent() and you can use wv2_Core_ExecuteScriptSync() there.
You can also pass the event arguments using the event data, but you have to add a reference to them to keep them alive args\AddRef() otherwise webview2 frees them when exiting the event.
Another option is to create a wv2_Navigate_Sync() helper that will block until the navigation is completed and then call wv2_Core_ExecuteScriptSync().
See example:
Code: Select all
;Get HTML
IncludeFile "..\PBWebView2.pb"
EnableExplicit
;- APP_TAG
Structure APP_TAG
window.i
wvEnvironment.ICoreWebView2Environment
wvController.ICoreWebView2Controller
wvCore.ICoreWebView2
evNavigationCompleted.IWV2EventHandler
EndStructure
Global.APP_TAG app
;- DECLARES
Declare main()
Declare window_Close()
Declare window_Resize()
Declare window_ProcessEvent(ev.l)
Enumeration #PB_Event_FirstCustomValue
#WINDOW_EVENT_NAVIGATION_COMPLETED
EndEnumeration
Procedure wv_NavigationCompleted(this.IWV2EventHandler, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
Debug "Webview2 Event NavigationCompleted"
;Webview2 releases args when exiting the event, add a reference to keep them alive for using it in window_on_navigation_completed()
args\AddRef()
;Post window event, set args as event data
PostEvent(#WINDOW_EVENT_NAVIGATION_COMPLETED, app\window, 0, 0, args)
EndProcedure
Procedure window_on_navigation_completed()
Protected.i json
Protected.ICoreWebView2NavigationCompletedEventArgs args
Protected.q navId
Debug "window window_on_navigation_completed"
args = EventData()
If args
args\get_NavigationId(@navId)
Debug "Navigation ID " + Str(navId)
EndIf
json = ParseJSON(#PB_Any, wv2_Core_ExecuteScriptSync(app\wvCore, "document.documentElement.outerHTML;", #Null))
Debug "HTML:"
Debug GetJSONString(JSONValue(json))
FreeJSON(json)
If args : args\Release() : EndIf
EndProcedure
Procedure window_Proc(hwnd.i, msg.l, wparam.i, lparam.i)
Select msg
Case #WM_MOVE, #WM_MOVING
wv2_Controller_On_WM_MOVE_MOVING(app\wvController)
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure window_Close()
If app\wvController : app\wvController\Close() : EndIf
If app\wvCore : app\wvCore\Release() : EndIf
ProcedureReturn #True ;Exit message loop.
EndProcedure
Procedure window_Resize()
Protected.RECT wvBounds
If app\wvController
GetClientRect_(WindowID(app\window), @wvBounds)
wv2_Controller_put_Bounds(app\wvController, @wvBounds)
EndIf
EndProcedure
Procedure main()
Protected.i ev
If wv2_GetBrowserVersion("") = ""
MessageRequester("Error", "MS Edge not found, install MS Edge Runtime.")
End
EndIf
app\window = OpenWindow(#PB_Any, 10, 10, 600, 400, "PBWebView2 - Basic Browser Synchronous Creation", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
SetWindowCallback(@window_Proc(), app\window)
BindEvent(#PB_Event_SizeWindow, @window_Resize())
BindEvent(#WINDOW_EVENT_NAVIGATION_COMPLETED, @window_on_navigation_completed(), app\window)
app\wvEnvironment = wv2_CreateCoreWebView2EnvironmentWithOptionsSync("", "", #Null)
If app\wvEnvironment = 0
MessageRequester("Error", "Failed to create WebView2Environment.")
End
EndIf
Debug "Environment created"
app\wvController = wv2_Environment_CreateCoreWebView2ControllerSync(app\wvEnvironment, WindowID(app\window))
If app\wvController = 0
MessageRequester("Error", "Failed to create WebView2Controller.")
End
EndIf
Debug "Controller created"
app\evNavigationCompleted = wv2_EventHandler_New(@wv_NavigationCompleted(), 0)
app\wvController\get_CoreWebView2(@app\wvCore)
window_Resize()
app\wvCore\add_NavigationCompleted(app\evNavigationCompleted, #Null)
app\wvCore\Navigate("https://duckduckgo.com/")
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
app\wvEnvironment\Release()
app\evNavigationCompleted\Release()
EndProcedure
main()
Re: Webview2 control - Chromium browser for Purebasic (Windows)
Tia ,
With PureBasic 5.73 LTS (Windows - x64) ,
Is Ohm Browser x86 or x64 ?
Thanks
With PureBasic 5.73 LTS (Windows - x64) ,
Is Ohm Browser x86 or x64 ?
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)
Ohm browser and all the examples work in x86 / x64, the only thing to notice is that the corresponding WebView2Loader.dll and WebView2Loader.lib need to be used, located in the x86 and x64 folders in the project.
I don't think i will keep updating the Ohm browser, i will focus on smaller examples.
I don't think i will keep updating the Ohm browser, i will focus on smaller examples.
Re: Webview2 control - Chromium browser for Purebasic (Windows)
?
I am using Ohm's WebView2Loader.dll , is that x86 or x64 ?
Thanks
I am using Ohm's WebView2Loader.dll , is that x86 or x64 ?
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)
The one in the ohm folder is the x64 version but i think the ones in the project /x86 /x64 are more up to date, both have the same name, it is how they are shipped with the Webview SDK, the x64 is the bigger one. You should ship the x86 or x64 depending on the target machine.