Get the URL using WebViewGadget?

Just starting out? Need help? Post your questions and find answers here.
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Get the URL using WebViewGadget?

Post by ricardo »

Hi,

I am testing WebViewGadget.

I know that i can add some javascript CallBack and inserting some code in the page i can find the url, but supousing the user navigates himself to another page, i cant find a way to get the URL (I tried GetGadgetText but does not work) and i cant find a way to automatically add the javascript code to every new page loaded.

I know how to do it to the initial page loaded, but not how to add the javascript code in to the other ones the user navigates.

I hope i explain myself.

Any help are welcome. Thanks in advabce.
ARGENTINA WORLD CHAMPION
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: Get the URL using WebViewGadget?

Post by ricardo »

Ideally, the WebViewGadget browser would have events, so it would be easy. Even for programming a more complex GUI it is important to have the most basic events and to get when the user navigates.

So far I only find the "somewhat dirty" option of using javascript's "beforeunload" to know that the user will navigate and maybe a timer (that's the dirty part) to know when the new page is loading or has already loaded.

I don't know if there is a solution within PureBasic to detect events or something similar.
ARGENTINA WORLD CHAMPION
User avatar
idle
Always Here
Always Here
Posts: 5834
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Get the URL using WebViewGadget?

Post by idle »

use atomic web server, see single_server_localhost.pb
https://www.purebasic.fr/english/viewtopic.php?t=83780

the TLS and packer are optional
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: Get the URL using WebViewGadget?

Post by ricardo »

idle wrote: Wed Aug 07, 2024 12:10 am use atomic web server, see single_server_localhost.pb
https://www.purebasic.fr/english/viewtopic.php?t=83780

the TLS and packer are optional
Thanks but that can add a lot of complication if the user has to run a server on his computer, just so I can know when he is browsing.
ARGENTINA WORLD CHAMPION
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: Get the URL using WebViewGadget?

Post by ricardo »

Finally i'm using javascript and a timer, its working fine now.
ARGENTINA WORLD CHAMPION
User avatar
jacdelad
Addict
Addict
Posts: 1991
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Get the URL using WebViewGadget?

Post by jacdelad »

ricardo wrote: Wed Aug 07, 2024 5:15 am Finally i'm using javascript and a timer, its working fine now.
Can someone tell me how to do this? I just need to know where the user navigated.

Edit: I found out that the WebGadget is already enough for my program. But the question still remains, somehow.
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
infratec
Always Here
Always Here
Posts: 7575
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Get the URL using WebViewGadget?

Post by infratec »

Why not using the example from the help:

Code: Select all

Procedure NavigationCallback(Gadget, Url$)
  
  Debug Url$
  
  ProcedureReturn #True 
  
EndProcedure 

If OpenWindow(0, 0, 0, 600, 300, "WebGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
  WebGadget(0, 10, 10, 580, 280, "https://www.purebasic.com") 
  SetGadgetAttribute(0, #PB_Web_NavigationCallback, @NavigationCallback())
  Repeat 
  Until WaitWindowEvent() = #PB_Event_CloseWindow 
EndIf
Select the menu of the side and change, for example, to the news page.
User avatar
jacdelad
Addict
Addict
Posts: 1991
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Get the URL using WebViewGadget?

Post by jacdelad »

Because it's a WebViewGadget? I meant the question still remains for the WebViewGadget, not the WebGadget, I already got that working (using the example from the help :mrgreen: ).
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
infratec
Always Here
Always Here
Posts: 7575
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Get the URL using WebViewGadget?

Post by infratec »

With the tools provided by Justin:

Code: Select all

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf

XIncludeFile "WebView2_Helper.pb"



Procedure.i WebView2GadgetNavigationStarting(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationStartingEventArgs)
  
  Protected *uri, *NavUri
  
;   Debug "WebView2GadgetNavigationStarting with gadget: " + Str(*this\context)
  If args\get_uri(@*uri) = #S_OK
;     Debug PeekS(*uri)
    *NavUri = UTF8(PeekS(*uri))
    CoTaskMemFree_(*uri)
    PostEvent(#PB_Event_Gadget, 0, *this\context, #PB_EventType_Change, *NavUri)
  EndIf
  
  ProcedureReturn #S_OK
  
EndProcedure



Procedure.i WebView2GadgetNavigationCompleted(*this.WV2_EVENT_HANDLER, sender.ICoreWebView2, args.ICoreWebView2NavigationCompletedEventArgs)
  
;   Debug "WebView2GadgetNavigationCompleted with gadget: " + Str(*this\context)
  
  PostEvent(#PB_Event_Gadget, 0, *this\context, #PB_EventType_StatusChange)
  
  ProcedureReturn #S_OK
  
EndProcedure



Procedure.i WebViewSetNavigationCallbacks(WebViewGadget)
  
  Protected Result
  Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
  Static *eventNavigationCompleted, *eventNavigationStarting
  
  If IsGadget(WebViewGadget)
    If GadgetType(WebViewGadget) = #PB_GadgetType_WebView
      
      Controller = GetGadgetAttribute(WebViewGadget, #PB_WebView_ICoreController)
      If Controller
        
        If Controller\get_CoreWebView2(@Core) = #S_OK
          
          *eventNavigationStarting = wv2_EventHandler_New(@WebView2GadgetNavigationStarting(), WebViewGadget)
          If *eventNavigationStarting
            If Core\add_NavigationStarting(*eventNavigationStarting, #Null) = #S_OK
              
              *eventNavigationCompleted = wv2_EventHandler_New(@WebView2GadgetNavigationCompleted(), WebViewGadget)
              If *eventNavigationCompleted
                If Core\add_NavigationCompleted(*eventNavigationCompleted, #Null) = #S_OK
                  Result = #True
                EndIf
              EndIf
              
            EndIf
          EndIf
          
        EndIf
        
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


CompilerIf #PB_Compiler_IsMainFile
  
  Define.i Event
  Define *UTF8Url
  
  OpenWindow(0, 0, 0, 800, 600, "Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  WebViewGadget(1, 0, 0, 800, 600)
  SetGadgetText(1, "https://www.purebasic.fr")
  
  If WebViewSetNavigationCallbacks(1)
    Debug "Navigation callbacks set"
  EndIf
  
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget
        If EventGadget() = 1
          Select EventType()
            Case #PB_EventType_Change
              *UTF8Url = EventData()
              Debug "Main loop navigation starting to " + PeekS(*UTF8Url, -1, #PB_UTF8)
              FreeMemory(*UTF8Url)
            Case #PB_EventType_StatusChange
              Debug "Main loop navigation completed"
          EndSelect         
        EndIf
    EndSelect
  Until Event = #PB_Event_CloseWindow
  
CompilerEndIf
Output:
Navigation callbacks set
Main loop navigation starting to https://www.purebasic.fr/
Main loop navigation completed
Main loop navigation starting to https://www.purebasic.com/french/
Main loop navigation completed
You can find the needed pbi here:
viewtopic.php?t=75898

Or in my PBWebView2 zip file:
PBWebView2 & WebView2Gadget

Unfortunately you can not get the uri in NavigationCompleted.
Last edited by infratec on Sat Sep 21, 2024 5:40 pm, edited 3 times in total.
User avatar
jacdelad
Addict
Addict
Posts: 1991
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Get the URL using WebViewGadget?

Post by jacdelad »

THanks for that. This is more complicated than I thought...
...I'll try to get it working.
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
infratec
Always Here
Always Here
Posts: 7575
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Get the URL using WebViewGadget?

Post by infratec »

Updated the listing above to make use of the PostEvents() and get the URL in the main loop.
infratec
Always Here
Always Here
Posts: 7575
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Get the URL using WebViewGadget?

Post by infratec »

I commented out in WebView2_Helper.pb:

XIncludeFile "WebView2Loader.pbi"

and from
Procedure wv2_CreateCoreWebView2EnvironmentWithOptionsSync()

to the end of the file.

But I was to lazy to implement all object stuff from scratch. :oops:
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Get the URL using WebViewGadget?

Post by breeze4me »

You can also implement ICoreWebView2NavigationCompletedEventHandler as shown below.

Code: Select all

;----------------------------------------------------------------------------------------
; https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/navigation-events

DataSection
  IID_IUnknown:
  Data.l $00000000
  Data.w $0000, $0000
  Data.b $C0, $00, $00, $00, $00, $00, $00, $46
EndDataSection

Structure STRUC_IUnknownBase
  *pVtbl
  *pQueryInterface
  *pAddRef
  *pRelease
  *pInvoke
  
  lRefCount.l
  Token.q
EndStructure

Structure STRUC_ICoreWebView2NavigationCompletedEventHandler Extends STRUC_IUnknownBase
  *pFunction
EndStructure

Global NewMap *NavigationCompletedEventHandler.STRUC_ICoreWebView2NavigationCompletedEventHandler()

Procedure.l ICoreWebView2NavigationCompletedEventHandler_QueryInterface(*this.STRUC_IUnknownBase, *riid.IID, *ppvObject.Integer)
  If *ppvObject And *riid
    If CompareMemory(*riid, ?IID_IUnknown, SizeOf(IID))
      *this\lRefCount + 1
      *ppvObject\i = *this
    Else
      *ppvObject\i = 0
      ProcedureReturn #E_NOINTERFACE
    EndIf
  Else
    ProcedureReturn #E_POINTER
  EndIf
  ProcedureReturn #S_OK
EndProcedure

Procedure.l ICoreWebView2NavigationCompletedEventHandler_AddRef(*this.STRUC_IUnknownBase)
  *this\lRefCount + 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2NavigationCompletedEventHandler_Release(*this.STRUC_IUnknownBase)
  *this\lRefCount - 1
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2NavigationCompletedEventHandler_Invoke(*this.STRUC_ICoreWebView2NavigationCompletedEventHandler, *sender.ICoreWebView2, *args.ICoreWebView2NavigationCompletedEventArgs)
  Protected isSuccess, *uri, uri.s
  
  If *args And *args\get_IsSuccess(@isSuccess) = #S_OK And isSuccess
    If *sender
      If *sender\get_Source(@*uri) = #S_OK
        If *uri
          uri = PeekS(*uri)
          If *this\pFunction
            CallFunctionFast(*this\pFunction, @uri)
          EndIf
          CoTaskMemFree_(*uri)
        EndIf
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn #S_OK
EndProcedure

Procedure SetNavigateCompleteFunc(WebView, *function)
  Protected Result
  Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
  Protected *NavigationCompletedEventHandler.STRUC_ICoreWebView2NavigationCompletedEventHandler
  Protected Token.q
  
  If GadgetType(WebView) <> #PB_GadgetType_WebView Or *function = 0 : ProcedureReturn 0 : EndIf
  
  Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
  If Controller = 0 : ProcedureReturn 0 : EndIf
  
  If Controller\get_CoreWebView2(@Core) <> #S_OK Or Core = 0 : ProcedureReturn 0 : EndIf
  
  If FindMapElement(*NavigationCompletedEventHandler(), Str(WebView))
    If *NavigationCompletedEventHandler()
      If *NavigationCompletedEventHandler()\Token
        Core\remove_NavigationCompleted(*NavigationCompletedEventHandler()\Token)
      EndIf
      FreeMemory(*NavigationCompletedEventHandler())
    EndIf
    DeleteMapElement(*NavigationCompletedEventHandler())
  EndIf
  
  If AddMapElement(*NavigationCompletedEventHandler(), Str(WebView)) = 0 : Goto Proc_Exit : EndIf
  
  *NavigationCompletedEventHandler = AllocateMemory(SizeOf(STRUC_ICoreWebView2NavigationCompletedEventHandler))
  If *NavigationCompletedEventHandler = 0 : Goto Proc_Exit : EndIf
  
  With *NavigationCompletedEventHandler
    \pVtbl = *NavigationCompletedEventHandler + OffsetOf(STRUC_IUnknownBase\pQueryInterface)
    \pQueryInterface = @ICoreWebView2NavigationCompletedEventHandler_QueryInterface()
    \pAddRef         = @ICoreWebView2NavigationCompletedEventHandler_AddRef()
    \pRelease        = @ICoreWebView2NavigationCompletedEventHandler_Release()
    \pInvoke         = @ICoreWebView2NavigationCompletedEventHandler_Invoke()
    
    \pFunction = *function
  EndWith
  
  If Core\add_NavigationCompleted(*NavigationCompletedEventHandler, @*NavigationCompletedEventHandler\Token) <> #S_OK : Goto Proc_Exit : EndIf
  
  ;Debug *NavigationCompletedEventHandler\Token
  
  *NavigationCompletedEventHandler() = *NavigationCompletedEventHandler
  
  Result = 1
  
  Proc_Exit:
  If Result = 0
    If *NavigationCompletedEventHandler
      If *NavigationCompletedEventHandler\Token And Core
        Core\remove_NavigationCompleted(*NavigationCompletedEventHandler\Token)
      EndIf
      FreeMemory(*NavigationCompletedEventHandler)
    EndIf
    If FindMapElement(*NavigationCompletedEventHandler(), Str(WebView))
      If *NavigationCompletedEventHandler() <> 0 And *NavigationCompletedEventHandler() <> *NavigationCompletedEventHandler
        FreeMemory(*NavigationCompletedEventHandler())
      EndIf
      DeleteMapElement(*NavigationCompletedEventHandler())
    EndIf
  EndIf
  If Core : Core\Release() : EndIf
  
  ProcedureReturn Result
EndProcedure

;----------------------------------------------------------------------------------------


Procedure NaviComplete(uri.s)
  Debug uri
EndProcedure


OpenWindow(0, 0, 0, 1000, 900, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

StringGadget(0, 0, 0, 400, 30, "https://www.purebasic.com")
ButtonGadget(1, 410, 0, 50, 30, "Go")
WebViewGadget(2, 0, 35, 1000, 900)

SetNavigateCompleteFunc(2, @NaviComplete())

SetGadgetText(2, "file://" + #PB_Compiler_Home + "examples/sources/Data/WebView/webview.html")

Repeat 
  Event = WaitWindowEvent()
  If Event = #PB_Event_Gadget
    If EventGadget() = 1
      SetGadgetText(2, Trim(GetGadgetText(0)))
    EndIf
  EndIf
Until Event = #PB_Event_CloseWindow

ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: Get the URL using WebViewGadget?

Post by ricardo »

breeze4me wrote: Sat Sep 21, 2024 6:10 pm You can also implement ICoreWebView2NavigationCompletedEventHandler as shown below.
Great.

Thanks !!
ARGENTINA WORLD CHAMPION
Post Reply