這是一個非常深入的技術架構問題。簡短的回答是:**「直接打包」不可行,但「功能移轉」與「資料對接」是可行的,只是架構需要完全翻轉。**
我們必須從 WebAssembly (Wasm) 的底層本質,來分析為什麼 EnScan 與 DibHandle 無法直接放入 Wasm:
核心障礙:硬體存取與沙盒 (Sandbox) 限制
EnScan 的核心是封裝 Windows 的 TWAIN API。TWAIN 是一個極度依賴作業系統訊息(Window Messages)與本地驅動程式(.ds 檔案)的協定。Wasm 無法呼叫 Windows API,也無法載入掃描機的 .dll 驅動程式。EnScan 是一個 VCL 元件,深層綁定了 Windows 的 GDI(圖形設備介面)。Wasm 並沒有 Windows GDI,它只有一塊線性記憶體(Linear Memory)和 Canvas API。DibHandle 或 TMemoryStream 嗎?這涉及到兩者記憶體模型的完全不相容:
DibHandle 本質上是一個 Windows 作業系統核心管理的**記憶體地址代號**。DibHandle 傳給 Wasm,Wasm 只會把它看作一個無意義的整數。TMemoryStream。TMemoryStream:操作的是實體 RAM。
TMemoryStream:操作的是瀏覽器分配給 Wasm 實例的一塊 ArrayBuffer。如果你想用 Wasm 處理掃描後的影像,正確的架構應該是:
你仍需要一個小的 Delphi Win32 程式(或 Service)跑在使用者電腦上:
1. 呼叫 EnScan 進行掃描。
2. 在 OnAcquire 中拿到 DibHandle。
3. 關鍵轉化:在本地端將 DibHandle 轉成標準的影像格式(如 Base64 String 或 Uint8Array 二進位流)。
本地程式透過 WebSocket 或 Local HTTP Server (REST) 將這串二進位資料傳送給瀏覽器。
ArrayBuffer)。| 功能特性 | 原有的 Delphi OCX | 現代 WebAssembly 方案 |
|---|---|---|
| 硬體控制 (TWAIN) | 直接呼叫 (OK) | 無法存取 (需透過本地 Service 轉發) |
| 記憶體管理 | 使用 Windows Handle (DibHandle) |
使用 Wasm 線性記憶體 (ArrayBuffer) |
| 影像處理速度 | 極快 (Native) | 極快 (Wasm 近乎 Native) |
| 跨瀏覽器支援 | 僅限 IE / Edge IE Mode | 全瀏覽器支援 (Chrome, Safari, Edge) |
| 安全風險 | 高 (ActiveX 有權限漏洞) | 極高 (沙盒保護) |
不要嘗試把 EnScan 直接「編譯」成 Wasm,那會導致數千個 WinAPI 連結錯誤。
你應該將 CB_IMGPSScanImp.pas 拆分成兩部分:
1. Backend (Win32): 只負責掃描與存成檔案/串流。
2. Frontend (Wasm/Web): 負責顯示 ImageScrollBox 的功能、UI 邏輯與上傳伺服器。
你想了解如何寫一個簡單的 Local Service,讓 Delphi 掃描後把資料傳給網頁嗎? 這通常是目前銀行系統現代化(去 IE 化)最普遍的作法。