I enhanced this code with some new functionality.
- SetExplorerFeatures (to force webgadget use IE 11 if #PB_COMPILER_VERSION <570)
Regrettably, most functions only work with the IE based gadget. So it would be great if somebody could add the corresponding code for the new edge based webgadget to have a universal code suited for both webgadget variants
Code: Select all
;- Include javascript.pbi ---------------------------------
; Original from https://www.purebasic.fr/english/viewtopic.php?p=553508#p553508
#URLMON_OPTION_USERAGENT = $10000001
#URLMON_OPTION_USERAGENT_REFRESH = $10000002
Prototype UrlMkGetSessionOption(dwoption.i,pBuffer.i,dwBufferLength.i,pdwBufferLengthOut.i,dwReserved.i)
OpenLibrary(0, "urlmon.dll")
Global UrlMkGetSessionOption.UrlMkGetSessionOption = GetFunction(0, "UrlMkGetSessionOption")
Enumeration ; VARENUM
#VT_EMPTY = 0
#VT_NULL = 1
#VT_I2 = 2
#VT_I4 = 3
#VT_R4 = 4
#VT_R8 = 5
#VT_CY = 6
#VT_DATE = 7
#VT_BSTR = 8
#VT_DISPATCH = 9
#VT_ERROR = 10
#VT_BOOL = 11
#VT_VARIANT = 12
#VT_UNKNOWN = 13
#VT_DECIMAL = 14
#VT_I1 = 16
#VT_UI1 = 17
#VT_UI2 = 18
#VT_UI4 = 19
#VT_I8 = 20
#VT_UI8 = 21
#VT_INT = 22
#VT_UINT = 23
#VT_VOID = 24
#VT_HRESULT = 25
#VT_PTR = 26
#VT_SAFEARRAY = 27
#VT_CARRAY = 28
#VT_USERDEFINED = 29
#VT_LPSTR = 30
#VT_LPWSTR = 31
#VT_RECORD = 36
#VT_INT_PTR = 37
#VT_UINT_PTR = 38
#VT_FILETIME = 64
#VT_BLOB = 65
#VT_STREAM = 66
#VT_STORAGE = 67
#VT_STREAMED_OBJECT = 68
#VT_STORED_OBJECT = 69
#VT_BLOB_OBJECT = 70
#VT_CF = 71
#VT_CLSID = 72
#VT_VERSIONED_STREAM = 73
#VT_BSTR_BLOB = $fff
#VT_VECTOR = $1000
#VT_ARRAY = $2000
#VT_BYREF = $4000
#VT_RESERVED = $8000
#VT_ILLEGAL = $ffff
#VT_ILLEGALMASKED = $fff
#VT_TYPEMASK = $fff
EndEnumeration
#DISPATCH_METHOD = $1
#DISPATCH_PROPERTYGET = $2
#DISPATCH_PROPERTYPUT = $4
#DISPATCH_PROPERTYPUTREF = $8
DataSection
IID_IHTMLDocument: ; {626FC520-A41E-11CF-A731-00A0C9082637}
Data.l $626FC520
Data.w $A41E, $11CF
Data.b $A7, $31, $00, $A0, $C9, $08, $26, $37
IID_NULL: ; {00000000-0000-0000-0000-000000000000}
Data.l $00000000
Data.w $0000, $0000
Data.b $00, $00, $00, $00, $00, $00, $00, $00
EndDataSection
Procedure.s StringFromVARIANT(*var.VARIANT)
Protected Result$
If VariantChangeType_(*var, *var, $2, #VT_BSTR) = #S_OK
Result$ = PeekS(*var\bstrVal, PeekL(*var\bstrVal - 4))
SysFreeString_(*var\bstrVal)
Else
Result$ = "ERROR : Cannot convert VARIANT to String!"
EndIf
ProcedureReturn Result$
EndProcedure
Procedure webgadget_isEdge(gadget)
; Check whether the webgadget has been created with #PB_Web_Edge flag
CompilerIf #PB_Compiler_Version>604
Protected Browser.IWebBrowser2
Browser = GetWindowLong_(GadgetID(Gadget), #GWL_USERDATA)
If browser
ProcedureReturn 0
EndIf
ProcedureReturn #True
CompilerElse
ProcedureReturn 0
CompilerEndIf
EndProcedure
Procedure.s webgadget_ExecuteJavaScript(Gadget.i, Function$, Arguments$, Separator$)
; Execute a java script function
; Note: Function must exiss
If webgadget_isEdge(gadget)=0; - IE based Webgadget
Protected.i result, Count, i
Protected Result$, Message$
Protected *dispID, *bstr_command, *Arguments
Protected Browser.IWebBrowser2
Protected DocumentDispatch.IDispatch, ScriptDispatch.IDispatch
Protected Document.IHTMLDocument
Protected *Arg.VARIANT, varResult.VARIANT
Protected params.DISPPARAMS
Result$ = "ERROR"
Browser = GetWindowLong_(GadgetID(Gadget), #GWL_USERDATA)
If browser
If Browser\get_Document(@DocumentDispatch) = #S_OK
If DocumentDispatch\QueryInterface(?IID_IHTMLDocument, @Document) = #S_OK
If Document\get_Script(@ScriptDispatch) = #S_OK
*bstr_command = SysAllocString_(Function$)
result = ScriptDispatch\GetIDsOfNames(?IID_NULL, @*bstr_command, 1, 0, @*dispID)
If result = #S_OK
; parse the arguments
;
If Trim(Arguments$) = ""
Count = 0
*Arguments = 0
Else
Count = CountString(Arguments$, Separator$)+1
*Arguments = AllocateMemory(SizeOf(VARIANT)*Count)
*Arg = *Arguments
For i = Count To 1 Step -1 ;-FIXED, parameters need to be set in descending order
*Arg\vt = #VT_BSTR
*Arg\bstrVal = SysAllocString_(Trim(StringField(Arguments$, i, Separator$)))
*Arg + SizeOf(VARIANT)
Next i
EndIf
params\cArgs = Count
params\cNamedArgs = 0
params\rgvarg = *Arguments
result = ScriptDispatch\Invoke(*dispID, ?IID_NULL, 0, #DISPATCH_METHOD, @params, @varResult, 0, 0)
If result = #S_OK
Result$ = StringFromVARIANT(@varResult)
Else
Message$ = Space(3000)
FormatMessage_(#FORMAT_MESSAGE_IGNORE_INSERTS|#FORMAT_MESSAGE_FROM_SYSTEM, 0, result, 0, @Message$, 3000, 0)
Result$ = "ERROR: Invoke() "+Message$
EndIf
If *Arguments
*Arg.VARIANT = *Arguments
For i = 1 To Count
SysFreeString_(*Arg\bstrVal)
*Arg + SizeOf(VARIANT)
Next i
FreeMemory(*Arguments)
EndIf
Else
Message$ = Space(3000)
FormatMessage_(#FORMAT_MESSAGE_IGNORE_INSERTS|#FORMAT_MESSAGE_FROM_SYSTEM, 0, result, 0, @Message$, 3000, 0)
Result$ = "ERROR: GetIDsOfNames() "+Message$
EndIf
SysFreeString_(*bstr_command)
ScriptDispatch\Release()
EndIf
Document\Release()
EndIf
DocumentDispatch\Release()
EndIf
ProcedureReturn Result$
EndIf
Else
;- Todo
Debug "Not imüplemented"
EndIf
EndProcedure
Procedure.s webgadget_GetJSVariable(Gadget.i, Name$)
; Retrieve value of a javascript variable
; Note: variable must be defined
If webgadget_isEdge(gadget)=0; - IE based Webgadget
Protected dispID.i, result.i
Protected Result$, Message$
Protected *bstr_name
Protected Browser.IWebBrowser2
Protected DocumentDispatch.IDispatch, ScriptDispatch.IDispatch
Protected Document.IHTMLDocument
Protected params.DISPPARAMS
Protected varResult.VARIANT
Result$ = "ERROR"
Browser = GetWindowLong_(GadgetID(Gadget), #GWL_USERDATA)
If browser
If Browser\get_Document(@DocumentDispatch) = #S_OK
If DocumentDispatch\QueryInterface(?IID_IHTMLDocument, @Document) = #S_OK
If Document\get_Script(@ScriptDispatch) = #S_OK
*bstr_name = SysAllocString_(Name$)
result = ScriptDispatch\GetIDsOfNames(?IID_NULL, @*bstr_name, 1, 0, @dispID)
If result = #S_OK
params\cArgs = 0
params\cNamedArgs = 0
result = ScriptDispatch\Invoke(dispID, ?IID_NULL, 0, #DISPATCH_PROPERTYGET, @params, @varResult, 0, 0)
If result = #S_OK
Result$ = StringFromVARIANT(@varResult)
Else
Message$ = Space(3000)
FormatMessage_(#FORMAT_MESSAGE_IGNORE_INSERTS|#FORMAT_MESSAGE_FROM_SYSTEM, 0, result, 0, @Message$, 3000, 0)
Result$ = "ERROR: Invoke() "+Message$
EndIf
Else
Message$ = Space(3000)
FormatMessage_(#FORMAT_MESSAGE_IGNORE_INSERTS|#FORMAT_MESSAGE_FROM_SYSTEM, 0, result, 0, @Message$, 3000, 0)
Result$ = "ERROR: GetIDsOfNames() "+Message$
EndIf
SysFreeString_(*bstr_name)
ScriptDispatch\Release()
EndIf
Document\Release()
EndIf
DocumentDispatch\Release()
EndIf
ProcedureReturn Result$
EndIf
Else
;- Todo
Debug "Not imüplemented"
EndIf
EndProcedure
Procedure webgadget_SetJSVariable(Gadget, Name$, Value$)
; Set value of a javascript variable
; Note: variable must be defined
If webgadget_isEdge(gadget)=0;- IE based Webgadget
Protected.i success, dispID, result, dispidNamed
Protected *bstr_name
Protected Browser.IWebBrowser2
Protected DocumentDispatch.IDispatch, ScriptDispatch.IDispatch
Protected Document.IHTMLDocument
Protected varValue.VARIANT
Protected params.DISPPARAMS
Browser = GetWindowLong_(GadgetID(Gadget), #GWL_USERDATA)
If browser
If Browser\get_Document(@DocumentDispatch) = #S_OK
If DocumentDispatch\QueryInterface(?IID_IHTMLDocument, @Document) = #S_OK
If Document\get_Script(@ScriptDispatch) = #S_OK
*bstr_name = SysAllocString_(Name$)
result = ScriptDispatch\GetIDsOfNames(?IID_NULL, @*bstr_name, 1, 0, @dispID)
If result = #S_OK
varValue\vt = #VT_BSTR
varValue\bstrVal = SysAllocString_(Value$)
dispidNamed = -3 ; #DISPID_PROPERTYPUT
params\cArgs = 1
params\cNamedArgs = 1
params\rgvarg = @varValue
params\rgdispidNamedArgs = @dispidNamed
result = ScriptDispatch\Invoke(dispID, ?IID_NULL, 0, #DISPATCH_PROPERTYPUT, @params, 0, 0, 0)
If result = #S_OK
success = 1
EndIf
SysFreeString_(varValue\bstrVal)
EndIf
SysFreeString_(*bstr_name)
ScriptDispatch\Release()
EndIf
Document\Release()
EndIf
DocumentDispatch\Release()
EndIf
ProcedureReturn success
EndIf
Else
;- Todo
Debug "Not imüplemented"
EndIf
EndProcedure
Procedure webgadget_SetExplorerFeatures(gadget,sKey$,iValue, iStorage=#HKEY_CURRENT_USER)
; Set Features of Webgadget
If webgadget_isEdge(gadget)=0;- IE based Webgadget
Protected keyName.s = "Software\Microsoft\Internet Explorer\Main\FeatureControl\"+skey$+"\"
Protected dwLabel.s = GetFilePart(ProgramFilename())
Protected dwValue =ivalue
Protected iRet
If iValue=-1; - Delete
If RegOpenKeyEx_(iStorage, keyName, 0, #KEY_SET_VALUE, @phkResult) = #ERROR_SUCCESS
RegDeleteValue_(phkResult, dwLabel)
RegCloseKey_(phkResult)
EndIf
ProcedureReturn #True
EndIf
If RegCreateKey_(iStorage, keyName, @keyResult) = #ERROR_SUCCESS
If RegSetValueEx_(keyResult, @dwLabel, 0, #REG_DWORD, @dwValue, SizeOf(Long)) = #ERROR_SUCCESS
iRet=#True ; MessageRequester("IE","OK")
EndIf
EndIf
ProcedureReturn iRet
Else
;- Todo
Debug "Not imüplemented"
EndIf
EndProcedure
Procedure webgadget_setUserAgent(gadget,ua$="")
; Set UserAgent to be used by webgadget
If webgadget_isEdge(gadget)=0;- IE based Webgadget
If ua$<>""
*Ascii = Ascii(ua$)
iret=UrlMkSetSessionOption_(#URLMON_OPTION_USERAGENT, *ascii, StringByteLength(ua$)+SizeOf(character), 0)
Debug" Result:"+iret
FreeMemory(*ascii)
EndIf
Else
;- Todo
Debug "Not imüplemented"
EndIf
EndProcedure
Procedure.s webgadget_getUserAgent()
; Retrieve UserAgent used by webgadget
If webgadget_isEdge(gadget)=0;- IE based Webgadget
Protected *buffer=AllocateMemory(4096)
Protected ilen
Protected iret=UrlMkGetSessionOption(#URLMON_OPTION_USERAGENT, *buffer,4096,@ilen,0)
Protected sresult$=PeekS(*buffer,ilen,#PB_Ascii)
FreeMemory(*buffer)
ProcedureReturn sresult$
;- Todo
Debug "Not imüplemented"
EndIf
EndProcedure
;-Test --------------------------------------
CompilerIf #PB_Compiler_IsMainFile
DisableExplicit
Enumeration
#WEBGADGET=0
#BTN_SET_IE11
#BTN_SET_IEDEFAULT
#BTN_SET_EDGE
#BTN_EXECUTEJS
#BTN_GETVARIABLE
#BTN_SETVARIABLE
#BTN_CHECKISEDGE
#BTN_SETUA
#BTN_RESETUA
#BTN_CHECKBROWSER
#BTN_CHECKHTML5
EndEnumeration
Global HTML$ = ~"<html>" + #CRLF$
HTML$ + ~" <script language=\"JavaScript\">" + #CRLF$
HTML$ + ~" var global = \"1234\";" + #CRLF$
HTML$ + ~" " + #CRLF$
HTML$ + ~" function getdate(){return new Date();}" + #CRLF$
HTML$ + ~" function getnavigator(){return navigator.userAgent;}" + #CRLF$
HTML$ + ~" function test(a, b) {return parseInt(a)+parseInt(b);}"
HTML$ + ~" </script>" + #CRLF$
HTML$ + ~" <body>" + #CRLF$
HTML$ + ~" Test" + #CRLF$
HTML$ + ~" </body>" + #CRLF$
HTML$ + ~"</html>"
Procedure.s testScript(gadget)
a$=InputRequester("test script","Name of scripts (proc arg1,arg2)","getnavigator")
If a$<>""
scommand$=StringField(a$,1," ")
sparam$=ReplaceString(a$,scommand$+" ","")
ProcedureReturn webgadget_ExecuteJavaScript(gadget,scommand$,sparam$,",")
EndIf
EndProcedure
Procedure testSetVar(gadget)
a$=InputRequester("Set variable","Name of variable (proc arg1,arg2)","global=5")
If a$<>""
webgadget_SetJSVariable(gadget,StringField(a$,1,"="),StringField(a$,2,"="))
EndIf
EndProcedure
Procedure testGetVar(gadget)
a$=InputRequester("Check variable","Name of variable","global")
If a$<>""
MessageRequester("Ergebnis",webgadget_GetJSVariable(gadget,a$))
EndIf
EndProcedure
Procedure ResizeWebWindow()
ResizeGadget(#WEBGADGET, #PB_Ignore, #PB_Ignore, WindowWidth(0)-120, WindowHeight(0))
ResizeGadget(#BTN_SET_IE11, WindowWidth(0)-110, #PB_Ignore,#PB_Ignore,#PB_Ignore)
ResizeGadget(#BTN_SET_IEDEFAULT, WindowWidth(0)-110, #PB_Ignore,#PB_Ignore,#PB_Ignore)
ResizeGadget(#BTN_SET_EDGE, WindowWidth(0)-110, #PB_Ignore,#PB_Ignore,#PB_Ignore)
ResizeGadget(#BTN_SETUA, WindowWidth(0)-110, #PB_Ignore,#PB_Ignore,#PB_Ignore)
ResizeGadget(#BTN_RESETUA, WindowWidth(0)-110, #PB_Ignore,#PB_Ignore,#PB_Ignore)
ResizeGadget(#BTN_EXECUTEJS, WindowWidth(0)-110, #PB_Ignore,#PB_Ignore,#PB_Ignore)
ResizeGadget(#BTN_SETVARIABLE, WindowWidth(0)-110, #PB_Ignore,#PB_Ignore,#PB_Ignore)
ResizeGadget(#BTN_GETVARIABLE, WindowWidth(0)-110, #PB_Ignore,#PB_Ignore,#PB_Ignore)
ResizeGadget(#BTN_CHECKISEDGE, WindowWidth(0)-110, #PB_Ignore,#PB_Ignore,#PB_Ignore)
ResizeGadget(#BTN_CHECKBROWSER, WindowWidth(0)-110, #PB_Ignore,#PB_Ignore,#PB_Ignore)
ResizeGadget(#BTN_CHECKHTML5, WindowWidth(0)-110, #PB_Ignore,#PB_Ignore,#PB_Ignore)
EndProcedure
;Global surl$="https://www.cyscape.com/showbrow.asp"
Global sDefaultUserAgent$=""
;Global surl$="www.purebasic.com"
;Global surl$="https://whichbrowser.net/"
Global suseragent$=""
Global iWebFlag=0
Procedure NavigationCallback(Gadget, Url$)
If Left(Url$,11)="javascript:"
; ProcedureReturn #False
EndIf
ProcedureReturn #True
EndProcedure
Procedure SetWebGadget(gadget)
If IsGadget(gadget)
FreeGadget(gadget)
EndIf
UseGadgetList(WindowID(0))
CompilerIf #PB_Compiler_Version>604
WebGadget(gadget, 0, 0, WindowWidth(0),WindowHeight(0), surl$,iWebFlag)
CompilerElse
WebGadget(gadget, 0, 0, WindowWidth(0),WindowHeight(0), surl$)
CompilerEndIf
If sDefaultUserAgent$=""
sDefaultUserAgent$=webgadget_getUserAgent()
EndIf
If surl$=""
SetGadgetItemText(gadget, #PB_Web_HtmlCode, HTML$)
EndIf
Debug "Browser UA:"+webgadget_getUserAgent()
BindEvent(#PB_Event_SizeWindow, @ResizeWebWindow())
ResizeWebWindow() ; Adjust the gadget to the current window size
EndProcedure
If OpenWindow(0, 0, 600, 800, 600, "Browsertest", #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget|#PB_Window_ScreenCentered)
cy=20
ButtonGadget(#BTN_SET_IE11,150,cy,100,20,"Set to IE 11")
cy+30
ButtonGadget(#BTN_SET_IEDEFAULT,150,cy,100,20,"Set to Default")
cy+30
ButtonGadget(#BTN_SET_EDGE,150,cy,100,20,"Edge")
cy+30
CompilerIf #PB_Compiler_Version<604
DisableGadget(#BTN_SET_EDGE,#True)
CompilerEndIf
ButtonGadget(#BTN_SETUA,150,cy,100,20,"Set UserAgent")
cy+30
ButtonGadget(#BTN_RESETUA,150,cy,100,20,"ReSet UserAgent")
cy+30
ButtonGadget( #BTN_EXECUTEJS,150,cy,100,20,"Run Javascript")
cy+30
ButtonGadget( #BTN_SETVARIABLE,150,cy,100,20,"Set Variable")
cy+30
ButtonGadget( #BTN_GETVARIABLE,150,cy,100,20,"Get Variable")
cy+30
ButtonGadget( #BTN_CHECKISEDGE,150,cy,100,20," #PB_Web_Edge?")
cy+30
ButtonGadget(#BTN_CHECKHTML5,150,cy,100,20,"HTML5 Check")
cy+30
ButtonGadget(#BTN_CHECKBROWSER,150,cy,100,20,"Browserinfo")
cy+30
; Use bindevent() to have a realtime window resize
;
; SetGadgetAttribute(10, #PB_Web_NavigationCallback, @NavigationCallback())
SetWebGadget(#WEBGADGET)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case #BTN_SET_IE11
webgadget_SetExplorerFeatures(#WEBGADGET,"FEATURE_BROWSER_EMULATION",11001 )
MessageRequester("Browser Emulation changed","Browser set to IE11 mode. Please restart to reflect changes")
iWebFlag=0
SetWebGadget(#WEBGADGET)
Case #BTN_SET_IEDEFAULT
webgadget_SetExplorerFeatures(#WEBGADGET,"FEATURE_BROWSER_EMULATION",-1 )
MessageRequester("Browser Emulation changed","Browser set to default mode. Please restart to reflect changes ")
iWebFlag=0
SetWebGadget(#WEBGADGET)
Case #BTN_SET_EDGE
CompilerIf #PB_Compiler_Version>604
iWebFlag=#PB_Web_Edge
SetWebGadget(#WEBGADGET)
CompilerEndIf
Case #BTN_CHECKBROWSER
SetGadgetText(#WEBGADGET,"https://www.cyscape.com/showbrow.asp")
Case #BTN_CHECKHTML5
SetGadgetText(#WEBGADGET,"https://html5test.com/")
Case #BTN_SETUA
a$=InputRequester("User Agent","Please enter user Agent String","")
If a$<>""
webgadget_setUserAgent(#WEBGADGET,a$)
SetWebGadget(#WEBGADGET)
EndIf
Case #BTN_RESETUA
webgadget_setUserAgent(#WEBGADGET,sDefaultUserAgent$)
SetWebGadget(#WEBGADGET)
Case #BTN_EXECUTEJS
MessageRequester("Execute", "Result:"+TestScript(#WEBGADGET))
Case #BTN_SETVARIABLE
testSetVar(#WEBGADGET)
Case #BTN_GETVARIABLE
testGetVar(#WEBGADGET)
Case #BTN_CHECKISEDGE
MessageRequester("Test for #PB_Web_Edge", "Result:"+Str(webgadget_isEdge(#WEBGADGET)))
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
CloseLibrary(0)
EndIf
CompilerEndIf