Skip to content

Commit c1c7d44

Browse files
authored
new example
1 parent 79bb878 commit c1c7d44

2 files changed

Lines changed: 380 additions & 0 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"Blacklist": [
3+
"electrician_simulator",
4+
"hitman_2_silent_assassin",
5+
"hitman_blood_money",
6+
"syberia_anniversary_collection",
7+
"hitman_contracts",
8+
"hitman_absolution",
9+
"fallout_4_game_of_the_year_edition",
10+
"summer_memories_deluxe_edition",
11+
"huniepop",
12+
"planescape_torment_enhanced_edition",
13+
"hitman_codename_47",
14+
"the_house_of_the_dead_remake",
15+
"cyberpunk_2077_phantom_liberty",
16+
"neverwinter_nights_enhanced_edition_digital_deluxe_edition",
17+
"god_of_war",
18+
"heroes_of_might_and_magic_4_complete",
19+
"horses",
20+
"cyberpunk_2077_ultimate_edition",
21+
"saints_row_2"
22+
],
23+
"Owned": [
24+
"stalker_call_of_prypiat_enhanced_edition",
25+
"lords_of_the_fallen_game_of_the_year_edition",
26+
"assassins_creed_directors_cut",
27+
"heroes_of_might_and_magic_3_complete_edition",
28+
"postal_2",
29+
"frostpunk_game_of_the_year_edition",
30+
"splinter_cell"
31+
],
32+
"Watchlist": [
33+
"tomb_raider_iv_vi_remastered",
34+
"styx_shards_of_darkness",
35+
"fallout_new_vegas_ultimate_edition"
36+
]
37+
}
Lines changed: 343 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,343 @@
1+
#AutoIt3Wrapper_UseX64=y
2+
; Html_Gui.au3
3+
#include <GUIConstantsEx.au3>
4+
#include <WindowsConstants.au3>
5+
#include <Array.au3>
6+
7+
; Register exit function to ensure clean WebView2 shutdown
8+
OnAutoItExitRegister("_ExitApp")
9+
10+
; Global objects
11+
Global $oWeb, $oJS
12+
Global $oMyError = ObjEvent("AutoIt.Error", "_ErrFunc") ; COM Error Handler
13+
Global $g_DebugInfo = True
14+
Global $g_sProfilePath = @ScriptDir & "\UserDataFolder"
15+
Global $hGUI
16+
17+
Main()
18+
19+
Func Main()
20+
; Create GUI with resizing support
21+
$hGUI = GUICreate("WebView2AutoIt JSON Viewer", 500, 650, -1, -1, BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPCHILDREN))
22+
GUISetBkColor(0x2B2B2B, $hGUI)
23+
24+
; GUI Controls for JSON Tree interaction
25+
Local $idExpand = GUICtrlCreateLabel("Expand All", 10, 10, 90, 30)
26+
GUICtrlSetFont(-1, 12, Default, $GUI_FONTUNDER, "Segoe UI")
27+
GUICtrlSetResizing(-1, $GUI_DOCKALL)
28+
GUICtrlSetColor(-1, 0x00FF00) ; Green
29+
30+
Local $idCollapse = GUICtrlCreateLabel("Collapse All", 110, 10, 90, 30)
31+
GUICtrlSetFont(-1, 12, Default, $GUI_FONTUNDER, "Segoe UI")
32+
GUICtrlSetResizing(-1, $GUI_DOCKALL)
33+
GUICtrlSetColor(-1, 0xFF4D4D) ; Red
34+
35+
Local $idFind = GUICtrlCreateLabel("Search", 210, 10, 60, 30)
36+
GUICtrlSetFont(-1, 12, Default, $GUI_FONTUNDER, "Segoe UI")
37+
GUICtrlSetResizing(-1, $GUI_DOCKALL)
38+
GUICtrlSetColor(-1, 0xFFD700) ; Gold
39+
40+
Local $idLoadFile = GUICtrlCreateLabel("Load JSON", 280, 10, 90, 30)
41+
GUICtrlSetFont(-1, 12, Default, $GUI_FONTUNDER, "Segoe UI")
42+
GUICtrlSetResizing(-1, $GUI_DOCKALL)
43+
GUICtrlSetColor(-1, 0x00CCFF) ; Light Blue
44+
45+
; Initialize WebView2 Manager and register events
46+
$oWeb = ObjCreate("NetWebView2.Manager")
47+
ObjEvent($oWeb, "WebEvents_", "IWebViewEvents")
48+
49+
; Important: Pass $hGUI in parentheses to maintain Pointer type for COM
50+
$oWeb.Initialize(($hGUI), $g_sProfilePath, 0, 50, 500, 600)
51+
52+
; Initialize JavaScript Bridge
53+
$oJS = $oWeb.GetBridge()
54+
ObjEvent($oJS, "JavaScript_", "IBridgeEvents")
55+
56+
; Wait for WebView2 to be ready
57+
Do
58+
Sleep(50)
59+
Until $oWeb.IsReady
60+
61+
; WebView2 Configuration
62+
$oWeb.SetAutoResize(True) ; Using SetAutoResize(True) to skip WM_SIZE
63+
$oWeb.BackColor = "0x2B2B2B"
64+
$oWeb.AreDevToolsEnabled = True ; Allow F12
65+
$oWeb.ZoomFactor = 1.2
66+
67+
; Initial JSON display
68+
Local $sMyJson = '{"Game": "Witcher 3", "ID": 1, "Meta": {"Developer": "CD Projekt", "Year": 2015 }, "Tags": ["RPG", "Open World"]}'
69+
70+
_Web_jsonTree($oWeb, $sMyJson) ; 🏆 https://github.com/summerstyle/jsonTreeViewer
71+
72+
GUISetState(@SW_SHOW)
73+
74+
Local $sLastSearch = ""
75+
76+
; Main Application Loop
77+
While 1
78+
Switch GUIGetMsg()
79+
Case $GUI_EVENT_CLOSE
80+
Exit
81+
82+
Case $idExpand
83+
; Call JavaScript expand method on the global tree object
84+
$oWeb.ExecuteScript("if(window.tree) window.tree.expand();")
85+
86+
Case $idCollapse
87+
; Call JavaScript collapse method
88+
$oWeb.ExecuteScript("if(window.tree) window.tree.collapse();")
89+
90+
Case $idFind
91+
Local $sInput = InputBox("JSON Search", "Enter key or value:", $sLastSearch, "", 200, 130, Default, Default, Default, $hGUI)
92+
If Not @error And StringLen(StringStripWS($sInput, 3)) > 0 Then
93+
$sLastSearch = StringStripWS($sInput, 3)
94+
_Web_jsonTreeFind($sLastSearch, False) ; New search
95+
EndIf
96+
97+
Case $idLoadFile
98+
Local $sFilePath = FileOpenDialog("Select JSON File", @ScriptDir, "JSON Files (*.json;*.txt)", 1)
99+
If Not @error Then
100+
Local $sFileData = FileRead($sFilePath)
101+
If $sFileData <> "" Then
102+
_Web_jsonTree($oWeb, $sFileData) ; Re-render tree with new data
103+
__DW("+ Loaded JSON from: " & $sFilePath & @CRLF)
104+
EndIf
105+
EndIf
106+
107+
EndSwitch
108+
WEnd
109+
EndFunc ;==>Main
110+
111+
#Region ; === EVENT HANDLERS ===
112+
113+
; Handles native WebView2 events
114+
Func WebEvents_OnMessageReceived($sMsg)
115+
__DW("+++ [WebEvents]: " & (StringLen($sMsg) > 150 ? StringLeft($sMsg, 150) & "..." : $sMsg) & @CRLF, 0)
116+
Local $iSplitPos = StringInStr($sMsg, "|")
117+
Local $sCommand = $iSplitPos ? StringStripWS(StringLeft($sMsg, $iSplitPos - 1), 3) : $sMsg
118+
Local $sData = $iSplitPos ? StringTrimLeft($sMsg, $iSplitPos) : ""
119+
Local $aParts
120+
121+
Switch $sCommand
122+
Case "WINDOW_RESIZED"
123+
$aParts = StringSplit($sData, "|")
124+
If $aParts[0] >= 2 Then
125+
Local $iW = Int($aParts[1]), $iH = Int($aParts[2])
126+
; Filter minor resize glitches
127+
If $iW > 50 And $iH > 50 Then __DW("WINDOW_RESIZED : " & $iW & "x" & $iH & @CRLF)
128+
EndIf
129+
EndSwitch
130+
EndFunc ;==>WebEvents_OnMessageReceived
131+
132+
; Handles custom messages from JavaScript (window.chrome.webview.postMessage)
133+
Func JavaScript_OnMessageReceived($sMsg)
134+
__DW(">>> [JavaScript]: " & (StringLen($sMsg) > 150 ? StringLeft($sMsg, 150) & "..." : $sMsg) & @CRLF, 0)
135+
Local $sFirstChar = StringLeft($sMsg, 1)
136+
137+
; 1. Modern JSON Messaging
138+
If $sFirstChar = "{" Or $sFirstChar = "[" Then
139+
__DW("+> : Processing JSON message..." & @CRLF)
140+
Local $oJson = ObjCreate("NetJson.Parser")
141+
If Not IsObj($oJson) Then Return ConsoleWrite("!> Error: Failed to create NetJson object." & @CRLF)
142+
143+
$oJson.Parse($sMsg)
144+
Local $sJobType = $oJson.GetTokenValue("type")
145+
146+
Switch $sJobType
147+
Case "CONSOLE_LOG"
148+
If Not _Web_DebugJStoConsole($oWeb) Then Return
149+
Local $sLvl = $oJson.GetTokenValue("level")
150+
Local $sTxt = $oJson.GetTokenValue("message")
151+
__DW(StringFormat("[JS-%s] %s", $sLvl, $sTxt) & @CRLF, 0)
152+
153+
Case "COM_TEST"
154+
__DW("- COM_TEST Confirmed: " & $oJson.GetTokenValue("status") & @CRLF)
155+
EndSwitch
156+
157+
Else
158+
; 2. Legacy / Native Pipe-Delimited Messaging
159+
__DW("+> : Processing Delimited message..." & @CRLF, 0)
160+
Local $sCommand, $sData, $iSplitPos
161+
$iSplitPos = StringInStr($sMsg, "|") - 1
162+
163+
If $iSplitPos < 0 Then
164+
$sCommand = StringStripWS($sMsg, 3)
165+
$sData = ""
166+
Else
167+
$sCommand = StringStripWS(StringLeft($sMsg, $iSplitPos), 3)
168+
$sData = StringTrimLeft($sMsg, $iSplitPos + 1)
169+
EndIf
170+
171+
Switch $sCommand
172+
Case "JSON_CLICKED"
173+
Local $aClickData = StringSplit($sData, "=", 2) ; Split "Key = Value"
174+
If UBound($aClickData) >= 2 Then
175+
Local $sKey = StringStripWS($aClickData[0], 3)
176+
Local $sVal = StringStripWS($aClickData[1], 3)
177+
__DW("+++ Property: " & $sKey & " | Value: " & $sVal & @CRLF)
178+
EndIf
179+
180+
Case "COM_TEST"
181+
__DW("- Status: Legacy COM_TEST: " & $sData & @CRLF)
182+
183+
Case "ERROR"
184+
__DW("! Status: " & $sData & @CRLF)
185+
EndSwitch
186+
EndIf
187+
EndFunc ;==>JavaScript_OnMessageReceived
188+
189+
Func WebEvents_OnContextMenuRequested($sLink, $iX, $iY, $sSelection)
190+
#forceref $sLink, $iX, $iY, $sSelection
191+
EndFunc ;==>WebEvents_OnContextMenuRequested
192+
193+
#EndRegion ; === EVENT HANDLERS ===
194+
195+
#Region ; === UTILS ===
196+
197+
Func _ErrFunc($oError) ; Global COM Error Handler
198+
ConsoleWrite('@@ Line(' & $oError.scriptline & ') : COM Error Number: (0x' & Hex($oError.number, 8) & ') ' & $oError.windescription & @CRLF)
199+
EndFunc ;==>_ErrFunc
200+
201+
; Debug Write utility
202+
Func __DW($sString, $iErrorNoLineNo = 1, $iLine = @ScriptLineNumber, $iError = @error, $iExtended = @extended)
203+
If Not $g_DebugInfo Then Return SetError($iError, $iExtended, 0)
204+
Local $iReturn
205+
If $iErrorNoLineNo = 1 Then
206+
If $iError Then
207+
$iReturn = ConsoleWrite("@@(" & $iLine & ") :: @error:" & $iError & ", @extended:" & $iExtended & ", " & $sString)
208+
Else
209+
$iReturn = ConsoleWrite("+>(" & $iLine & ") :: " & $sString)
210+
EndIf
211+
Else
212+
$iReturn = ConsoleWrite($sString)
213+
EndIf
214+
Return SetError($iError, $iExtended, $iReturn)
215+
EndFunc ;==>__DW
216+
217+
Func _NetJson_New($sInitialJson = "{}")
218+
Local $oParser = ObjCreate("NetJson.Parser")
219+
If Not IsObj($oParser) Then Return SetError(1, 0, 0)
220+
If $sInitialJson <> "" Then $oParser.Parse($sInitialJson)
221+
Return $oParser
222+
EndFunc ;==>_NetJson_New
223+
224+
; #FUNCTION# ====================================================================================================================
225+
; Name...........: _Web_jsonTree
226+
; Description....: Renders JSON data using the jsonTree library by summerstyle.
227+
; Author.........: summerstyle (https://github.com/summerstyle/jsonTreeViewer)
228+
; Integration....: Adapted for AutoIt WebView2
229+
; ===============================================================================================================================
230+
Func _Web_jsonTree(ByRef $oWeb, $sJson)
231+
; 1. Prepare JSON (Minify to prevent script errors from line breaks)
232+
Local $oJsonObj = _NetJson_New($sJson)
233+
$sJson = $oJsonObj.GetMinifiedJson()
234+
235+
; 2. Load local library files
236+
Local $sJsLib = FileRead(@ScriptDir & "\.JS_Lib\jsonTree.js")
237+
Local $sCssLib = FileRead(@ScriptDir & "\.JS_Lib\jsonTreeDark.css")
238+
239+
; 3. Build HTML with embedded Logic
240+
Local $sHTML = "<html><head><meta charset=""utf-8""><style>" & _
241+
$sCssLib & _
242+
"</style></head><body>" & _
243+
"<div id='tree-container' class='jsontree_tree'></div>" & _
244+
" <div style='position:fixed; bottom:5px; right:10px; font-size:10px; color:#555; font-family:sans-serif;'>" & _
245+
" Powered by <a href='https://github.com/summerstyle/jsonTreeViewer' style='color:#777; text-decoration:none;'>jsonTree</a>" & _
246+
" </div>" & _
247+
"<script>" & @CRLF & _
248+
$sJsLib & @CRLF & _
249+
";" & @CRLF & _ ; Ensure library/code separation
250+
"try {" & @CRLF & _
251+
" var data = " & $sJson & ";" & @CRLF & _
252+
" var container = document.getElementById('tree-container');" & @CRLF & _
253+
" if (typeof jsonTree !== 'undefined') {" & @CRLF & _
254+
" window.tree = jsonTree.create(data, container);" & @CRLF & _ ; Assign to window for global access
255+
" window.tree.expand(1);" & @CRLF & _
256+
" container.addEventListener('click', function(e) {" & @CRLF & _
257+
" var node = e.target.closest('.jsontree_node');" & @CRLF & _
258+
" if (node) {" & @CRLF & _
259+
" var labelEl = node.querySelector('.jsontree_label');" & @CRLF & _
260+
" var valueEl = node.querySelector('.jsontree_value');" & @CRLF & _
261+
" if (labelEl && valueEl) {" & @CRLF & _
262+
" var msg = 'JSON_CLICKED|' + labelEl.innerText + ' = ' + valueEl.innerText;" & @CRLF & _
263+
" window.chrome.webview.postMessage(msg);" & @CRLF & _
264+
" }" & @CRLF & _
265+
" }" & @CRLF & _
266+
" });" & @CRLF & _
267+
" } else {" & @CRLF & _
268+
" throw new Error('jsonTree library not loaded');" & @CRLF & _
269+
" }" & @CRLF & _
270+
"} catch(e) {" & @CRLF & _
271+
" window.chrome.webview.postMessage('DEBUG:' + e.message);" & @CRLF & _
272+
" document.body.innerHTML = '<b style=""color:red"">JS Error:</b> ' + e.message;" & @CRLF & _
273+
"}" & @CRLF & _
274+
"</script></body></html>"
275+
276+
; 4. Navigate to the generated HTML
277+
$oWeb.NavigateToString($sHTML)
278+
__DW("+ JSON Tree Rendered & Listeners Active." & @CRLF)
279+
EndFunc ;==>_Web_jsonTree
280+
281+
; #FUNCTION# ====================================================================================================================
282+
; Name...........: _Web_jsonTreeFind
283+
; Description....: Searches for a string in labels and values and highlights matching nodes.
284+
; Parameters.....: $sSearch - The string to find
285+
; ===============================================================================================================================
286+
Func _Web_jsonTreeFind($sSearch, $bNext = False)
287+
Local $sJS = _
288+
"var term = '" & $sSearch & "'.toLowerCase();" & _
289+
"if (!window.searchIndices || window.lastTerm !== term) {" & _
290+
" window.searchIndices = [];" & _
291+
" window.currentSearchIndex = -1;" & _
292+
" window.lastTerm = term;" & _
293+
"}" & _
294+
"" & _
295+
"/* 1. If it's a new search, find all targets */" & _
296+
"if (!" & StringLower($bNext) & " || window.searchIndices.length === 0) {" & _
297+
" document.querySelectorAll('.jsontree_node_marked').forEach(el => el.classList.remove('jsontree_node_marked', 'jsontree_node_active'));" & _
298+
" var targets = document.querySelectorAll('.jsontree_label, .jsontree_value');" & _
299+
" window.searchIndices = [];" & _
300+
" targets.forEach(function(el) {" & _
301+
" var text = el.innerText.toLowerCase();" & _
302+
" var isBracket = (text === '{' || text === '}' || text === '[' || text === ']' || text === '{ }' || text === '[ ]');" & _
303+
" if (!isBracket && (el.classList.contains('jsontree_label') || el.children.length === 0) && text.includes(term)) {" & _
304+
" el.classList.add('jsontree_node_marked');" & _
305+
" window.searchIndices.push(el);" & _
306+
" }" & _
307+
" });" & _
308+
"}" & _
309+
"" & _
310+
"/* 2. Move to next index */" & _
311+
"if (window.searchIndices.length > 0) {" & _
312+
" /* Remove active class from previous */" & _
313+
" if (window.currentSearchIndex >= 0) window.searchIndices[window.currentSearchIndex].classList.remove('jsontree_node_active');" & _
314+
" " & _
315+
" window.currentSearchIndex++;" & _
316+
" if (window.currentSearchIndex >= window.searchIndices.length) window.currentSearchIndex = 0;" & _
317+
" " & _
318+
" var activeEl = window.searchIndices[window.currentSearchIndex];" & _
319+
" activeEl.classList.add('jsontree_node_active');" & _
320+
" " & _
321+
" /* Expand parents of active element */" & _
322+
" var p = activeEl.closest('.jsontree_node');" & _
323+
" while (p && p.id !== 'tree-container') {" & _
324+
" if (p.classList.contains('jsontree_node_complex')) p.classList.add('jsontree_node_expanded');" & _
325+
" p = p.parentElement;" & _
326+
" }" & _
327+
" activeEl.scrollIntoView({behavior: 'smooth', block: 'center'});" & _
328+
"}"
329+
330+
; Replace the AutoIt variable $bNext with JS boolean
331+
;~ $sJS = StringReplace($sJS, "$bNext", ($bNext ? "true" : "false"))
332+
ConsoleWrite("$sJS=" & $sJS & @CRLF)
333+
$oWeb.ExecuteScript($sJS)
334+
EndFunc ;==>_Web_jsonTreeFind
335+
336+
Func _ExitApp()
337+
If IsObj($oWeb) Then $oWeb.Cleanup()
338+
$oWeb = 0
339+
$oJS = 0
340+
Exit
341+
EndFunc ;==>_ExitApp
342+
343+
#EndRegion ; === UTILS ===

0 commit comments

Comments
 (0)