Skip to content

Commit 04e5d58

Browse files
authored
Merge branch 'ioa747:main' into patch-1
2 parents d67f2bd + 7edb27e commit 04e5d58

3 files changed

Lines changed: 188 additions & 0 deletions

File tree

Doc/📜 JavaScript Scraping Cheat Sheet.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,13 @@ rows.forEach(row => {
6161
window.chrome.webview.postMessage(results.join('\n'));
6262
```
6363

64+
```
65+
// Wait for a specific element to appear before scraping
66+
new MutationObserver((mutations, observer) => {
67+
let el = document.querySelector('.target-data');
68+
if (el) {
69+
window.chrome.webview.postMessage("DATA_READY:" + el.innerText);
70+
observer.disconnect();
71+
}
72+
}).observe(document.body, { childList: true, subtree: true });
73+
```

Doc/🪽 Volatile_Usage.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# The Volatile Keyword in NetWebView2Lib
2+
3+
In **NetWebView2Lib**, callback functions such as `JS_Events_OnMessageReceived` and `OnBasicAuthenticationRequested` **must** be declared using the `Volatile` qualifier. This is a technical requirement for reliable interaction between AutoIt and the WebView2 runtime.
4+
5+
## What `Volatile` Does
6+
7+
The `Volatile` keyword enables **re-entrant execution**.
8+
9+
- **With Volatile:** While a function is running, AutoIt continues to process its internal message loop, including GUI and COM events.
10+
11+
- **Without Volatile:** AutoIt pauses message processing until the function returns.
12+
13+
14+
## Why It Is Required
15+
16+
### 1. Continuous Message Processing
17+
18+
WebView2 communicates with AutoIt through COM events. If AutoIt stops processing messages while handling a callback, incoming events may be delayed or blocked. Declaring the function as `Volatile` ensures that message handling continues during execution, preventing the interface from becoming unresponsive.
19+
20+
### 2. Synchronous COM Callbacks
21+
22+
WebView2 event handlers are invoked through **synchronous COM calls**. This means the WebView2 process waits for AutoIt to finish executing the callback before continuing. If AutoIt is busy (e.g., during GUI interaction like moving the window), the WebView2 process may stall. Using `Volatile` allows the callback to execute without interrupting message handling.
23+
24+
### 3. Deadlock Prevention
25+
26+
Because AutoIt and WebView2 run in separate processes, improper message handling can lead to deadlocks.
27+
28+
> **Deadlock Scenario:**
29+
> 1. WebView2 triggers a callback and waits for AutoIt to return.
30+
> 2. AutoIt is blocked (e.g. by a system menu or moving the GUI) and is not processing messages.
31+
> 3. Neither process can continue, resulting in a frozen application.
32+
33+
Declaring callbacks as `Volatile` prevents this by allowing AutoIt to remain responsive.
34+
35+
## Rule of Thumb
36+
37+
**All functions used as WebView2 event handlers MUST be declared Volatile.**
38+
39+
**Example**
40+
41+
```AutoIt
42+
; WebView2 callback must be declared as Volatile
43+
Volatile Func JS_Events_OnMessageReceived($oWebV2M, $hGUI, $sMessage)
44+
; Handle message from WebView2
45+
ConsoleWrite("Message received: " & $sMessage & @CRLF)
46+
EndFunc
47+
```
48+
49+
---
50+
51+
## Object Cleanup & Memory Management in Callbacks
52+
53+
When working with **Volatile** functions in `NetWebView2Lib`, AutoIt often receives COM objects as arguments (like `$oArgs` or `$oFrame`) directly from the WebView2 engine. To ensure high performance and stability, it is highly recommended to explicitly release these references before the function returns.
54+
55+
### Why zero out objects in Volatile functions?
56+
57+
1. **Immediate Reference Release:** COM objects use **Reference Counting**. As long as AutoIt holds a reference to an object in a variable, that object stays alive in memory. By setting `$oObject = 0`, you decrement this count immediately.
58+
59+
2. **Preventing Memory Leaks:** WebView2 events can fire hundreds of times (e.g., during navigation or frame changes). If these references are not cleared, your script's RAM usage will grow unnecessarily over time.
60+
61+
3. **Process Sync:** Since WebView2 is an external Chromium process, clearing the reference in AutoIt tells the engine that you are done with that specific resource, allowing it to clean up its own internal memory.
62+
63+
64+
### Implementation Example
65+
66+
In every **Volatile** event handler, make it a habit to nullify any object received as a parameter at the end of the code block.
67+
68+
69+
```AutoIt
70+
; Example: Handling a new frame creation
71+
Volatile Func NetWebView2_Events_OnFrameCreated($oWebV2M, $hGUI, $oFrame)
72+
Local Const $s_Prefix = "[EVENT: OnFrameCreated]: WebV2M: " & VarGetType($oWebV2M) & " GUI: " & $hGUI & " Frame: " & VarGetType($oFrame)
73+
74+
; Perform your logic here
75+
__NetWebView2_Log(@ScriptLineNumber, $s_Prefix, 1)
76+
77+
; --- Performance Tip ---
78+
; Manually release the object reference to help AutoIt's memory management
79+
$oFrame = 0
80+
EndFunc ;==>NetWebView2_Events_OnFrameCreated
81+
```
82+
83+
84+
>[!TIP]
85+
This practice is especially important for the `$oArgs` object in events like `OnWebMessageReceived` or `OnNavigationCompleted`. Even though AutoIt will eventually clear local variables when the function exits, setting them to `0` manually is an "active" safeguard against memory fragmentation in high-frequency events.
86+
87+
88+
---

examples/021-ModernSidebarUI.au3

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
; https://github.com/ioa747/NetWebView2Lib/blob/main/examples/021-ModernSidebarUI.au3
2+
;----------------------------------------------------------------------------------------
3+
; Title...........: 021-ModernSidebarUI.au3
4+
; Description.....: Injects a high-performance, Chromium-based Sidebar into a Win32 GUI using WebView2.
5+
; This method bypasses GDI/Win32 rendering limitations, allowing for full CSS3 animations,
6+
; Vector (SVG) icons, and 100% Color Emoji support.
7+
; AutoIt Version..: 3.3.18.0 Author: ioa747 Script Version: 0.1
8+
; Note............: Testet in Windows 11 Pro 25H2
9+
;----------------------------------------------------------------------------------------
10+
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
11+
#include <GUIConstantsEx.au3>
12+
#include <WindowsConstants.au3>
13+
#include "..\NetWebView2Lib.au3"
14+
15+
; 021-ModernSidebarUI.au3
16+
17+
Global $g_idMemo
18+
19+
_Example()
20+
21+
;---------------------------------------------------------------------------------------
22+
Func _Example()
23+
Local $hGui = GUICreate("Modern Sidebar UI", 550, 410)
24+
GUISetBkColor(0x252526) ; Dark Background
25+
26+
$g_idMemo = GUICtrlCreateEdit("", 160, 10, 370, 390, $WS_VSCROLL, 0)
27+
GUICtrlSetFont(-1, 11, 400, 0, "Courier New")
28+
GUICtrlSetColor(-1, 0xF0F0F0)
29+
GUICtrlSetBkColor(-1, 0x333333)
30+
31+
; We create ONE WebView2 for the entire sidebar
32+
Local $oWebV2M = _NetWebView2_CreateManager()
33+
Local $oBridge = _NetWebView2_GetBridge($oWebV2M, "JS_Events_")
34+
35+
; Initialize on the left side (0, 0, 140, 410)
36+
_NetWebView2_Initialize($oWebV2M, $hGui, @ScriptDir & "\UserData", 0, 0, 140, 410, True)
37+
38+
; Constructing the HTML with all the buttons
39+
Local $sHTML = _GenerateSidebarHTML()
40+
_NetWebView2_NavigateToString($oWebV2M, $sHTML)
41+
42+
GUISetState(@SW_SHOW)
43+
44+
While 1
45+
Switch GUIGetMsg()
46+
Case $GUI_EVENT_CLOSE
47+
ExitLoop
48+
EndSwitch
49+
WEnd
50+
51+
_NetWebView2_CleanUp($oWebV2M, $oBridge)
52+
EndFunc ;==>_Example
53+
;---------------------------------------------------------------------------------------
54+
Func _GenerateSidebarHTML() ; The function that creates the "Menu"
55+
Local $sCSS = "body { margin: 0; background: #252526; font-family: 'Segoe UI', sans-serif; overflow: hidden; padding: 10px; }" & _
56+
".btn { " & _
57+
" width: 100%; padding: 12px; margin-bottom: 8px; border: none; border-radius: 6px; " & _
58+
" background: #333; color: white; text-align: left; cursor: pointer; font-size: 15px; " & _
59+
" transition: 0.2s; display: flex; align-items: center; " & _
60+
"} " & _
61+
".btn:hover { background: #444; transform: translateX(5px); } " & _
62+
".btn span { margin-right: 10px; font-size: 18px; }"
63+
64+
Local $sHTML = "<html><head><style>" & $sCSS & "</style></head><body>"
65+
66+
Local $aLabels[7] = ["🏆 Trophy", "🎯 Target", "⚠️ Warning", "😎 Cool", "👉 Select", "🌏 World", "🚧 Work"]
67+
68+
For $i = 0 To 6
69+
$sHTML &= "<button class='btn' onclick='window.chrome.webview.postMessage(""BTN_CLICKED:" & $i & """)'>" & _
70+
"<span>" & StringLeft($aLabels[$i], 2) & "</span>" & StringTrimLeft($aLabels[$i], 2) & "</button>"
71+
Next
72+
73+
$sHTML &= "</body></html>"
74+
Return $sHTML
75+
EndFunc ;==>_GenerateSidebarHTML
76+
;---------------------------------------------------------------------------------------
77+
Volatile Func JS_Events_OnMessageReceived($oWebV2M, $hGui, $sMessage) ; The Bridge that "catches" clicks
78+
#forceref $oWebV2M, $hGui
79+
If StringLeft($sMessage, 12) = "BTN_CLICKED:" Then
80+
Local $sIndex = StringTrimLeft($sMessage, 12)
81+
; Here you can call any AutoIt function
82+
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83+
MemoWrite("Index button pressed: " & $sIndex)
84+
EndIf
85+
EndFunc ;==>JS_Events_OnMessageReceived
86+
;---------------------------------------------------------------------------------------
87+
Func MemoWrite($sMessage) ; Write a line to the memo control
88+
GUICtrlSetData($g_idMemo, $sMessage & @CRLF, 1)
89+
EndFunc ;==>MemoWrite
90+
;---------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)