Page 1 of 1

[Resolved] Focus WebViewGadget() error

Posted: Tue Feb 03, 2026 10:20 am
by falsam
[PB 6.30 (x64)]

Hello @Alls

Bug or no bug? That is the question.

I have an application that allows me to enter HTML/CSS/JavaScript code into a Scintilla gadget and see the result in a WebViewGadget().

I switch from code to result using the F5 key and vice versa from result to code using the Esc key.

➡️ This works fine as long as I don't click on the WebViewGadget().

➡️ When I click on the WebViewGadget(), the application appears to freeze, but this is not the case because I can close the application.

➡️ I need Windows & MacOS compatibility.

Here is a minimal code snippet that reproduces this behavior.

Code: Select all

EnableExplicit

Enumeration window
  #app
EndEnumeration

Enumeration gadgets
  #editor
  #webView
EndEnumeration

Enumeration menu
  #viewCode
  #viewResult  
EndEnumeration

Declare scintillaCallBack(gadget, *scn.scNotification)
Declare viewCode()
Declare viewResult()

OpenWindow(#app, 0, 0, 800, 600, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

; ESC - Voir code
AddKeyboardShortcut(#app, #PB_Shortcut_Escape, #viewCode)

; F5 - Visualiser le résultat
AddKeyboardShortcut(#app, #PB_Shortcut_F5, #viewResult)

; Editeur Scintilla gadget associé à un callback 
ScintillaGadget(#editor, 10, 10, 780, 580, @scintillaCallBack())

; Visualisation du résultat
WebViewGadget(#webView, 10, 10, 780, 580, #PB_WebView_Debug)
HideGadget(#webView, #True)

; Positionner le curseur de saisie dans l'éditeur
SetActiveGadget(#editor)

; Déclencheurs
BindEvent(#PB_Event_Menu, @viewCode(), #app, #viewCode)
BindEvent(#PB_Event_Menu, @viewResult(), #app, #viewResult)

; Boucle évenementielle
Repeat : Until WaitWindowEvent(1) = #PB_Event_CloseWindow

; Callback evenementielle du gadget scintilla
Procedure scintillaCallBack(gadget, *scn.scNotification)
  ; Analyser les evenement scintilla
  Select *scn\nmhdr\code
    Case #SCN_CHARADDED 
    Case #SCN_UPDATEUI  
    Case #SCN_MARGINCLICK
  EndSelect
EndProcedure

; Basculement Code / Résultat 
Procedure viewCode()
  Debug "viewCode()"
  HideGadget(#editor, #False)
  HideGadget(#webView, #True)  
  SetActiveGadget(#editor)
EndProcedure

Procedure viewResult()
  Debug "viewResult()"
  HideGadget(#editor, #True)
  HideGadget(#webView, #False)
EndProcedure
I hope you will be able to help me. Thank you 🌞

Re: Focus WebViewGadget() error

Posted: Tue Feb 03, 2026 11:59 am
by breeze4me
Since the WebView gadget intercepts keyboard shortcut inputs, you must handle it as shown below.

Code: Select all

EnableExplicit

Enumeration window
  #app
EndEnumeration

Enumeration gadgets
  #editor
  #webView
EndEnumeration

Enumeration menu
  #viewCode
  #viewResult  
EndEnumeration

Declare scintillaCallBack(gadget, *scn.scNotification)
Declare viewCode()
Declare viewResult()


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

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

Procedure.l ICoreWebView2AcceleratorKeyPressedEventHandler_QueryInterface(*this._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 ICoreWebView2AcceleratorKeyPressedEventHandler_AddRef(*this._IUnknownBase)
  *this\lRefCount + 1
  ;Debug #PB_Compiler_Procedure + " " + *this\lRefCount
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2AcceleratorKeyPressedEventHandler_Release(*this._IUnknownBase)
  *this\lRefCount - 1
  ;Debug #PB_Compiler_Procedure + " " + *this\lRefCount
  
  If *this\lRefCount <= 0
    FreeMemory(*this)
    ProcedureReturn 0
  EndIf
  
  ProcedureReturn *this\lRefCount
EndProcedure

Procedure.l ICoreWebView2AcceleratorKeyPressedEventHandler_Invoke(*this._IUnknownBase, *sender.ICoreWebView2Controller, *args.ICoreWebView2AcceleratorKeyPressedEventArgs)
  Protected EventKind, VKey.l
  
  If *args And *args\get_KeyEventKind(@EventKind) = #S_OK
    If EventKind = #COREWEBVIEW2_KEY_EVENT_KIND_KEY_DOWN
      If *args\get_VirtualKey(@VKey) = #S_OK And VKey = #VK_ESCAPE
        *args\put_Handled(#True)
        PostEvent(#PB_Event_Menu, #app, #viewCode)
      EndIf
    EndIf
  EndIf
  
  ProcedureReturn #S_OK
EndProcedure

Procedure SetAcceleratorKeyPressedEvent(WebView)
  Protected Result
  Protected Controller.ICoreWebView2Controller
  Protected *ICoreWebView2AcceleratorKeyPressedEventHandler._IUnknownBase
  Protected Token.q
  
  If GadgetType(WebView) <> #PB_GadgetType_WebView : ProcedureReturn 0 : EndIf
  
  Controller = GetGadgetAttribute(WebView, #PB_WebView_ICoreController)
  If Controller = 0 : ProcedureReturn 0 : EndIf
  
  *ICoreWebView2AcceleratorKeyPressedEventHandler = AllocateMemory(SizeOf(_IUnknownBase))
  If *ICoreWebView2AcceleratorKeyPressedEventHandler = 0 : Goto Proc_Exit : EndIf
  
  With *ICoreWebView2AcceleratorKeyPressedEventHandler
    \pVtbl = *ICoreWebView2AcceleratorKeyPressedEventHandler + OffsetOf(_IUnknownBase\pQueryInterface)
    \pQueryInterface = @ICoreWebView2AcceleratorKeyPressedEventHandler_QueryInterface()
    \pAddRef         = @ICoreWebView2AcceleratorKeyPressedEventHandler_AddRef()
    \pRelease        = @ICoreWebView2AcceleratorKeyPressedEventHandler_Release()
    \pInvoke         = @ICoreWebView2AcceleratorKeyPressedEventHandler_Invoke()
  EndWith
  
  If Controller\add_AcceleratorKeyPressed(*ICoreWebView2AcceleratorKeyPressedEventHandler, @Token) <> #S_OK : Goto Proc_Exit : EndIf
  
  ;Debug Token
  *ICoreWebView2AcceleratorKeyPressedEventHandler\Token = Token
  
  Result = 1
  
  Proc_Exit:
  If Result = 0
    If *ICoreWebView2AcceleratorKeyPressedEventHandler
      If *ICoreWebView2AcceleratorKeyPressedEventHandler\Token And Controller
        Controller\remove_AcceleratorKeyPressed(*ICoreWebView2AcceleratorKeyPressedEventHandler\Token)
      EndIf
      FreeMemory(*ICoreWebView2AcceleratorKeyPressedEventHandler)
    EndIf
  EndIf
  
  ProcedureReturn Result
EndProcedure
;----------------------------------------------------------------------------------------

OpenWindow(#app, 0, 0, 800, 600, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

; ESC - Voir code
AddKeyboardShortcut(#app, #PB_Shortcut_Escape, #viewCode)

; F5 - Visualiser le résultat
AddKeyboardShortcut(#app, #PB_Shortcut_F5, #viewResult)

; Editeur Scintilla gadget associé à un callback 
ScintillaGadget(#editor, 10, 10, 780, 580, @scintillaCallBack())

; Visualisation du résultat
WebViewGadget(#webView, 10, 10, 780, 580, #PB_WebView_Debug)
HideGadget(#webView, #True)

SetAcceleratorKeyPressedEvent(#webView)

; Positionner le curseur de saisie dans l'éditeur
SetActiveGadget(#editor)

; Déclencheurs
BindEvent(#PB_Event_Menu, @viewCode(), #app, #viewCode)
BindEvent(#PB_Event_Menu, @viewResult(), #app, #viewResult)

; Boucle évenementielle
Repeat : Until WaitWindowEvent(1) = #PB_Event_CloseWindow

; Callback evenementielle du gadget scintilla
Procedure scintillaCallBack(gadget, *scn.scNotification)
  ; Analyser les evenement scintilla
  Select *scn\nmhdr\code
    Case #SCN_CHARADDED 
    Case #SCN_UPDATEUI  
    Case #SCN_MARGINCLICK
  EndSelect
EndProcedure

; Basculement Code / Résultat 
Procedure viewCode()
  Debug "viewCode()"
  HideGadget(#editor, #False)
  HideGadget(#webView, #True)  
  SetActiveGadget(#editor)
EndProcedure

Procedure viewResult()
  Debug "viewResult()"
  HideGadget(#editor, #True)
  HideGadget(#webView, #False)
EndProcedure

Re: Focus WebViewGadget() error

Posted: Tue Feb 03, 2026 12:08 pm
by falsam
Thank you very much for this solution.
I'll try to figure it out.
Will this solution also work on macOS?

Re: Focus WebViewGadget() error

Posted: Tue Feb 03, 2026 12:13 pm
by breeze4me
Unfortunately, Windows only.

Re: Focus WebViewGadget() error

Posted: Tue Feb 03, 2026 1:03 pm
by infratec
If you only want to show the result:

Code: Select all

; Visualisation du résultat
WebViewGadget(#webView, 10, 10, 780, 580, #PB_WebView_Debug)
DisableGadget(#webView, #True)
HideGadget(#webView, #True)

Re: Focus WebViewGadget() error

Posted: Tue Feb 03, 2026 1:26 pm
by falsam
Yes, but it is no longer possible to interact with the elements on the page. Thank you 😉

Re: Focus WebViewGadget() error

Posted: Tue Feb 03, 2026 9:39 pm
by infratec
Try this:

Code: Select all

EnableExplicit

Enumeration window
  #app
EndEnumeration

Enumeration gadgets
  #editor
  #webView
EndEnumeration

Enumeration menu
  #viewCode
  #viewResult  
EndEnumeration

Declare scintillaCallBack(gadget, *scn.scNotification)
Declare viewCode()
Declare viewResult()


Procedure.i escapeJS(JsonParameters$)
  Debug "escapeJS"
  
  viewCode()
  ProcedureReturn #Null
EndProcedure


Define *Text

OpenWindow(#app, 0, 0, 800, 600, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

; ESC - Voir code
AddKeyboardShortcut(#app, #PB_Shortcut_Escape, #viewCode)

; F5 - Visualiser le résultat
AddKeyboardShortcut(#app, #PB_Shortcut_F5, #viewResult)

; Editeur Scintilla gadget associé à un callback 
ScintillaGadget(#editor, 10, 10, 780, 580, @scintillaCallBack())

; Visualisation du résultat
WebViewGadget(#webView, 10, 10, 780, 580, #PB_WebView_Debug)
HideGadget(#webView, #True)

; Positionner le curseur de saisie dans l'éditeur
SetActiveGadget(#editor)
*Text=UTF8("<html><head></head><body><h1>Hello world!</h1></body></html>")
ScintillaSendMessage(#editor, #SCI_SETTEXT, 0, *Text)
FreeMemory(*Text)

; Déclencheurs
BindEvent(#PB_Event_Menu, @viewCode(), #app, #viewCode)
BindEvent(#PB_Event_Menu, @viewResult(), #app, #viewResult)

BindWebViewCallback(#webView, "escapePB", @escapeJS())

; Boucle évenementielle
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

; Callback evenementielle du gadget scintilla
Procedure scintillaCallBack(gadget, *scn.scNotification)
  ; Analyser les evenement scintilla
  Select *scn\nmhdr\code
    Case #SCN_CHARADDED 
    Case #SCN_UPDATEUI  
    Case #SCN_MARGINCLICK
  EndSelect
EndProcedure

; Basculement Code / Résultat 
Procedure viewCode()
  Debug "viewCode()"
  HideGadget(#editor, #False)
  HideGadget(#webView, #True)  
  SetActiveGadget(#editor)
EndProcedure

Procedure viewResult()
  
  Protected Inject$
  
  
  Inject$ = "<script>"
  Inject$ + " document.addEventListener('keydown', function(event) {"
  Inject$ + "  if (event.key === 'Escape') {"
  Inject$ + "   console.log('Escape key was pressed!');"
  Inject$ + "   window.escapePB('test');"
  Inject$ + "  }"
  Inject$ + " })"  
  Inject$ + "</script>"
  
  Debug "viewResult()"
  SetGadgetItemText(#webView, #PB_WebView_HtmlCode, Inject$ + GetGadgetText(#editor))
  HideGadget(#editor, #True)
  HideGadget(#webView, #False)
EndProcedure

Re: Focus WebViewGadget() error

Posted: Tue Feb 03, 2026 10:20 pm
by falsam
Nice workaround ! Thank you for this contribution Infratec 👍