Page 4 of 13

Re: Webview2 control - Chromium browser for Purebasic (Windo

Posted: Mon Apr 12, 2021 8:57 pm
by Justin
I don't think is CEF based, it's MS implementation of the Chromium browser (MS Edge) as a COM Control, it is supossed to be easier to implement in C / C++ , .NET , C# , WPF than CEF, there are also Linux and Mac versions planned.

Re: Webview2 control - Chromium browser for Purebasic (Windo

Posted: Thu Apr 15, 2021 2:03 am
by Lunasole
Justin wrote: Mon Apr 12, 2021 8:57 pm I don't think is CEF based, it's MS implementation of the Chromium browser (MS Edge) as a COM Control, it is supossed to be easier to implement in C / C++ , .NET , C# , WPF than CEF, there are also Linux and Mac versions planned.
Thanks for some brief view

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

Posted: Tue May 11, 2021 12:10 pm
by Morty
Thank you. This is awesome!

So far it works very well, but I have a big problem to place it into ContainerGadgets

I will put the WebViewControll in a Container as part of a SplitGadget in a Container. The initialization is ok, no errors, but the view isn't shown. I've tried with SetParent_ and other boundries, but it doesn't work (is not shown). To get it clear - If I put it on a single window it works as expected.

Code: Select all

ContaingerGadget1
	ListGadget
	ContainerGadget2
		CanvasGadget
		WebView2Controll
	[SpinGadget: ListGadget & ContainerGadget2]
Thanks

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

Posted: Tue May 11, 2021 2:12 pm
by Justin
Hi Morty,

Are you setting the container gadget that will host the webview in the Environment_Created event?
It should be something like this, taken from the basic_browser_async.pb example:

Code: Select all

Procedure wvEnvironment_Created(*this.WV2_EVENT_HANDLER, result.l, environment.ICoreWebView2Environment)	
	If result = #S_OK
		environment\QueryInterface(?IID_ICoreWebView2Environment, @app\wvEnvironment)
		;SET CONTAINER GADGET THAT WILL HOST WEBVIEW
		app\wvEnvironment\CreateCoreWebView2Controller(GadgetID(YOUR_GADGET_CONTAINER), wv2_EventHandler_New(?IID_ICoreWebView2CreateCoreWebView2ControllerCompletedHandler, @wvController_Created()))

		wv2_EventHandler_Release(*this)
		app\wvEnvironment\Release()

	Else
		MessageRequester("Error", "Failed to create WebView2Environment.")
		End 
	EndIf 
EndProcedure
Then you will need to resize the webview to the container dimension in wvController_Created event and everytime the container is resized.
I will test it by myself later.

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

Posted: Tue May 11, 2021 6:35 pm
by Justin
I think this code does it i need to check it with more dpi settings with another computer at home, i will update the repository later.

Edit: Fixed dpi scaling

Code: Select all

;container.pb

IncludeFile "..\PBWebView2.pb"

EnableExplicit

;- APP_TAG
Structure APP_TAG
	window.i
	splitter.i
	cont1.i
	cont2.i
	listGd.i
	canvas.i
	wvEnvironment.ICoreWebView2Environment
	wvController.ICoreWebView2Controller
	wvCore.ICoreWebView2
	*eventNavigationCompleted.WV2_EVENT_HANDLER
	*eventNavigationSarting.WV2_EVENT_HANDLER
EndStructure
Global.APP_TAG app

;- DECLARES
Declare main()

Declare window_Close()
Declare window_Resize()
Declare wv_Resize()
Declare window_ProcessEvents(ev.l)

Declare wvEnvironment_Created(*this.WV2_EVENT_HANDLER, result.l, environment.ICoreWebView2Environment)	
Declare wvController_Created(*this.WV2_EVENT_HANDLER, result.l, controller.ICoreWebView2Controller)
Declare wv_NavigationCompleted(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
Declare wv_NavigationStarting(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationStartingEventArgs)

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 wvEnvironment_Created(*this.WV2_EVENT_HANDLER, result.l, environment.ICoreWebView2Environment)	
	If result = #S_OK
		environment\QueryInterface(?IID_ICoreWebView2Environment, @app\wvEnvironment)
		app\wvEnvironment\CreateCoreWebView2Controller(GadgetID(app\cont2), wv2_EventHandler_New(?IID_ICoreWebView2CreateCoreWebView2ControllerCompletedHandler, @wvController_Created()))

		wv2_EventHandler_Release(*this)
		app\wvEnvironment\Release()

	Else
		MessageRequester("Error", "Failed to create WebView2Environment.")
		End 
	EndIf 
EndProcedure

Procedure wvController_Created(*this.WV2_EVENT_HANDLER, result.l, controller.ICoreWebView2Controller)	
	If result = #S_OK
		controller\QueryInterface(?IID_ICoreWebView2Controller, @app\wvController)
		app\wvController\get_CoreWebView2(@app\wvCore)
		
		;Setup events
		app\eventNavigationCompleted = wv2_EventHandler_New(?IID_ICoreWebView2NavigationCompletedEventHandler, @wv_NavigationCompleted())
		app\wvCore\add_NavigationCompleted(app\eventNavigationCompleted, #Null)
		
		app\eventNavigationSarting = wv2_EventHandler_New(?IID_ICoreWebView2NavigationStartingEventHandler, @wv_NavigationStarting())
		app\wvCore\add_NavigationStarting(app\eventNavigationSarting, #Null)
		
		window_Resize()
		wv_Resize()
		
		app\wvCore\Navigate("https://duckduckgo.com")

		wv2_EventHandler_Release(*this)

	Else
		MessageRequester("Error", "Failed to create WebView2Controller.")
		End
	EndIf 
EndProcedure

Procedure wv_NavigationCompleted(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
	Debug "Event NavigationCompleted"

EndProcedure

Procedure wv_NavigationStarting(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationStartingEventArgs)
	Protected.i uri
	Protected.s suri
	
	Debug "Event NavigationStarting"

	If args\get_uri(@uri) = #S_OK
		suri = PeekS(uri)
		CoTaskMemFree_(uri)

		;CANCEL NAVIGATION
		If LCase(StringField(GetURLPart(suri, #PB_URL_Site), 2, ".")) = "google"
			MessageRequester("Purebasic", "Sorry google is banned.")
			args\put_Cancel(#True)
		EndIf 
	EndIf 
EndProcedure

Procedure window_Close()
	If app\wvController
		app\wvController\Close()
		app\wvController\Release()	
	EndIf 
	
	If app\wvCore : app\wvCore\Release() : EndIf 
	
	If app\eventNavigationCompleted
		wv2_EventHandler_Release(app\eventNavigationCompleted)
	EndIf 
	
	If app\eventNavigationSarting
		wv2_EventHandler_Release(app\eventNavigationSarting)
	EndIf 
	
	ProcedureReturn #True ;Exit message loop.
EndProcedure

Procedure canvas_Draw()
	If StartDrawing(CanvasOutput(app\canvas))
		Circle(10, 10, 10, RGB(255, 0, 0))
		StopDrawing()
 	EndIf 
EndProcedure

Procedure window_Resize()		
	ResizeGadget(app\cont1, 0, 0, WindowWidth(app\window), WindowHeight(app\window))
EndProcedure

Procedure cont1_Resize()
	ResizeGadget(app\splitter, 0, 0, GadgetWidth(app\cont1), GadgetHeight(app\cont1))
EndProcedure

Procedure wv_Resize()
	Protected.RECT wvBounds

	wvBounds\left = DesktopScaledX(GadgetWidth(app\canvas))
	wvBounds\top = 0
	wvBounds\bottom = DesktopScaledY(GadgetHeight(app\cont2))
	wvBounds\right = DesktopScaledX(GadgetWidth(app\cont2))
	If app\wvController
		wv2_Controller_put_Bounds(app\wvController, @wvBounds)
	EndIf 
EndProcedure

Procedure cont2_Resize()

	ResizeGadget(app\canvas, 0, 0, #PB_Ignore, GadgetHeight(app\cont2))
	canvas_Draw()
	
	wv_Resize()
EndProcedure

Procedure window_ProcessEvents(ev.l)
	Select ev
		Case #PB_Event_CloseWindow : ProcedureReturn window_Close()
	EndSelect
	
	ProcedureReturn #False 
EndProcedure

Procedure main()
	Protected.l winWidth, winHeight, x
	
	If wv2_GetBrowserVersion("") = ""
		MessageRequester("Error", "MS Edge not found, install MS Edge runtime.")
		End 
	EndIf
	
	winWidth = 600
	winHeight = 400
	
	app\window = OpenWindow(#PB_Any, 10, 10, winWidth, winHeight, "PBWebView2 - Basic Browser Asynchronous Creation", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
	SetWindowCallback(@window_Proc(), app\window)
	
	app\cont1 = ContainerGadget(#PB_Any, 0, 0, WindowWidth(app\window), WindowHeight(app\window))
	BindGadgetEvent(app\cont1, @cont1_Resize(), #PB_EventType_Resize)
	app\listGd = ListViewGadget(#PB_Any, 0, 0, 0, 0)
	For X = 1 To 10
  	AddGadgetItem (app\listGd, -1, "Item" + Str(x))
  Next

	app\cont2 = ContainerGadget(#PB_Any, 0, 0, 0, 0)
	BindGadgetEvent(app\cont2, @cont2_Resize(), #PB_EventType_Resize)
	app\canvas = CanvasGadget(#PB_Any, 0, 0, 0, 0)
	CloseGadgetList()
	app\splitter = SplitterGadget(#PB_Any, 0, 0, 600, 400, app\listGd, app\cont2, #PB_Splitter_Separator   )
	CloseGadgetList()
	
	ResizeGadget(app\canvas, 0, 0, GadgetWidth(app\cont2) / 2, GadgetHeight(app\cont2))
	
	canvas_Draw()

	BindEvent(#PB_Event_SizeWindow, @window_Resize())
	CreateCoreWebView2EnvironmentWithOptions("", "", #Null, wv2_EventHandler_New(?IID_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, @wvEnvironment_Created()))

	Repeat
	Until window_ProcessEvents(WaitWindowEvent()) = #True 
EndProcedure

main()

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

Posted: Wed May 12, 2021 8:11 am
by Morty
Hi Justin,

thank you very much. That was realy fast. I will give it a try in the next days.

Morty

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

Posted: Thu May 13, 2021 9:56 pm
by fluent
Another question that is bothering me a little (although not important)... Would there be a way to add a custom HTTP header to each request (for both top navigation and resource loading events)? So that each request has a custom "HeaderX:ValueY" header?

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

Posted: Fri May 14, 2021 2:25 pm
by Justin
Hi fluent,

You can set custom headers handling the WebResourceRequested event, i have updated the basic_browser_async.pb example with that, not in the repository yet, look at the wv_WebResourceRequested() procedure.
You can check your headers online at:
https://headers.cloxy.net/request.php
You have to set a request filter for the requests you want to handle with core\AddWebResourceRequestedFilter() done in wvController_Created().
basic_browser_async.pb

Code: Select all

;basic_browser_async.pb

;Basic browser asyncrhonous creation.

IncludeFile "..\PBWebView2.pb"

EnableExplicit

;- APP_TAG
Structure APP_TAG
	window.i
	wvEnvironment.ICoreWebView2Environment
	wvController.ICoreWebView2Controller
	wvCore.ICoreWebView2
	*eventNavigationCompleted.WV2_EVENT_HANDLER
	*eventNavigationSarting.WV2_EVENT_HANDLER
	*eventWebResourceRequested.WV2_EVENT_HANDLER
EndStructure
Global.APP_TAG app

;- DECLARES
Declare main()

Declare window_Close()
Declare window_Resize()
Declare window_ProcessEvents(ev.l)

Declare wvEnvironment_Created(*this.WV2_EVENT_HANDLER, result.l, environment.ICoreWebView2Environment)	
Declare wvController_Created(*this.WV2_EVENT_HANDLER, result.l, controller.ICoreWebView2Controller)
Declare wv_NavigationCompleted(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
Declare wv_NavigationStarting(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationStartingEventArgs)
Declare wv_WebResourceRequested(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2WebResourceRequestedEventArgs)	

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 wvEnvironment_Created(*this.WV2_EVENT_HANDLER, result.l, environment.ICoreWebView2Environment)	
	If result = #S_OK
		environment\QueryInterface(?IID_ICoreWebView2Environment, @app\wvEnvironment)
		app\wvEnvironment\CreateCoreWebView2Controller(WindowID(app\window), wv2_EventHandler_New(?IID_ICoreWebView2CreateCoreWebView2ControllerCompletedHandler, @wvController_Created()))

		wv2_EventHandler_Release(*this)
		app\wvEnvironment\Release()

	Else
		MessageRequester("Error", "Failed to create WebView2Environment.")
		End 
	EndIf 
EndProcedure

Procedure wvController_Created(*this.WV2_EVENT_HANDLER, result.l, controller.ICoreWebView2Controller)	
	If result = #S_OK
		controller\QueryInterface(?IID_ICoreWebView2Controller, @app\wvController)
		app\wvController\get_CoreWebView2(@app\wvCore)
		
		;Setup events
		app\eventNavigationCompleted = wv2_EventHandler_New(?IID_ICoreWebView2NavigationCompletedEventHandler, @wv_NavigationCompleted())
		app\wvCore\add_NavigationCompleted(app\eventNavigationCompleted, #Null)
		
		app\eventNavigationSarting = wv2_EventHandler_New(?IID_ICoreWebView2NavigationStartingEventHandler, @wv_NavigationStarting())
		app\wvCore\add_NavigationStarting(app\eventNavigationSarting, #Null)
		
		app\wvCore\AddWebResourceRequestedFilter("*", #COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL)
		app\eventWebResourceRequested = wv2_EventHandler_New(?IID_ICoreWebView2WebResourceRequestedEventHandler, @wv_WebResourceRequested())
		app\wvCore\add_WebResourceRequested(app\eventWebResourceRequested, #Null)
		
		
		window_Resize()
		
		app\wvCore\Navigate("https://duckduckgo.com")

		wv2_EventHandler_Release(*this)

	Else
		MessageRequester("Error", "Failed to create WebView2Controller.")
		End
	EndIf 
EndProcedure

Procedure wv_WebResourceRequested(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2WebResourceRequestedEventArgs)	
	Protected.ICoreWebView2WebResourceRequest req
	Protected.ICoreWebView2HttpRequestHeaders reqHeaders
	
	;SET CUSTOM HEADER
	If args\get_Request(@req) = #S_OK
		If req\get_Headers(@reqHeaders) = #S_OK
			reqHeaders\SetHeader("myheader", "myvalue")
			
			reqHeaders\Release()
		EndIf 
		
		req\Release()
	EndIf 
EndProcedure

Procedure wv_NavigationCompleted(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
	Debug "Event NavigationCompleted"

EndProcedure

Procedure wv_NavigationStarting(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationStartingEventArgs)
	Protected.i uri
	Protected.s suri
	
	Debug "Event NavigationStarting"

	If args\get_uri(@uri) = #S_OK
		suri = PeekS(uri)
		CoTaskMemFree_(uri)

		;CANCEL NAVIGATION
		If LCase(StringField(GetURLPart(suri, #PB_URL_Site), 2, ".")) = "google"
			MessageRequester("Purebasic", "Sorry google is banned.")
			args\put_Cancel(#True)
		EndIf 
	EndIf 
EndProcedure

Procedure window_Close()
	If app\wvController
		app\wvController\Close()
		app\wvController\Release()	
	EndIf 
	
	If app\wvCore : app\wvCore\Release() : EndIf 
	
	If app\eventNavigationCompleted
		wv2_EventHandler_Release(app\eventNavigationCompleted)
	EndIf 
	
	If app\eventNavigationSarting
		wv2_EventHandler_Release(app\eventNavigationSarting)
	EndIf 
	
	If app\eventWebResourceRequested
		wv2_EventHandler_Release(app\eventWebResourceRequested)
	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 window_ProcessEvents(ev.l)
	Select ev
		Case #PB_Event_CloseWindow : ProcedureReturn window_Close()
	EndSelect
	
	ProcedureReturn #False 
EndProcedure

Procedure main()	
	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 Asynchronous Creation", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
	SetWindowCallback(@window_Proc(), app\window)

	BindEvent(#PB_Event_SizeWindow, @window_Resize())
	
	CreateCoreWebView2EnvironmentWithOptions("", "", #Null, wv2_EventHandler_New(?IID_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, @wvEnvironment_Created()))

	Repeat
	Until window_ProcessEvents(WaitWindowEvent()) = #True 
EndProcedure

main()

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

Posted: Fri May 14, 2021 6:23 pm
by fluent
That's a fantastic example justin, thanks a lot.

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

Posted: Thu Jul 08, 2021 9:04 am
by firace
About memory usage you can pass Chromium flags when creating the control
https://peter.sh/experiments/chromium-c ... -switches/,
maybe disabling some things will help, i did it in the bootstrap.pb to disable web security, see main() proc.
Hello, a small question about the bootstrap.pb example:

It seems that the "--disable-web-security" additional argument has no effect here
(the example works fine, but if I check in the task manager, the additional argument doesn't seem to be passed to the msedgewebview2.exe process command line)

Any idea why? Could there be a bug in put_AdditionalBrowserArguments, or am I missing something?

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

Posted: Thu Jul 08, 2021 9:17 pm
by Justin
Hi firace,

the argument is passed here the first process has it, the command line is very long
Image

Using Windows 10 64.
Anyways i need to update it to the last SDK, i will take a closer look.

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

Posted: Sun Jul 11, 2021 8:57 am
by firace
Thanks Justin, I will do more testing on my end. Perhaps I've messed something up in the code.

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

Posted: Tue Sep 21, 2021 12:08 pm
by CELTIC88
great work.

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

Posted: Tue Oct 05, 2021 7:35 am
by Derren
Hey,

this looks promising. Thanks for posting.

But now, over a year later, every machine (including mine) has Edge installed and the example codes still fail to run.
Does it still not work without the runtime or does the check in the code need an update?

---------------------------
Error
---------------------------
MS Edge not found, install MS Edge Runtime.
---------------------------
OK
---------------------------

Installed Edge info:
Microsoft Edge
Version 92.0.902.73 (Offizielles Build) (64-Bit)

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

Posted: Tue Oct 05, 2021 8:47 am
by Justin
You still need to install the runtime or deploy it with your app (fixed runtime version).
https://developer.microsoft.com/en-us/m ... /webview2/
I don't think this will change, but who knows.

I need to update the code to the last sdk but the examples should work.