Leaderboard
Popular Content
Showing content with the highest reputation on 02/23/2021 in all areas
-
This is yet another HTTP server written in AutoIt3. Originally based on jvanegmond's POST HTTP Server. It is designed to be used either as is, or by scripts for a HTTP communication between any browser and AutoIt3. It can run PHP and AutoIt3 CGI, if setup in the settings ini file. Github repository AutoIt-HTTP-Server-master.zip3 points
-
The ObjectFromTag() function is used to implement COM callback interfaces, pointers and objects. This is documentation for using the function. When talking about ObjectFromTag(), you cannot get around ObjCreateInterface(). ObjCreateInterface() was introduced in AutoIt version 3.3.8.0 (2011-12-23). The function is coded in the C/C++ language by trancexx. At the top of the official documentation there is a large warning box. A few comments on this warning: "This feature is experimental". No it's not. A function that has been used for more than 9 years to implement advanced code like the following is no longer experimental but has long proven its worth: IUIAutomation MS framework automate chrome, FF, IE, .... created by junkew August 2013 Newer versions of UIA code in this and other threads Using .NET library with AutoIt, possible? and several derived and advanced examples Implementing IRunningObjectTable Interface File/Windows Explorer examples Microsoft Edge - WebView2 As well as a myriad of other examples "It may not work, may contain bugs". The function works and it contains no bugs. This has long been proven by the examples above. "may be changed or removed without notice". On what grounds? The function works, contains no bugs, and adds lots of value to the AutoIt language. "DO NOT REPORT BUGS OR REQUEST NEW FEATURES FOR THIS FEATURE". There's really no reason for that. ObjectFromTag() is implemented as pure AutoIt code and is also made by trancexx. One of the first versions of the function is available in the Ribbon example. One of the latest versions of the function coded by trancexx is found in this post. Description tagsBoth ObjCreateInterface() and ObjectFromTag() use description tags to create objects with methods and properties. A description tag is a string that looks like this (the example of ObjCreateInterface()) $dTag_ITaskbarList = _ "HrInit hresult();" & _ "AddTab hresult(hwnd);" & _ "DeleteTab hresult(hwnd);" & _ "ActivateTab hresult(hwnd);" & _ "SetActiveAlt hresult(hwnd);" Here, the description tag is split into substrings for each method/property. ITaskbarList is the name of the COM interface. The name to the left of each substring is the name of the method/property. hresult in the middle is the method/property return type (always hresult for COM methods/properties), and the data types to the right in parentheses are parameter data types. If there are several parameters, the data types must be separated by a semi colon. Methods/properties of the description tag string must be in correct Vtable order. Vtable order In the Microsoft documentation for the ITaskbarList interface, methods/properties are listed in alphabetical order. But it's not possible to determine the correct Vtable order from this alphabetical list. The only way to determine the correct Vtable order is to study the interface in the appropriate C/C++ header file (shobjidl_core.h for ITaskbarList). All Microsoft header files are included in the Windows SDK. To access the header files, it's necessary to install the Windows SDK on your PC. The header files are located in the folder "E:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0" or similar. When you need a specific header file, it's easiest to search for it. shobjidl_core.h is found in the um subfolder. This is the definition of ITaskbarList in shobjidl_core.h: /* interface ITaskbarList */ /* [object][uuid] */ EXTERN_C const IID IID_ITaskbarList; #if defined(__cplusplus) && !defined(CINTERFACE) MIDL_INTERFACE("56FDF342-FD6D-11d0-958A-006097C9A090") ITaskbarList : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE HrInit( void) = 0; virtual HRESULT STDMETHODCALLTYPE AddTab( /* [in] */ __RPC__in HWND hwnd) = 0; virtual HRESULT STDMETHODCALLTYPE DeleteTab( /* [in] */ __RPC__in HWND hwnd) = 0; virtual HRESULT STDMETHODCALLTYPE ActivateTab( /* [in] */ __RPC__in HWND hwnd) = 0; virtual HRESULT STDMETHODCALLTYPE SetActiveAlt( /* [in] */ __RPC__in HWND hwnd) = 0; }; #else /* C style interface */ typedef struct ITaskbarListVtbl { BEGIN_INTERFACE HRESULT ( STDMETHODCALLTYPE *QueryInterface )( __RPC__in ITaskbarList * This, /* [in] */ __RPC__in REFIID riid, /* [annotation][iid_is][out] */ _COM_Outptr_ void **ppvObject); ULONG ( STDMETHODCALLTYPE *AddRef )( __RPC__in ITaskbarList * This); ULONG ( STDMETHODCALLTYPE *Release )( __RPC__in ITaskbarList * This); HRESULT ( STDMETHODCALLTYPE *HrInit )( __RPC__in ITaskbarList * This); HRESULT ( STDMETHODCALLTYPE *AddTab )( __RPC__in ITaskbarList * This, /* [in] */ __RPC__in HWND hwnd); HRESULT ( STDMETHODCALLTYPE *DeleteTab )( __RPC__in ITaskbarList * This, /* [in] */ __RPC__in HWND hwnd); HRESULT ( STDMETHODCALLTYPE *ActivateTab )( __RPC__in ITaskbarList * This, /* [in] */ __RPC__in HWND hwnd); HRESULT ( STDMETHODCALLTYPE *SetActiveAlt )( __RPC__in ITaskbarList * This, /* [in] */ __RPC__in HWND hwnd); END_INTERFACE } ITaskbarListVtbl; interface ITaskbarList { CONST_VTBL struct ITaskbarListVtbl *lpVtbl; }; The upper part of the definition is used in the C++ language. The lower part is used in the C language. When translating the definition to AutoIt, it's easiest to look at the C++ definition: /* interface ITaskbarList */ /* [object][uuid] */ EXTERN_C const IID IID_ITaskbarList; #if defined(__cplusplus) && !defined(CINTERFACE) MIDL_INTERFACE("56FDF342-FD6D-11d0-958A-006097C9A090") ITaskbarList : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE HrInit( void) = 0; virtual HRESULT STDMETHODCALLTYPE AddTab( /* [in] */ __RPC__in HWND hwnd) = 0; virtual HRESULT STDMETHODCALLTYPE DeleteTab( /* [in] */ __RPC__in HWND hwnd) = 0; virtual HRESULT STDMETHODCALLTYPE ActivateTab( /* [in] */ __RPC__in HWND hwnd) = 0; virtual HRESULT STDMETHODCALLTYPE SetActiveAlt( /* [in] */ __RPC__in HWND hwnd) = 0; }; Note that the order of the methods in the description tag string above corresponds to the order of the methods in the C++ definition. Names of methods/properties and the correct Vtable order can be copied directly from the C++ definition. Parameter data types The parameter data types that can be used in the description tag string are listed in the ObjCreateInterface() documentation. Both the header file and the Microsoft documentation can be used to help you find the right data types. In many cases, the data type in the header file or Microsoft documentation corresponds directly to one of the data types in the ObjCreateInterface() documentation. In other cases, it's necessary to translate the data type to one of the valid AutoIt data types. Filling in the parameter data types is the most time consuming task of creating the description tag string. Fortunately, it's enough to fill in the data types for the methods/properties you actually need. For methods/properties you don't need, you can simply enter an empty parenthesis, as is the case in the "HrInit hresult();" substring (in this case because HrInit doesn't actually take any parameters). You can omit the parameter data types for methods/properties that are not to be used in the first place, but all methods/properties must be specified in the correct Vtable order. IUnknown interface All COM interfaces inherits from the IUnknown interface. It's indicated in the C++ definition by this line ITaskbarList : public IUnknown Because all COM interfaces inherits from the IUnknown interface, don't specify IUnknown methods/properties in the description tag string. IUnknown methods/properties are added automatically in both ObjCreateInterface() and ObjectFromTag() functions. $sIID and $sCLSID Note that this line in the AutoIt code $sIID_ITaskbarList = "{56FDF342-FD6D-11D0-958A-006097C9A090}" corresponds to this line in the C++ definition MIDL_INTERFACE("56FDF342-FD6D-11D0-958A-006097C9A090") And that this line in the AutoIt code $sCLSID_TaskbarList = "{56FDF344-FD6D-11D0-958A-006097C9A090}" corresponds to these lines in the C++ definition (further down in the header file) class DECLSPEC_UUID("56FDF344-FD6D-11D0-958A-006097C9A090") TaskbarList; ObjectFromTag() functionThe version of ObjectFromTag() that I'm using is based on this version by trancexx. My first version is contained in the 7z-file below and coded in ObjectFromTag-a.au3 dated 2014-01-14. My current version is coded in ObjectFromTag.au3 dated 2021-02-06. The function is defined as follows: Func ObjectFromTag( _ $sFunctionPrefix, _ ; Presents methods/properties with the same prefix name $tagInterface, _ ; Interface description tag string ByRef $tInterface, _ ; Interface struct (DllStruct) $bObject = True, _ ; Return object or object pointer $bPrint = False, _ ; Print information in SciTE console $bIsUnknown = True, _ ; Inherits from the IUnknown interface $sIID = "{00000000-0000-0000-C000-000000000046}" ) ; $sIID_IUnknown ObjectFromTag() exampleAs an example of using the function, I'll show how to create the first part of the WebView2-1.au3 example here (WebView2-1-0.au3, all required code and files are contained in the 7z-file below). According to the Getting started with WebView2 example, the prerequisites for running the code are installing the Microsoft Edge Chromium version and the WebView2 Runtime (Evergreen Bootstrapper). #AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=y Opt( "MustDeclareVars", 1 ) #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <WinAPICom.au3> #include <WinAPI.au3> Global $hGui ; Project includes #include "..\Includes\WV2Interfaces.au3" WebView2() Func WebView2() ; Create WebView2 GUI $hGui = GUICreate( "WebView2 Sample", 1200, 900, -1, -1, $WS_OVERLAPPEDWINDOW ) ; Initialize COM _WinAPI_CoInitialize( $COINIT_APARTMENTTHREADED ) ; Create callback interfaces and functions CoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerCreate( True ) ; DllCall CreateCoreWebView2EnvironmentWithOptions Local $hWebView2Loader = DllOpen( @AutoItX64 ? "WebView2Loader-x64.dll" : "WebView2Loader-x86.dll" ) Local $aRet = DllCall( $hWebView2Loader, "long", "CreateCoreWebView2EnvironmentWithOptions", "wstr", "", "wstr", "", _ "ptr", NULL, "ptr", $pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler ) ; Forces CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke() below to be executed If @error Or $aRet[0] Then Return ConsoleWrite( "CreateCoreWebView2EnvironmentWithOptions ERR" & @CRLF ) ConsoleWrite( "CreateCoreWebView2EnvironmentWithOptions OK" & @CRLF & @CRLF ) ; Show WebView2 GUI GUISetState( @SW_SHOW ) ; Loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup CoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerDelete() DllClose( $hWebView2Loader ) EndFunc ; Copied from WV2Interfaces.au3 ; Executed as a consequence of the DllCall() function above Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke( $pSelf, $long, $ptr ) ; Ret: long Par: long;ptr* ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke" & @CRLF ) Return 0 ; S_OK = 0x00000000 #forceref $pSelf, $long, $ptr EndFunc The code can be run without errors. However, since it's only about half of all the code, an empty window without web content is displayed. A crucial point, of course, is to create this code from scratch. I've read the WebView2 documentation and especially the API reference documentation and studied the HelloWebView.cpp and WebView2.ahk examples (contained in the 7z-file). By running the examples and adding "ConsoleWrites" to the code, I've found that the examples can be translated to AutoIt code as shown. Because the WebView2 code is new code that's still under development, the WebView2.h header file isn't included in the Windows SDK. WebView2.h can instead be downloaded in a NuGet package as described in the WebView2 documentation. I'll focus on this part of the code: ; Create callback interfaces and functions CoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerCreate( True ) The code creates the CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler callback interface and its functions. CoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerCreate() in WV2Interfaces.au3: Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerCreate( $bPrint = False ) $pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler = _ ObjectFromTag( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_", _ $dtag_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, _ $tCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, False, $bPrint ) If $bPrint Then ConsoleWrite( "$pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler = " & _ $pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler & @CRLF & @CRLF ) EndFunc The function executes ObjectFromTag(), which creates the callback interface and its functions. Note the False parameter just before $bPrint. False means that ObjectFromTag() returns an object pointer instead of the object itself. It seems that all WebView2 callback interfaces are created from an object pointer and not the object itself. Implement these steps to create the callback interface and its functions: Step 1: Create the description tag for ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler callback interface Step 2: Execute ObjectFromTag() with the $bPrint = True parameter Step 3: Copy the functions printed in the SciTE console into the code and run the code again Step 4: Continue executing ObjectFromTag() and copy the functions until there are no more errors Step 5: Test the code to check if the interface functions are called as expected Step 1The $dtag for the ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler callback interface can be created based on the information in WebView2.h (search the interface) and the Microsoft documentation (google the interface): Global Const $dtag_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler = _ "Invoke hresult(hresult;ptr*);" Step 2Execute ObjectFromTag() with the $bPrint = True parameter this way (WebView2-1-1.au3) #AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=y Opt( "MustDeclareVars", 1 ) #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <WinAPICom.au3> #include <WinAPI.au3> Global $hGui Global $pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, _ $tCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler Global Const $dtag_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler = _ "Invoke hresult(hresult;ptr*);" ; Project includes ;#include "..\Includes\WV2Interfaces.au3" #include "..\Includes\ObjectFromTag.au3" WebView2() Func WebView2() ; Create WebView2 GUI $hGui = GUICreate( "WebView2 Sample", 1200, 900, -1, -1, $WS_OVERLAPPEDWINDOW ) ; Initialize COM _WinAPI_CoInitialize( $COINIT_APARTMENTTHREADED ) ; Create callback interfaces and functions $pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler = _ ObjectFromTag( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_", _ $dtag_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, _ $tCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, False, True ) ; $bPrint = True ; Show WebView2 GUI GUISetState( @SW_SHOW ) ; Loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup EndFunc SciTE console output: Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface( $pSelf, $pRIID, $pObj ) ; Ret: long Par: ptr;ptr* ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface()" & @CRLF & @CRLF ) Return 0 ; S_OK = 0x00000000 #forceref $pSelf, $pRIID, $pObj EndFunc @error = 3 Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_AddRef( $pSelf ) ; Ret: dword ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_AddRef()" & @CRLF & @CRLF ) Return 1 ; For AddRef/Release #forceref $pSelf EndFunc @error = 3 Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Release( $pSelf ) ; Ret: dword ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Release()" & @CRLF & @CRLF ) Return 1 ; For AddRef/Release #forceref $pSelf EndFunc @error = 3 Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke( $pSelf, $long, $ptr ) ; Ret: long Par: long;ptr* ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke()" & @CRLF & @CRLF ) Return 0 ; S_OK = 0x00000000 #forceref $pSelf, $long, $ptr EndFunc @error = 3 @error = 3 is an error code from DllCallbackRegister() in the ObjectFromTag() function and apparently means that the functions don't exist. Step 3Copy the four functions into the code and run the code again (WebView2-1-2.au3, delete @error = 3 lines): #AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=y Opt( "MustDeclareVars", 1 ) #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <WinAPICom.au3> #include <WinAPI.au3> Global $hGui Global $pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, _ $tCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler Global Const $dtag_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler = _ "Invoke hresult(hresult;ptr*);" ; Project includes ;#include "..\Includes\WV2Interfaces.au3" #include "..\Includes\ObjectFromTag.au3" WebView2() Func WebView2() ; Create WebView2 GUI $hGui = GUICreate( "WebView2 Sample", 1200, 900, -1, -1, $WS_OVERLAPPEDWINDOW ) ; Initialize COM _WinAPI_CoInitialize( $COINIT_APARTMENTTHREADED ) ; Create callback interfaces and functions $pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler = _ ObjectFromTag( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_", _ $dtag_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, _ $tCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, False, True ) ; $bPrint = True ; Show WebView2 GUI GUISetState( @SW_SHOW ) ; Loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup EndFunc Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface( $pSelf, $pRIID, $pObj ) ; Ret: long Par: ptr;ptr* ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface()" & @CRLF & @CRLF ) Return 0 ; S_OK = 0x00000000 #forceref $pSelf, $pRIID, $pObj EndFunc Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_AddRef( $pSelf ) ; Ret: dword ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_AddRef()" & @CRLF & @CRLF ) Return 1 ; For AddRef/Release #forceref $pSelf EndFunc Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Release( $pSelf ) ; Ret: dword ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Release()" & @CRLF & @CRLF ) Return 1 ; For AddRef/Release #forceref $pSelf EndFunc Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke( $pSelf, $long, $ptr ) ; Ret: long Par: long;ptr* ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke()" & @CRLF & @CRLF ) Return 0 ; S_OK = 0x00000000 #forceref $pSelf, $long, $ptr EndFunc SciTE console output: Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface( $pSelf, $pRIID, $pObj ) ; Ret: long Par: ptr;ptr* ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface()" & @CRLF & @CRLF ) Return 0 ; S_OK = 0x00000000 #forceref $pSelf, $pRIID, $pObj EndFunc @error = 0 Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_AddRef( $pSelf ) ; Ret: dword ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_AddRef()" & @CRLF & @CRLF ) Return 1 ; For AddRef/Release #forceref $pSelf EndFunc @error = 0 Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Release( $pSelf ) ; Ret: dword ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Release()" & @CRLF & @CRLF ) Return 1 ; For AddRef/Release #forceref $pSelf EndFunc @error = 0 Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke( $pSelf, $long, $ptr ) ; Ret: long Par: long;ptr* ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke()" & @CRLF & @CRLF ) Return 0 ; S_OK = 0x00000000 #forceref $pSelf, $long, $ptr EndFunc @error = 0 Step 4No more errors. We're done. The callback interface and its functions are implemented. Step 5Check if the interface functions are called as expected (WebView2-1-3.au3) #AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=y Opt( "MustDeclareVars", 1 ) #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <WinAPICom.au3> #include <WinAPI.au3> Global $hGui Global $pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, _ $tCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler Global Const $dtag_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler = _ "Invoke hresult(hresult;ptr*);" ; Project includes ;#include "..\Includes\WV2Interfaces.au3" #include "..\Includes\ObjectFromTag.au3" WebView2() Func WebView2() ; Create WebView2 GUI $hGui = GUICreate( "WebView2 Sample", 1200, 900, -1, -1, $WS_OVERLAPPEDWINDOW ) ; Initialize COM _WinAPI_CoInitialize( $COINIT_APARTMENTTHREADED ) ; Create callback interfaces and functions $pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler = _ ObjectFromTag( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_", _ $dtag_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, _ $tCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, False, True ) ; $bPrint = True ; DllCall CreateCoreWebView2EnvironmentWithOptions Local $hWebView2Loader = DllOpen( @AutoItX64 ? "WebView2Loader-x64.dll" : "WebView2Loader-x86.dll" ) Local $aRet = DllCall( $hWebView2Loader, "long", "CreateCoreWebView2EnvironmentWithOptions", "wstr", "", "wstr", "", _ "ptr", NULL, "ptr", $pCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler ) ; Forces CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke() below to be executed If @error Or $aRet[0] Then Return ConsoleWrite( "CreateCoreWebView2EnvironmentWithOptions ERR" & @CRLF ) ConsoleWrite( "CreateCoreWebView2EnvironmentWithOptions OK" & @CRLF & @CRLF ) ; Show WebView2 GUI GUISetState( @SW_SHOW ) ; Loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; Cleanup DllClose( $hWebView2Loader ) EndFunc Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface( $pSelf, $pRIID, $pObj ) ; Ret: long Par: ptr;ptr* ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface()" & @CRLF & @CRLF ) Return 0 ; S_OK = 0x00000000 #forceref $pSelf, $pRIID, $pObj EndFunc Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_AddRef( $pSelf ) ; Ret: dword ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_AddRef()" & @CRLF & @CRLF ) Return 1 ; For AddRef/Release #forceref $pSelf EndFunc Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Release( $pSelf ) ; Ret: dword ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Release()" & @CRLF & @CRLF ) Return 1 ; For AddRef/Release #forceref $pSelf EndFunc Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke( $pSelf, $long, $ptr ) ; Ret: long Par: long;ptr* ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke()" & @CRLF & @CRLF ) Return 0 ; S_OK = 0x00000000 #forceref $pSelf, $long, $ptr EndFunc SciTE console output: Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface( $pSelf, $pRIID, $pObj ) ; Ret: long Par: ptr;ptr* ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface()" & @CRLF & @CRLF ) Return 0 ; S_OK = 0x00000000 #forceref $pSelf, $pRIID, $pObj EndFunc @error = 0 Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_AddRef( $pSelf ) ; Ret: dword ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_AddRef()" & @CRLF & @CRLF ) Return 1 ; For AddRef/Release #forceref $pSelf EndFunc @error = 0 Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Release( $pSelf ) ; Ret: dword ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Release()" & @CRLF & @CRLF ) Return 1 ; For AddRef/Release #forceref $pSelf EndFunc @error = 0 Func CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke( $pSelf, $long, $ptr ) ; Ret: long Par: long;ptr* ConsoleWrite( "CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke()" & @CRLF & @CRLF ) Return 0 ; S_OK = 0x00000000 #forceref $pSelf, $long, $ptr EndFunc @error = 0 CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_AddRef() CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke() CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Release() CreateCoreWebView2EnvironmentWithOptions OK Output looks as expected - even if CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_QueryInterface() isn't called. If you get a CreateCoreWebView2EnvironmentWithOptions ERR from the DllCall() function and you're sure that the function is coded correctly, read this post by Chimp for a description and solution to the problem. Note that for all WebView2 callback interfaces, it seems that the Invoke() method is interesting, while the other methods/properties aren't so interesting. To proceed with the WebView2-1.au3 example (included as WebView2-1-a.au3) add code in the CoreWebView2CreateCoreWebView2EnvironmentCompletedHandler_Invoke() function. 7z-fileThe 7z-file contains source code for the UDF and examples and other files needed to run the code. You need AutoIt 3.3.12 or later. Tested on Windows 7 and Windows 10. Comments are welcome. Let me know if there are any issues. ObjectFromTag.7z2 points
-
Step through and rewrite Json
AspirinJunkie and one other reacted to TheXman for a topic
First, thank you for mentioning jq. The only issue with your example is that the result will only be the selected keys' object values without their keys. If I understood the OP correctly, the result should be a complete, modified json configuration file. The example below, using jq, shows one way to replace just the specified values while leaving the rest of the data as-is. For brevity, I've condensed the json source but kept the relevant fields. I have also assumed that the original json snippet was of a json object with multiple key/value pairs. If it was supposed to be an array of json objects, it would be a simple modification to the jq filter to get the required result. #cs This example uses the jq UDF. https://www.autoitscript.com/forum/files/file/502-jq-udf-a-powerful-flexible-json-processor/ #ce #include <Constants.au3> #include <jq.au3> ;<== Modify as needed Const $JSON_DATA = '{"x-ID.0":{"name":"Fox 2 KTVI","x-update-channel-icon":false,"x-update-channel-name":false,"x-description":""},"x-ID.1":{"name":"CBS 4 KMOV","x-name":"CBS 4 | HD","x-update-channel-icon":false,"x-update-channel-name":false,"x-description":""}}' Const $JQ_FILTER = 'walk( ' & _ ' if (.name? // ""| startswith("Fox 2") ) then ' & _ ' (."x-update-channel-icon" = true | ."x-update-channel-name" = true) ' & _ ' else ' & _ ' . ' & _ ' end ' & _ ')' ;Initialize jq _jqInit("C:\<path to jq executable>\jq-win64.exe") ;<== Modify as needed If @error Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", "ERROR: Unable to initialize jq - @error = " & @error) ;Replace specified values $sCmdOutput = _jqExec($JSON_DATA, $JQ_FILTER) ;Display results ConsoleWrite("Before:" & @CRLF) ConsoleWrite(_jqPrettyPrintJson($JSON_DATA) & @CRLF) ConsoleWrite(@CRLF) ConsoleWrite("After:" & @CRLF) ConsoleWrite($sCmdOutput & @CRLF) Console output Before: { "x-ID.0": { "name": "Fox 2 KTVI", "x-update-channel-icon": false, "x-update-channel-name": false, "x-description": "" }, "x-ID.1": { "name": "CBS 4 KMOV", "x-name": "CBS 4 | HD", "x-update-channel-icon": false, "x-update-channel-name": false, "x-description": "" } } After: { "x-ID.0": { "name": "Fox 2 KTVI", "x-update-channel-icon": true, "x-update-channel-name": true, "x-description": "" }, "x-ID.1": { "name": "CBS 4 KMOV", "x-name": "CBS 4 | HD", "x-update-channel-icon": false, "x-update-channel-name": false, "x-description": "" } }2 points -
Anybody could help with using QueryInterface in AutoIt to embed Microsoft Edge using WebView2 Interface ? Here are links to information/documentation: Image comes from: https://docs.microsoft.com/en-us/microsoft-edge/webview2/media/webview2/whatwebview.png Introduction to Microsoft Edge WebView2 https://docs.microsoft.com/en-us/microsoft-edge/webview2/ Understand WebView2 SDK versions https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/versioning Download: https://developer.microsoft.com/en-US/microsoft-edge/webview2/ https://developer.microsoft.com/en-US/microsoft-edge/webview2/#download-section https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution API Reference: https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/?view=webview2-1.0.622.22 HowTo/Concepts: https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/versioning https://docs.microsoft.com/en-us/microsoft-edge/webview2/gettingstarted/win32 https://docs.microsoft.com/en-us/microsoft-edge/webview2/howto/debug?tabs=devtools https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/security https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/userdatafolder https://mybuild.microsoft.com/sessions/9198aeac-0c8e-4d32-96d1-cbb99a390aa6 Example: https://github.com/MicrosoftEdge/WebView2Samples Related: https://www.essentialobjects.com/Products/WebBrowser/Default.aspx?gclid=CjwKCAiA17P9BRB2EiwAMvwNyMe6UI9VHej-JYDBUoyGDFz40KaaJ_RidY-75Fhr-PHz65sSVC0XlxoC5loQAvD_BwE https://docs.microsoft.com/en-us/microsoft-edge/webview2/howto/webdriver btw. I'm not WindowsApi expert (QueryInterface, C++, DllCall). What I trying to say is: It means that I do not done anything in this regards .... as so far. TIMELINE/ChangeLog: 2020-11-12 - Project propsed by @mLipok 2021-02-03 - First version provided by @LarsJ1 point
-
[Solved] struct _WTSINFO
argumentum reacted to Nine for a topic
Ok seems to be working well : Local $sString = _WTSQuerySessionInformation($i, 24, 1) Local $dData = Binary($sString) ConsoleWrite ($dData & @CRLF) $tByte = DllStructCreate("byte string[" & BinaryLen($dData) & "]") Const $WINSTATIONNAME_LENGTH = 32 Const $DOMAIN_LENGTH = 17 Const $USERNAME_LENGTH = 20 DllStructSetData($tByte, 1, $dData) Const $tagWTSINFOA = "BYTE state;DWORD SessionId;DWORD IncomingBytes;DWORD OutgoingBytes;DWORD IncomingFrames;DWORD OutgoingFrames;" & _ "DWORD IncomingCompressedBytes;DWORD OutgoingCompressedBy;CHAR WinStationName[32];CHAR Domain[17];CHAR UserName[21];" & _ "INT64 ConnectTime;INT64 DisconnectTime;INT64 LastInputTime;INT64 LogonTime;INT64 CurrentTime;" $tWTSINFOA = DllStructCreate($tagWTSINFOA, DllStructGetPtr($tByte)) ConsoleWrite ($tWTSINFOA.WinStationName & @CRLF)1 point -
[Solved] struct _WTSINFO
argumentum reacted to UEZ for a topic
You can read out the binary value of WTSSessionInfo and put it to a ubyte array struct. Afterwards just create the _WTSINFOA and map it the binary string. Something like this here: Global $a = ListUserSessions() $t24 = DllStructCreate("ubyte mem[" & BinaryLen(_WTSQuerySessionInformation($i, 24, 1)) / 2 & "]") $t24.mem = _WTSQuerySessionInformation($i, 24, 1) $tag = "int State;dword State;dword IncomingBytes;dword OutgoingBytes;dword IncomingFrames;dword OutgoingFrames;dword IncomingCompressedBytes;dword OutgoingCompressedBy;" & _ "ubyte WinStationName[12];ubyte Domain[3];ubyte UserName[7];int64 ConnectTime;int64 DisconnectTime;int64 LastInputTime;int64 LogonTime;int64 LogonTime" $t = DllStructCreate($tag, DllStructGetPtr($t24)) _WinAPI_DisplayStruct($t, $tag) You have to set the length of arrays WinStationName, Domain and UserName accordingly. I hope it helps.1 point -
Step through and rewrite Json
TheXman reacted to AspirinJunkie for a topic
Ah now i see the difference in our results. You're completely right - I simply did not look closely at my result. Since this was the very first time I ever dealt with jq, I assumed anyway that improvements to my approach were needed.1 point -
Try this : $oIE = _IECreate(......) $oDiv2 = _IEGetObjById($oIE, "tab4-2") If Not IsObj($oDiv2) Then Exit MsgBox($MB_SYSTEMMODAL, "", "not an object") $objs = _IETagNameGetCollection($oDiv2, "div") For $obj In $objs If $obj.title = "Cayman Islands - George Town" Then _IEAction($obj, "click") _IELoadWait($oIE, 2000) ExitLoop EndIf Next1 point
-
Script Work on multiple Windows
WillFerraz reacted to Nine for a topic
Run("Notepad") $hWnd = WinWait("[CLASS:Notepad]") WinSetState($hWnd, "", @SW_MINIMIZE) Sleep(1000) ControlSetText($hWnd, "", "Edit1", "This was set") ControlSend($hWnd, "", "Edit1", "This was send") You can set/send text to minimize windows at the condition you can know the control ID of the field you want to fill1 point -
Break a Query Possible ?
pixelsearch reacted to dmob for a topic
You could try _GUICtrlListView_AddArray, in some cases its quicker, assuming yr data is in an array.1 point -
EasyCodeIt - cross-platform AutoIt implementation
seadoggie01 reacted to TheDcoder for a topic
This is an open invitation to anyone who is interested in getting involved with development. I think it is a good time to start seeking help from other experienced programmers to speed up development on EasyCodeIt. Tagging all users who voted "I am willing to work on the code" on the original thread's poll: @genius257 @StandardUser @KhalidAnsari @seadoggie01 @Surya @MattHiggs Knowledge of C is not required, sharing ideas and suggestions also counts I request those who are interested to make an account in the dedicated forum (link in my signature, see last post for details) and post in the latest progress thread You can also join the chatroom in Matrix, see the first post for details.1 point -
Step through and rewrite Json
TheXman reacted to AspirinJunkie for a topic
There exists also a json-processor UDF for manipulate json: jq-udf Admittedly, the syntax is not very intuitive, but this is how it could work with this UDF: #include "jq.au3" $data = FileRead("Test2.json") _jqInit() $sCmdOutput = _jqExec($data, '.[] | (objects | select(.name | contains("Fox 2")) | ."x-update-channel-icon" = true) // . ') ConsoleWrite($sCmdOutput)1 point -
Break a Query Possible ?
pixelsearch reacted to jchd for a topic
Add a LIMIT n clause to your query, so that at most n rows are returned and fed to the ListView. Since it's the time spent filling the listview with a large number of rows which can be an issue when unsufficient filtering is setup, the problem lies in the code filling of the ListView, hence in your own AutoIt code instead of the SQL query. Besides, a listview with thousands of rows is essentially unmanageable. Using a reasonnable n, e.g. LIMIT 200, clause would probably do.1 point -
Problems with simple GUISetOnEvent
FrancescoDiMuro reacted to Jos for a topic
You simply need to learn to open the helpfile and try to understand before posting these kind of questions, as the examples in there are quit elaborate! ..so study first and try to understand it..... but an GUI won't magically appear unless you code it.1 point -
Break a Query Possible ?
pixelsearch reacted to Skysnake for a topic
Perhaps you are using the wrong tool to solve this problem? Most users have no idea how much data is involved in a query. Timeouts (both session / connection and query time outs) can be set. Generally the SQL query will return very quickly and the delay occurs during the AutoIt processing / display, which is genrally done in a loop. Simply build the break check into the AutoIt loop.1 point -
Welcome to the AutoIt forum. Normally you should come up with a basic script so we can be able to help in solving issues you are facing. BUT since it is your first time here and it is such an easy script, it would take me longer to explain what you should be doing than giving a frame that you could work on. Next time, please, make an effort to create a runable script that we actually can execute. If you still need help, provide example files that you want to modify. #include <File.au3> Local $aRoot[] = ["c:\Apps\Temp\","c:\users\" & @UserName & "AppData\local\"] ; add as much root folders as you want here Local $aFile, $sFile, $sContent, $sDrive, $sDir, $sFileName, $sExtension For $sFolder in $aRoot ConsoleWrite ($sFolder & @CRLF) $aFile = _FileListToArrayRec($sFolder, "*.HOD;*.WS", $FLTAR_FILES, $FLTAR_RECUR, Default, $FLTAR_FULLPATH) If @error Then ContinueLoop For $i = 1 To $aFile[0] $sFile = $aFile[$i] $sContent = FileRead($sFile) _PathSplit($sFile, $sDrive, $sDir, $sFileName, $sExtension) If $sExtension = ".HOD" Then $sContent = StringRegExpReplace($sContent, "(?is)(Host=)(\d+\.\d+\.\d+\.\d+)","$1DNSNAME") Else $sContent = StringRegExpReplace($sContent, "(?is)(HostName=)(\d+\.\d+\.\d+\.\d+)","$1DNSNAME") EndIf FileWrite($sDrive & $sDir & "New_" & $sFileName & $sExtension, $sContent) Next Next1 point
-
Moved to the appropriate forum. Moderation Team1 point
-
"One gui to rule all these pixels, one gui to find them, one gui to bring them all and in an array bind them"1 point
-
[Solved] Create borders around excel range
kawumm3000 reacted to AnonymousX for a topic
Thanks Water. Didn't figure out a way to turn it into a one liner of code, to get just outside border for range, but can now get it to work with writing something for every case (Top, Bot, Left, Right). Also from what you sent was able to write something to get all borders without having to write a line for top, bot, left, right. Might be useful to someone in the future ;Equivalent to "All Borders" for range given $oExcel.ActiveSheet.range("F2:G3").Borders.LineStyle = 11 point -
[Solved] Create borders around excel range
kawumm3000 reacted to water for a topic
The needed enumerations to create this variables can be found here: https://msdn.microsoft.com/en-us/vba/excel-vba/articles/xlbordersindex-enumeration-excel and here https://msdn.microsoft.com/en-us/vba/excel-vba/articles/xlborderweight-enumeration-excel1 point -
Have a look at this example: The script to compile, then Run and you like to close gracefully: OnAutoItExitRegister("OnAutoItExit") AutoItWinSetTitle("testing") While 1 sleep(50) WEnd Func OnAutoItExit() MsgBox(0,"testing closing","test") EndFunc ;==>OnAutoItExit The AutoIt3 command to close it gracefully: WinClose("testing") Jos1 point
-
Hi all! I made this script because this script don`t work for me. I tested below script on several computers and this work fine. But i want that you tested this script. Waiting for your comments. _ScreenSetting(1024, 768, 32, 100) ;==================================================================================== ; ;Function Name: _ScreenSetting() ;Description: Changes the screen resolution, color dept and refresh rate ;Version: 1.0 ;Parameters: $iWidth - Width of the desktop screen in pixels. (horizontal resolution) ; $iHeight - Height of the desktop screen in pixels. (vertical resolution) ; $iDepth - Depth of the desktop screen in bits per pixel. ; $iRefresh - Refresh rate of the desktop screen in hertz. ;Return Value(s): On Success - Screen is adjusted ; On failure - Message with error description ;Requirement(s): Tested on AutoIt 3.2.10.0 ;Autor(s): R.Gilman (a.k.a rasim); special thanks to amel27 ; ;==================================================================================== Func _ScreenSetting($iWidth = @DesktopWidth, $iHeight = @DesktopHeight, $iDepth = @DesktopDepth, $iRefresh = @DesktopRefresh) Local Const $DISP_CHANGE_SUCCESSFUL = 0 Local Const $DISP_CHANGE_RESTART = 1 Local Const $DISP_CHANGE_FAILED = -1 Local Const $DISP_CHANGE_BADMODE = -2 Local Const $DISP_CHANGE_NOTUPDATED = -3 Local Const $DISP_CHANGE_BADFLAGS = -4 Local Const $DISP_CHANGE_BADPARAM = -5 Local Const $CDS_TEST = 0x4 Local Const $CDS_UPDATEREGISTRY = 0x1 Local Const $DM_PELSWIDTH = 0x80000 Local Const $DM_PELSHEIGHT = 0x100000 Local Const $DM_BITSPERPEL = 0x40000 Local Const $DM_DISPLAYFREQUENCY = 0x400000 Local Const $ENUM_CURRENT_SETTINGS = -1 Local Const $WM_DISPLAYCHANGE = 0x007E Local Const $HWND_BROADCAST = 0xFFFF Local Const $SPI_SETNONCLIENTMETRICS = 0x2A Local $DEVMODE, $DllRet $DEVMODE = DllStructCreate("char dmDeviceName[32];ushort dmSpecVersion;ushort dmDriverVersion;short dmSize;" & _ "ushort dmDriverExtra;dword dmFields;short dmOrientation;short dmPaperSize;short dmPaperLength;" & _ "short dmPaperWidth;short dmScale;short dmCopies;short dmDefaultSource;short dmPrintQuality;" & _ "short dmColor;short dmDuplex;short dmYResolution;short dmTTOption;short dmCollate;" & _ "byte dmFormName[32];dword dmBitsPerPel;int dmPelsWidth;dword dmPelsHeight;" & _ "dword dmDisplayFlags;dword dmDisplayFrequency") $DllRet = DllCall("user32.dll", "int", "EnumDisplaySettings", "ptr", 0, "dword", $ENUM_CURRENT_SETTINGS, _ "ptr", DllStructGetPtr($DEVMODE)) $DllRet = $DllRet[0] If $DllRet = 0 Then MsgBox(16, "Error", "Unable to get graphic mode") Return False EndIf $VGA_MAP_KEY = RegRead("HKLM\HARDWARE\DEVICEMAP\VIDEO", "\Device\Video0") $VGA_KEY = StringReplace($VGA_MAP_KEY, "\Registry\Machine", "HKLM") RegWrite($VGA_KEY, "PruningMode", "REG_DWORD", 0) DllStructSetData($DEVMODE, "dmSize", DllStructGetSize($DEVMODE)) DllStructSetData($DEVMODE, "dmPelsWidth", $iWidth) DllStructSetData($DEVMODE, "dmPelsHeight", $iHeight) DllStructSetData($DEVMODE, "dmBitsPerPel", $iDepth) DllStructSetData($DEVMODE, "dmDisplayFrequency", $iRefresh) DllStructSetData($DEVMODE, "dmFields", BitOR($DM_PELSWIDTH, $DM_PELSHEIGHT, $DM_BITSPERPEL, $DM_DISPLAYFREQUENCY)) $DllRet = DllCall("user32.dll", "int", "ChangeDisplaySettings", "ptr", DllStructGetPtr($DEVMODE), "int", $CDS_TEST) $DllRet = $DllRet[0] If $DllRet <> $DISP_CHANGE_SUCCESSFUL Then Switch $DllRet Case $DISP_CHANGE_RESTART MsgBox(48, "Warning", "Restart your computer for change display settings") Case $DISP_CHANGE_FAILED MsgBox(16, "Error", "The video driver not set a new mode") Return False Case $DISP_CHANGE_BADMODE MsgBox(16, "Error", "Video mode not supported") Return False Case $DISP_CHANGE_NOTUPDATED MsgBox(16, "Error", "Unable to write in registry") Return False Case $DISP_CHANGE_BADFLAGS MsgBox(16, "Error", "Bad flags") Return False Case $DISP_CHANGE_BADPARAM MsgBox(16, "Error", "Bad parameters") Return False EndSwitch EndIf $DllRet = DllCall("user32.dll", "int", "ChangeDisplaySettings", "ptr", DllStructGetPtr($DEVMODE), "int", $CDS_UPDATEREGISTRY) $DllRet = $DllRet[0] DllCall("user32.dll", "int", "SendMessage", "hwnd", $HWND_BROADCAST, "int", $WM_DISPLAYCHANGE, _ "int", $SPI_SETNONCLIENTMETRICS, "int", 0) RegWrite($VGA_KEY, "PruningMode", "REG_DWORD", 1) $DEVMODE = "" $DllRet = "" EndFunc1 point