It seems to work almost as well.
However, on some sites, certain elements don't seem to be captured properly.
Tested on Windows 10 Home 22H2 build 19045.4170 x64.
Improved code.
Code: Select all
EnableExplicit
UsePNGImageDecoder()
DataSection
IID_IUnknown:
Data.l $00000000
Data.w $0000, $0000
Data.b $C0, $00, $00, $00, $00, $00, $00, $46
EndDataSection
Structure STRUC_IUnknownBase
*pVtbl
lRefCount.l
hEvent.i
EndStructure
Structure STRUC_ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerVtbl Extends STRUC_IUnknownBase
*pQueryInterface
*pAddRef
*pRelease
*pInvoke
EndStructure
Structure STRUC_ICoreWebView2ExecuteScriptCompletedHandlerVtbl Extends STRUC_IUnknownBase
*pValue.Integer
*pQueryInterface
*pAddRef
*pRelease
*pInvoke
EndStructure
Procedure.l CoreWebView2CompletedHandler_QueryInterface(*this.STRUC_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 CoreWebView2CompletedHandler_AddRef(*this.STRUC_IUnknownBase)
*this\lRefCount + 1
ProcedureReturn *this\lRefCount
EndProcedure
Procedure.l CoreWebView2CallDevToolsProtocolMethodCompletedHandler_Release(*this.STRUC_IUnknownBase)
*this\lRefCount - 1
If *this\lRefCount <= 0
FreeMemory(*this)
ProcedureReturn 0
EndIf
ProcedureReturn *this\lRefCount
EndProcedure
Procedure.l CoreWebView2CallDevToolsProtocolMethodCompletedHandler_Invoke(*this.STRUC_IUnknownBase, errorCode.l, *returnObjectAsJson)
Protected sJSON.s, iJSON, sImgData.s, iImgDataStrLen, *buffer, iDecodedBytes
If *returnObjectAsJson
If errorCode = #S_OK
sJson = PeekS(*returnObjectAsJson)
If sJSON
iJSON = ParseJSON(#PB_Any, sJSON)
If iJSON
sImgData = GetJSONString(GetJSONMember(JSONValue(iJSON), "data"))
If sImgData
iImgDataStrLen = Len(sImgData)
If iImgDataStrLen > 0
*buffer = AllocateMemory(iImgDataStrLen * 2)
If *buffer
iDecodedBytes = Base64Decoder(sImgData, *buffer, MemorySize(*buffer))
If iDecodedBytes > 0
If CatchImage(#PB_Any, *buffer, iDecodedBytes)
ShowLibraryViewer("image")
SetEvent_(*this\hEvent)
EndIf
EndIf
FreeMemory(*buffer)
EndIf
EndIf
EndIf
FreeJSON(iJSON)
EndIf
EndIf
EndIf
EndIf
ProcedureReturn #S_OK
EndProcedure
Procedure.l CoreWebView2ExecuteScriptCompletedHandler_Release(*this.STRUC_IUnknownBase)
*this\lRefCount - 1
ProcedureReturn *this\lRefCount
EndProcedure
Procedure.l CoreWebView2ExecuteScriptCompletedHandler_Invoke(*this.STRUC_ICoreWebView2ExecuteScriptCompletedHandlerVtbl, errorCode.l, *returnObjectAsJson)
If *returnObjectAsJson
If errorCode = #S_OK
;Debug Val(PeekS(*returnObjectAsJson))
If *this\pValue
*this\pValue\i = Val(PeekS(*returnObjectAsJson))
EndIf
SetEvent_(*this\hEvent)
EndIf
EndIf
ProcedureReturn #S_OK
EndProcedure
Procedure CaptureEdgeWeb(WebGadget)
Protected Result
Protected Controller.ICoreWebView2Controller, Core.ICoreWebView2
Protected *CoreWebView2CallDevToolsProtocolMethodCompletedHandler.STRUC_ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerVtbl
Protected *CoreWebView2ExecuteScriptCompletedHandler.STRUC_ICoreWebView2ExecuteScriptCompletedHandlerVtbl
Protected hEvent, iValue, w, h, sParam.s
If GadgetType(WebGadget) <> #PB_GadgetType_Web : ProcedureReturn 0 : EndIf
Controller = GetGadgetAttribute(WebGadget, #PB_WebView_ICoreController)
If Controller = 0 : Goto Proc_Exit : EndIf
If Controller\get_CoreWebView2(@Core) <> #S_OK Or Core = 0 : Goto Proc_Exit : EndIf
*CoreWebView2ExecuteScriptCompletedHandler = AllocateMemory(SizeOf(STRUC_ICoreWebView2ExecuteScriptCompletedHandlerVtbl))
If *CoreWebView2ExecuteScriptCompletedHandler = 0 : Goto Proc_Exit : EndIf
hEvent = CreateEvent_(0, 0, 0, 0)
If hEvent = 0 : Goto Proc_Exit : EndIf
With *CoreWebView2ExecuteScriptCompletedHandler
\pVtbl = *CoreWebView2ExecuteScriptCompletedHandler + OffsetOf(STRUC_ICoreWebView2ExecuteScriptCompletedHandlerVtbl\pQueryInterface)
\pQueryInterface = @CoreWebView2CompletedHandler_QueryInterface()
\pAddRef = @CoreWebView2CompletedHandler_AddRef()
\pRelease = @CoreWebView2ExecuteScriptCompletedHandler_Release()
\pInvoke = @CoreWebView2ExecuteScriptCompletedHandler_Invoke()
\pValue = @iValue
\hEvent = hEvent
EndWith
If Core\ExecuteScript("document.body.scrollWidth", *CoreWebView2ExecuteScriptCompletedHandler) = #S_OK
While WaitForSingleObject_(hEvent, 0) <> #WAIT_OBJECT_0
While WindowEvent() : Wend
Wend
w = iValue
EndIf
If Core\ExecuteScript("document.body.scrollHeight", *CoreWebView2ExecuteScriptCompletedHandler) = #S_OK
While WaitForSingleObject_(hEvent, 0) <> #WAIT_OBJECT_0
While WindowEvent() : Wend
Wend
h = iValue
EndIf
FreeMemory(*CoreWebView2ExecuteScriptCompletedHandler)
*CoreWebView2ExecuteScriptCompletedHandler = 0
If w <= 0 Or h <= 0 : Goto Proc_Exit : EndIf
*CoreWebView2CallDevToolsProtocolMethodCompletedHandler = AllocateMemory(SizeOf(STRUC_ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerVtbl))
If *CoreWebView2CallDevToolsProtocolMethodCompletedHandler = 0 : Goto Proc_Exit : EndIf
With *CoreWebView2CallDevToolsProtocolMethodCompletedHandler
\pVtbl = *CoreWebView2CallDevToolsProtocolMethodCompletedHandler + OffsetOf(STRUC_ICoreWebView2CallDevToolsProtocolMethodCompletedHandlerVtbl\pQueryInterface)
\pQueryInterface = @CoreWebView2CompletedHandler_QueryInterface()
\pAddRef = @CoreWebView2CompletedHandler_AddRef()
\pRelease = @CoreWebView2CallDevToolsProtocolMethodCompletedHandler_Release()
\pInvoke = @CoreWebView2CallDevToolsProtocolMethodCompletedHandler_Invoke()
\hEvent = hEvent
EndWith
; https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-captureScreenshot
sParam = ~"{ \"format\" : \"png\", \"quality\" : 100, \"clip\" : { \"x\" : 0, \"y\" : 0, \"width\" : " + w + ~", \"height\" : " + h + ~", \"scale\" : 1 }, \"fromSurface\" : true, \"captureBeyondViewport\" : true, \"optimizeForSpeed\" : false }"
;If Core\CallDevToolsProtocolMethod("Page.captureScreenshot", "{}", *CoreWebView2CallDevToolsProtocolMethodCompletedHandler) = #S_OK
If Core\CallDevToolsProtocolMethod("Page.captureScreenshot", sParam, *CoreWebView2CallDevToolsProtocolMethodCompletedHandler) = #S_OK
While WaitForSingleObject_(hEvent, 0) <> #WAIT_OBJECT_0
While WindowEvent() : Wend
Wend
Result = 1
*CoreWebView2CallDevToolsProtocolMethodCompletedHandler = 0
EndIf
Core\Release()
Proc_Exit:
If hEvent : CloseHandle_(hEvent) : EndIf
If *CoreWebView2ExecuteScriptCompletedHandler : FreeMemory(*CoreWebView2ExecuteScriptCompletedHandler) : EndIf
If *CoreWebView2CallDevToolsProtocolMethodCompletedHandler : FreeMemory(*CoreWebView2CallDevToolsProtocolMethodCompletedHandler) : EndIf
ProcedureReturn Result
EndProcedure
Define e
OpenWindow(0, 0, 0, 1000, 700, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 20, 4, 80, 24, "Capture")
WebGadget(1, 0, 30, 1000, 660, "https://www.purebasic.com", #PB_Web_Edge)
Repeat
e = WaitWindowEvent()
If e = #PB_Event_Gadget And EventGadget() = 0
CaptureEdgeWeb(1)
EndIf
Until e = #PB_Event_CloseWindow