Webview2 control - Chromium browser for Purebasic (Windows) [Jan 1, 2024]

Everything else that doesn't fall into one of the other PB categories.
Justin
Addict
Addict
Posts: 829
Joined: Sat Apr 26, 2003 2:49 pm

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by Justin »

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.
vmars316
Enthusiast
Enthusiast
Posts: 464
Joined: Fri Jun 29, 2012 12:24 am
Contact:

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by vmars316 »

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' .

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

+
Much Thanks to you :
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."
Justin
Addict
Addict
Posts: 829
Joined: Sat Apr 26, 2003 2:49 pm

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by Justin »

HI vmars316,

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)
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:

Code: Select all

eventNavigationCompleted.IWV2EventHandler
instead of:

Code: Select all

*eventNavigationCompleted.WV2_EVENT_HANDLER
in the event callback you have to declare it also as an interface:

Code: Select all

Procedure wvCore_NavigationCompleted(this.IWV2EventHandler, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
EndProcedure

You free it through the interface:

Code: Select all

this\Release()
instead of:

Code: Select all

wv2_EventHandler_Free(*this)
And that's it. Look at the examples they are all updated.
vmars316
Enthusiast
Enthusiast
Posts: 464
Joined: Fri Jun 29, 2012 12:24 am
Contact:

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by vmars316 »

"Look at the examples they are all updated."

Incredible , Thank you very much !
vmars.us Win11 x64 , Martin Guitar 000-16 (1995)
"All things in moderation , except for love and forgiveness."
vmars316
Enthusiast
Enthusiast
Posts: 464
Joined: Fri Jun 29, 2012 12:24 am
Contact:

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by vmars316 »

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 .
vmars.us Win11 x64 , Martin Guitar 000-16 (1995)
"All things in moderation , except for love and forgiveness."
Justin
Addict
Addict
Posts: 829
Joined: Sat Apr 26, 2003 2:49 pm

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by Justin »

Hi, there is a paypal donate button in the github page at the bottom of the Readme.md, also in my first post, or directly here:
Image
All contributions are appreciated, thank you.
vmars316
Enthusiast
Enthusiast
Posts: 464
Joined: Fri Jun 29, 2012 12:24 am
Contact:

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by vmars316 »

Done , Thanks
vmars.us Win11 x64 , Martin Guitar 000-16 (1995)
"All things in moderation , except for love and forgiveness."
Justin
Addict
Addict
Posts: 829
Joined: Sat Apr 26, 2003 2:49 pm

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by Justin »

Thank you, it helps to keep the motivation.
QuiGon
New User
New User
Posts: 1
Joined: Thu Mar 03, 2022 8:56 am

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by QuiGon »

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

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

Maybe anyone can help? Would appreciate it. Thank you in advance.
vmars316
Enthusiast
Enthusiast
Posts: 464
Joined: Fri Jun 29, 2012 12:24 am
Contact:

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by vmars316 »

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
vmars.us Win11 x64 , Martin Guitar 000-16 (1995)
"All things in moderation , except for love and forgiveness."
Justin
Addict
Addict
Posts: 829
Joined: Sat Apr 26, 2003 2:49 pm

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by Justin »

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:

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()
vmars316
Enthusiast
Enthusiast
Posts: 464
Joined: Fri Jun 29, 2012 12:24 am
Contact:

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by vmars316 »

Tia ,
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."
Justin
Addict
Addict
Posts: 829
Joined: Sat Apr 26, 2003 2:49 pm

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by Justin »

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.
vmars316
Enthusiast
Enthusiast
Posts: 464
Joined: Fri Jun 29, 2012 12:24 am
Contact:

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by vmars316 »

?

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."
Justin
Addict
Addict
Posts: 829
Joined: Sat Apr 26, 2003 2:49 pm

Re: Webview2 control - Chromium browser for Purebasic (Windows)

Post by Justin »

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.
Post Reply