Skip to content

Commit e954ef1

Browse files
authored
015-CSV_Viewer.au3 + 016-CSV_Editor.au3 + CSV file
1 parent 9a7e5e6 commit e954ef1

3 files changed

Lines changed: 607 additions & 0 deletions

File tree

examples/015-CSV_Viewer.au3

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#AutoIt3Wrapper_UseX64=n
2+
#AutoIt3Wrapper_Run_AU3Check=Y
3+
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=y
4+
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
5+
#Au3Stripper_Ignore_Funcs=__NetWebView2_WebEvents_*,__NetWebView2_JSEvents_*
6+
7+
; CSV_Viewer.au3
8+
9+
#include <Array.au3>
10+
#include <GUIConstantsEx.au3>
11+
#include <WindowsConstants.au3>
12+
#include "..\NetWebView2Lib.au3"
13+
14+
_Example()
15+
16+
#Region ; UDF TESTING EXAMPLE
17+
Func _Example()
18+
Local $oMyError = ObjEvent("AutoIt.Error", __NetWebView2_COMErrFunc)
19+
#forceref $oMyError
20+
21+
; Create GUI with resizing support
22+
Local $hGUI = GUICreate("WebView2AutoIt CSV Viewer", 500, 650, -1, -1, BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPCHILDREN))
23+
GUISetBkColor(0x2B2B2B, $hGUI)
24+
25+
; GUI Controls for CSV interaction
26+
Local $idLoadFile = GUICtrlCreateLabel("Load CSV", 280, 10, 90, 30)
27+
GUICtrlSetFont(-1, 12, Default, $GUI_FONTUNDER, "Segoe UI")
28+
GUICtrlSetResizing(-1, $GUI_DOCKALL)
29+
GUICtrlSetColor(-1, 0x00CCFF) ; Light Blue
30+
31+
; Initialize WebView2 Manager and register events
32+
Local $oWebV2M = _NetWebView2_CreateManager()
33+
If @error Then Return SetError(@error, @extended, $oWebV2M)
34+
35+
; Initialize JavaScript Bridge
36+
Local $oJSBridge = _NetWebView2_GetBridge($oWebV2M)
37+
If @error Then Return SetError(@error, @extended, $oWebV2M)
38+
39+
Local $sProfileDirectory = @ScriptDir & "\NetWebView2Lib-UserDataFolder"
40+
_NetWebView2_Initialize($oWebV2M, $hGUI, $sProfileDirectory, 0, 50, 0, 0, True, True, True, 1.2, "0x2B2B2B")
41+
42+
; Initial CSV display
43+
_Web_CSVViewer($oWebV2M) ; 🏆 https://stackblitz.com/edit/web-platform-3kkvy2?file=index.html
44+
45+
GUISetState(@SW_SHOW)
46+
47+
; Main Application Loop
48+
While 1
49+
Switch GUIGetMsg()
50+
Case $GUI_EVENT_CLOSE
51+
Exit
52+
53+
Case $idLoadFile
54+
Local $sFilePath = FileOpenDialog("Select CSV File", @ScriptDir, "CSV Files (*.csv;*.txt)", 1)
55+
If Not @error Then
56+
Local $sFileData = FileRead($sFilePath)
57+
If $sFileData <> "" Then
58+
_Web_CSVViewer($oWebV2M, $sFileData) ; Re-render CSV with new data
59+
__NetWebView2_Log(@ScriptLineNumber, "+ Loaded CSV from: " & $sFilePath)
60+
EndIf
61+
EndIf
62+
63+
EndSwitch
64+
WEnd
65+
66+
_NetWebView2_CleanUp($oWebV2M, $oJSBridge)
67+
EndFunc ;==>Main
68+
69+
#Region ; === UTILS ===
70+
Func _Web_CSVViewer(ByRef $oWeb, $sFileData = "")
71+
; 1. CSS - Dark Theme
72+
Local $sCSS = "body { background-color: #2b2b2b; color: white; font-family: 'Segoe UI', sans-serif; margin: 0; padding: 0; }" & _
73+
".container { width: 100%; padding: 20px; box-sizing: border-box; }" & _
74+
"h1 { font-size: 1.5rem; margin-bottom: 20px; color: #00CCFF; text-align: center; }" & _
75+
"table { border-collapse: collapse; width: 100%; background: #333; box-shadow: 0 4px 8px rgba(0,0,0,0.5); }" & _
76+
"th, td { border: 1px solid #444; padding: 12px 8px; text-align: left; }" & _
77+
"th { background-color: #444; color: #00CCFF; position: sticky; top: 0; }" & _
78+
"tr:nth-child(even) { background-color: #383838; }" & _
79+
"tr:hover { background-color: #4a4a4a; }"
80+
81+
; 2. JavaScript - Preparing data for safe insertion into JS
82+
Local $sSafeData = StringReplace($sFileData, "\", "\\")
83+
$sSafeData = StringReplace($sSafeData, "'", "\'")
84+
$sSafeData = StringReplace($sSafeData, @CRLF, "\n")
85+
$sSafeData = StringReplace($sSafeData, @LF, "\n")
86+
87+
Local $sJS = "const table = document.getElementById('table');" & @CRLF & _
88+
"function renderCSV(csvData) {" & @CRLF & _
89+
" if (!csvData) return;" & @CRLF & _
90+
" const rows = csvData.split(/\n/);" & @CRLF & _
91+
" let html = '';" & @CRLF & _
92+
" rows.forEach((row, index) => {" & @CRLF & _
93+
" if (row.trim() === '') return;" & @CRLF & _
94+
" const cells = row.split(',');" & @CRLF & _
95+
" html += '<tr>';" & @CRLF & _
96+
" cells.forEach(cell => {" & @CRLF & _
97+
" const tag = index === 0 ? 'th' : 'td';" & @CRLF & _
98+
" html += `<${tag}>${cell.trim()}</${tag}>`;" & @CRLF & _
99+
" });" & @CRLF & _
100+
" html += '</tr>';" & @CRLF & _
101+
" });" & @CRLF & _
102+
" table.innerHTML = html;" & @CRLF & _
103+
"}" & @CRLF & _
104+
"if ('" & $sSafeData & "' !== '') { renderCSV('" & $sSafeData & "'); }"
105+
106+
; 3. HTML Structure
107+
Local $sHTML = "<html><head><meta charset='UTF-8'><style>" & $sCSS & "</style></head><body>" & _
108+
"<div class='container'>" & _
109+
" <table id='table'></table>" & _
110+
"</div>" & _
111+
"<script>" & $sJS & "</script>" & _
112+
"</body></html>"
113+
114+
; 4. Loading - using NavigateToString to refresh all the content
115+
$oWeb.NavigateToString($sHTML)
116+
EndFunc
117+
#EndRegion ; === UTILS ===
118+
#EndRegion ; UDF TESTING EXAMPLE

examples/016-CSV_Editor.au3

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
#WIP - this Example is imported from 1.5.0 UDF - and is in "WORK IN PROGRESS" state
2+
3+
#AutoIt3Wrapper_UseX64=n
4+
#AutoIt3Wrapper_Run_AU3Check=Y
5+
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=y
6+
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
7+
#Au3Stripper_Ignore_Funcs=__NetWebView2_WebEvents_*,__NetWebView2_JSEvents_*
8+
9+
; CSV_editor.au3
10+
11+
#include <GUIConstantsEx.au3>
12+
#include <WindowsConstants.au3>
13+
#include <Array.au3>
14+
15+
; Register exit function to ensure clean WebView2 shutdown
16+
OnAutoItExitRegister("_ExitApp")
17+
18+
; Global objects
19+
Global $oWeb, $oJS
20+
Global $oMyError = ObjEvent("AutoIt.Error", "_ErrFunc") ; COM Error Handler
21+
Global $g_DebugInfo = True
22+
Global $sProfileDirectory = @ScriptDir & "\UserDataFolder"
23+
Global $hGUI
24+
25+
Main()
26+
27+
Func Main()
28+
; Create GUI with resizing support
29+
$hGUI = GUICreate("WebView2AutoIt CSV_editor", 1500, 650, -1, -1, BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPCHILDREN))
30+
GUISetBkColor(0x2B2B2B, $hGUI)
31+
32+
; GUI Controls for CSV interaction
33+
Local $idSaveFile = GUICtrlCreateLabel("Save CSV", 100, 10, 90, 30)
34+
GUICtrlSetFont(-1, 12, Default, $GUI_FONTUNDER, "Segoe UI")
35+
GUICtrlSetResizing(-1, $GUI_DOCKALL)
36+
GUICtrlSetColor(-1, 0x4CFF00) ; Chartreuse
37+
38+
Local $idLoadFile = GUICtrlCreateLabel("Load CSV", 280, 10, 90, 30)
39+
GUICtrlSetFont(-1, 12, Default, $GUI_FONTUNDER, "Segoe UI")
40+
GUICtrlSetResizing(-1, $GUI_DOCKALL)
41+
GUICtrlSetColor(-1, 0x00CCFF) ; Light Blue
42+
43+
; Initialize WebView2 Manager and register events
44+
$oWeb = ObjCreate("NetWebView2.Manager")
45+
ObjEvent($oWeb, "WebEvents_", "IWebViewEvents")
46+
47+
; Important: Pass $hGUI in parentheses to maintain Pointer type for COM
48+
$oWeb.Initialize(($hGUI), $sProfileDirectory, 0, 50, 1500, 600)
49+
50+
; Initialize JavaScript Bridge
51+
$oJS = $oWeb.GetBridge()
52+
ObjEvent($oJS, "JavaScript_", "IBridgeEvents")
53+
54+
; Wait for WebView2 to be ready
55+
Do
56+
Sleep(50)
57+
Until $oWeb.IsReady
58+
59+
; WebView2 Configuration
60+
$oWeb.SetAutoResize(True) ; Using SetAutoResize(True) to skip WM_SIZE
61+
$oWeb.BackColor = "0x2B2B2B"
62+
$oWeb.AreDevToolsEnabled = True ; Allow F12
63+
$oWeb.ZoomFactor = 1.2
64+
65+
; Initial CSV display
66+
_Web_CSVViewer($oWeb) ; 🏆 https://stackblitz.com/edit/web-platform-3kkvy2?file=index.html
67+
68+
GUISetState(@SW_SHOW)
69+
70+
; Main Application Loop
71+
While 1
72+
Switch GUIGetMsg()
73+
Case $GUI_EVENT_CLOSE
74+
Exit
75+
76+
Case $idSaveFile
77+
$oWeb.ExecuteScript("sendDataToAutoIt();")
78+
79+
Case $idLoadFile
80+
Local $sFilePath = FileOpenDialog("Select CSV File", @ScriptDir, "CSV Files (*.csv;*.txt)", 1)
81+
If Not @error Then
82+
Local $sFileData = FileRead($sFilePath)
83+
If $sFileData <> "" Then
84+
_Web_CSVViewer($oWeb, $sFileData) ; Re-render CSV with new data
85+
__DW("+ Loaded CSV from: " & $sFilePath)
86+
EndIf
87+
EndIf
88+
89+
EndSwitch
90+
WEnd
91+
EndFunc ;==>Main
92+
93+
#Region ; === EVENT HANDLERS ===
94+
95+
; Handles native WebView2 events
96+
Func WebEvents_OnMessageReceived($sMsg)
97+
__DW("+++ [WebEvents]: " & (StringLen($sMsg) > 150 ? StringLeft($sMsg, 150) & "..." : $sMsg) & @CRLF, 0)
98+
Local $iSplitPos = StringInStr($sMsg, "|")
99+
Local $sCommand = $iSplitPos ? StringStripWS(StringLeft($sMsg, $iSplitPos - 1), 3) : $sMsg
100+
Local $sData = $iSplitPos ? StringTrimLeft($sMsg, $iSplitPos) : ""
101+
Local $aParts
102+
103+
Switch $sCommand
104+
Case "INIT_READY"
105+
$oWeb.ExecuteScript('window.chrome.webview.postMessage(JSON.stringify({ "type": "COM_TEST", "status": "OK" }));')
106+
107+
Case "WINDOW_RESIZED"
108+
$aParts = StringSplit($sData, "|")
109+
If $aParts[0] >= 2 Then
110+
Local $iW = Int($aParts[1]), $iH = Int($aParts[2])
111+
; Filter minor resize glitches
112+
If $iW > 50 And $iH > 50 Then __DW("WINDOW_RESIZED : " & $iW & "x" & $iH & @CRLF)
113+
EndIf
114+
EndSwitch
115+
EndFunc ;==>WebEvents_OnMessageReceived
116+
117+
; Handles custom messages from JavaScript (window.chrome.webview.postMessage)
118+
Func JavaScript_OnMessageReceived($sMsg)
119+
__DW(">>> [JavaScript]: " & (StringLen($sMsg) > 150 ? StringLeft($sMsg, 150) & "..." : $sMsg) & @CRLF, 0)
120+
Local $sFirstChar = StringLeft($sMsg, 1)
121+
122+
; 1. JSON Messaging
123+
If $sFirstChar = "{" Or $sFirstChar = "[" Then
124+
__DW("+> : Processing JSON Messaging..." & @CRLF)
125+
Local $oJson = ObjCreate("NetJson.Parser")
126+
If Not IsObj($oJson) Then Return ConsoleWrite("!> Error: Failed to create NetJson object." & @CRLF)
127+
128+
$oJson.Parse($sMsg)
129+
Local $sJobType = $oJson.GetTokenValue("type")
130+
131+
Switch $sJobType
132+
Case "COM_TEST"
133+
__DW("- COM_TEST Confirmed: " & $oJson.GetTokenValue("status") & @CRLF)
134+
EndSwitch
135+
136+
Else
137+
; 2. Legacy / Native Pipe-Delimited Messaging
138+
__DW("+> : Legacy / Native Pipe-Delimited Messaging..." & @CRLF, 0)
139+
Local $sCommand, $sData, $iSplitPos
140+
$iSplitPos = StringInStr($sMsg, "|") - 1
141+
142+
If $iSplitPos < 0 Then
143+
$sCommand = StringStripWS($sMsg, 3)
144+
$sData = ""
145+
Else
146+
$sCommand = StringStripWS(StringLeft($sMsg, $iSplitPos), 3)
147+
$sData = StringTrimLeft($sMsg, $iSplitPos + 1)
148+
EndIf
149+
150+
Switch $sCommand
151+
Case "JSON_CLICKED"
152+
Local $aClickData = StringSplit($sData, "=", 2) ; Split "Key = Value"
153+
If UBound($aClickData) >= 2 Then
154+
Local $sKey = StringStripWS($aClickData[0], 3)
155+
Local $sVal = StringStripWS($aClickData[1], 3)
156+
__DW("+++ Property: " & $sKey & " | Value: " & $sVal & @CRLF)
157+
EndIf
158+
159+
Case "COM_TEST"
160+
__DW("- Status: Legacy COM_TEST: " & $sData & @CRLF)
161+
162+
Case "CSV_UPDATED"
163+
; Clean up literal \n sent by JS to real @CRLF for AutoIt
164+
Local $sCleanData = StringReplace($sData, "\n", @CRLF)
165+
166+
; Here you define what you want to do with the data
167+
; E.g. Save to a file so that changes are not lost
168+
Local $hFile = FileOpen(@ScriptDir & "\updated_data.csv", 2) ; 2 = Overwrite
169+
If $hFile <> -1 Then
170+
FileWrite($hFile, $sCleanData)
171+
FileClose($hFile)
172+
__DW("- CSV saved to file successfully!")
173+
EndIf
174+
175+
Case "ERROR"
176+
__DW("! Status: " & $sData & @CRLF)
177+
EndSwitch
178+
EndIf
179+
EndFunc ;==>JavaScript_OnMessageReceived
180+
181+
Func WebEvents_OnContextMenuRequested($sLink, $iX, $iY, $sSelection)
182+
#forceref $sLink, $iX, $iY, $sSelection
183+
EndFunc ;==>WebEvents_OnContextMenuRequested
184+
185+
#EndRegion ; === EVENT HANDLERS ===
186+
187+
#Region ; === UTILS ===
188+
189+
Func _Web_CSVViewer(ByRef $oWeb, $sFileData = "")
190+
Local $sSafeData = StringReplace($sFileData, "\", "\\")
191+
$sSafeData = StringReplace($sSafeData, "'", "\'")
192+
$sSafeData = StringReplace($sSafeData, @CRLF, "\n")
193+
$sSafeData = StringReplace($sSafeData, @LF, "\n")
194+
195+
Local $sCSS = "body { background-color: #2b2b2b; color: white; font-family: 'Segoe UI', sans-serif; margin: 0; padding: 0; }" & _
196+
".container { width: 100%; padding: 20px; box-sizing: border-box; }" & _
197+
"h1 { font-size: 1.5rem; margin-bottom: 20px; color: #00CCFF; text-align: center; }" & _
198+
"table { border-collapse: collapse; width: 100%; background: #333; box-shadow: 0 4px 8px rgba(0,0,0,0.5); }" & _
199+
"th, td { border: 1px solid #444; padding: 12px 8px; text-align: left; }" & _
200+
"th { background-color: #444; color: #00CCFF; position: sticky; top: 0; }" & _
201+
"tr:nth-child(even) { background-color: #383838; }" & _
202+
"tr:hover { background-color: #4a4a4a; }"
203+
204+
Local $sJS = "const table = document.getElementById('table');" & @CRLF & _
205+
"function renderCSV(csvData) {" & @CRLF & _
206+
" const rows = csvData.split(/\r?\n/);" & @CRLF & _
207+
" let html = '';" & @CRLF & _
208+
" rows.forEach((row, index) => {" & @CRLF & _
209+
" if (row.trim() === '') return;" & @CRLF & _
210+
" const cells = row.split(',');" & @CRLF & _
211+
" html += '<tr>';" & @CRLF & _
212+
" cells.forEach(cell => {" & @CRLF & _
213+
" const tag = index === 0 ? 'th' : 'td';" & @CRLF & _
214+
" const editable = index === 0 ? '' : 'contenteditable=""true""';" & @CRLF & _
215+
" html += `<${tag} ${editable}>${cell.trim()}</${tag}>`;" & @CRLF & _
216+
" });" & @CRLF & _
217+
" html += '</tr>';" & @CRLF & _
218+
" });" & @CRLF & _
219+
" table.innerHTML = html;" & @CRLF & _
220+
"}" & @CRLF & _
221+
"function sendDataToAutoIt() {" & @CRLF & _
222+
" let data = [];" & @CRLF & _
223+
" Array.from(table.rows).forEach(row => {" & @CRLF & _
224+
" let rowData = Array.from(row.cells).map(cell => cell.innerText.replace(/,/g, ''));" & @CRLF & _ ; Removing commas from text to avoid corrupting CSV
225+
" data.push(rowData.join(','));" & @CRLF & _
226+
" });" & @CRLF & _
227+
" window.chrome.webview.postMessage('CSV_UPDATED|' + data.join('\\n'));" & @CRLF & _
228+
"}" & @CRLF & _
229+
"if ('" & $sSafeData & "' !== '') { renderCSV('" & $sSafeData & "'); }"
230+
231+
Local $sHTML = "<html><head><meta charset='UTF-8'><style>" & $sCSS & "</style></head><body>" & _
232+
"<div class='container'><table id='table'></table></div>" & _
233+
"<script>" & $sJS & "</script></body></html>"
234+
235+
$oWeb.NavigateToString($sHTML)
236+
EndFunc ;==>_Web_CSVViewer
237+
238+
Func _ErrFunc($oError) ; Global COM Error Handler
239+
ConsoleWrite('@@ Line(' & $oError.scriptline & ') : COM Error Number: (0x' & Hex($oError.number, 8) & ') ' & $oError.windescription & @CRLF)
240+
EndFunc ;==>_ErrFunc
241+
242+
; Debug Write utility
243+
Func __DW($sString, $iErrorNoLineNo = 1, $iLine = @ScriptLineNumber, $iError = @error, $iExtended = @extended)
244+
If Not $g_DebugInfo Then Return SetError($iError, $iExtended, 0)
245+
Local $iReturn
246+
If $iErrorNoLineNo = 1 Then
247+
If $iError Then
248+
$iReturn = ConsoleWrite("@@(" & $iLine & ") :: @error:" & $iError & ", @extended:" & $iExtended & ", " & $sString)
249+
Else
250+
$iReturn = ConsoleWrite("+>(" & $iLine & ") :: " & $sString)
251+
EndIf
252+
Else
253+
$iReturn = ConsoleWrite($sString)
254+
EndIf
255+
Return SetError($iError, $iExtended, $iReturn)
256+
EndFunc ;==>__DW
257+
258+
Func _NetJson_New($sInitialJson = "{}")
259+
Local $oParser = ObjCreate("NetJson.Parser")
260+
If Not IsObj($oParser) Then Return SetError(1, 0, 0)
261+
If $sInitialJson <> "" Then $oParser.Parse($sInitialJson)
262+
Return $oParser
263+
EndFunc ;==>_NetJson_New
264+
265+
Func _ExitApp()
266+
If IsObj($oWeb) Then $oWeb.Cleanup()
267+
$oWeb = 0
268+
$oJS = 0
269+
Exit
270+
EndFunc ;==>_ExitApp
271+
272+
#EndRegion ; === UTILS ===

0 commit comments

Comments
 (0)