Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/25/2021 in all areas

  1. GUIs of interest here are non-AutoIt GUIs not created with GUICreate(). They are created with Windows API functions eg. _WinAPI_CreateWindowEx(). (2020-04-26) Is it possible in such a non-AutoIt GUI to implement a Windows message loop? Which functionality and techniques do and do not work in such non-AutoIt GUIs? Which internal functions can be used? Can AutoIt and non-AutoIt GUIs exist side by side in the same script? Can existing UDFs be used? This example started last week with inspiration from this thread. After several tests during the week, I've decided to make a little more of the example. This is an update of first post. Over the coming weeks I'll be adding more code in new posts. If it all works well and stable, the ideas in the project may be seen in a wider perspective. Some information has been deleted during this update. The information will be added again later. Basic functionality What is a Windows message loop In Microsoft documentation, a message loop is usually coded like this: while GetMessage(&msg, 0, 0, 0) { // Retrieve a message from the message queue // Processes accelerator keystrokes if (!TranslateAccelerator( hwndMain, // handle to receiving window haccel, // handle to active accelerator table &msg)) // message data { TranslateMessage(&msg); // Translate a virtual-key message into a character message DispatchMessage(&msg); // Send a message to the window procedure } } And the window procedure is defined like this: LRESULT CALLBACK WinProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam) // second message parameter { switch (uMsg) { case WM_CREATE: // Initialize the window. return 0; case WM_PAINT: // Paint the window's client area. return 0; case WM_SIZE: // Set the size and position of the window. return 0; case WM_DESTROY: // Clean up window-specific data objects. return 0; // // Process other messages. // default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; } Message loop The purpose of a message loop is first and foremost to keep the program running and prevent it from ending immediately. It's exactly the same in AutoIt. But why so complicated code as shown above? It's necessary for advanced message handling eg. to use keyboard accelerators that are local to the individual program and not global as hot keys. Window procedure The window procedure handles the messages sent from the DispatchMessage() function in the message loop. Even in a simpler message loop, messages are sent to the window procedure. This is done through deault code in the Windows API functions and the operating system. If a message isn't handled by the window procedure, it's forwarded to the default window procedure DefWindowProc(). 0) _WinAPI_RegisterClassEx.au3 This is the example of _WinAPI_RegisterClassEx() in the help file. _WinAPI_CreateWindowEx() is used to create the GUI window. The example here is a slightly modified version: #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 <WinAPIRes.au3> #include <WinAPISys.au3> #include <WindowsConstants.au3> Global $bExit = False Example() Func Example() Local Const $sClass = "MyWindowClass" Local Const $sName = "_WinAPI_RegisterClassEx" ; Get module handle for the current process Local $hInstance = _WinAPI_GetModuleHandle( 0 ) ; Create a class cursor Local $hCursor = _WinAPI_LoadCursor( 0, 32512 ) ; IDC_ARROW ; Create a class icons (large and small) Local $tIcons = DllStructCreate( "ptr;ptr" ) _WinAPI_ExtractIconEx( @SystemDir & "\shell32.dll", 130, DllStructGetPtr( $tIcons, 1 ), DllStructGetPtr( $tIcons, 2 ), 1 ) Local $hIcon = DllStructGetData( $tIcons, 1 ) Local $hIconSm = DllStructGetData( $tIcons, 2 ) ; Create DLL callback function (window procedure) Local $pWinProc = DllCallbackGetPtr( DllCallbackRegister( "WinProc", "lresult", "hwnd;uint;wparam;lparam" ) ) ; Create and fill $tagWNDCLASSEX structure Local $tWCEX = DllStructCreate( $tagWNDCLASSEX & ";wchar szClassName[" & ( StringLen( $sClass ) + 1 ) & "]" ) DllStructSetData( $tWCEX, "Size", DllStructGetPtr( $tWCEX, "szClassName" ) - DllStructGetPtr( $tWCEX ) ) DllStructSetData( $tWCEX, "Style", 0 ) DllStructSetData( $tWCEX, "hWndProc", $pWinProc ) DllStructSetData( $tWCEX, "ClsExtra", 0 ) DllStructSetData( $tWCEX, "WndExtra", 0 ) DllStructSetData( $tWCEX, "hInstance", $hInstance ) DllStructSetData( $tWCEX, "hIcon", $hIcon ) DllStructSetData( $tWCEX, "hCursor", $hCursor ) DllStructSetData( $tWCEX, "hBackground", _WinAPI_CreateSolidBrush( _WinAPI_GetSysColor( $COLOR_3DFACE ) ) ) DllStructSetData( $tWCEX, "MenuName", 0 ) DllStructSetData( $tWCEX, "ClassName", DllStructGetPtr( $tWCEX, "szClassName" ) ) DllStructSetData( $tWCEX, "hIconSm", $hIconSm ) DllStructSetData( $tWCEX, "szClassName", $sClass ) ; Register a window class _WinAPI_RegisterClassEx( $tWCEX ) ; Create a window _WinAPI_CreateWindowEx( 0, $sClass, $sName, BitOR( $WS_CAPTION, $WS_POPUPWINDOW, $WS_VISIBLE ), ( @DesktopWidth - 826 ) / 2, ( @DesktopHeight - 584 ) / 2, 826, 584, 0 ) ; Main msg loop While Sleep(10) If $bExit Then ExitLoop WEnd ; Unregister window class and release resources _WinAPI_UnregisterClass( $sClass, $hInstance ) _WinAPI_DestroyCursor( $hCursor ) _WinAPI_DestroyIcon( $hIcon ) _WinAPI_DestroyIcon( $hIconSm ) EndFunc ; Window procedure Func WinProc( $hWnd, $iMsg, $wParam, $lParam ) Switch $iMsg Case $WM_CLOSE $bExit = True EndSwitch Return _WinAPI_DefWindowProcW( $hWnd, $iMsg, $wParam, $lParam ) EndFunc Note that the Esc key, which can normally be used to close an AutoIt window, doesn't work. But you can use Alt+F4 to close the window. Alt+F4 is a hot key. In the example, the main message loop is coded this way: ; Main msg loop While Sleep(10) If $bExit Then ExitLoop WEnd And the window procedure that handles messages: Func WinProc( $hWnd, $iMsg, $wParam, $lParam ) Switch $iMsg Case $WM_CLOSE $bExit = True EndSwitch Return _WinAPI_DefWindowProcW( $hWnd, $iMsg, $wParam, $lParam ) EndFunc Esc key In AutoIt, the Esc key to exit the program is implemented as an accelerator key. But this simple message loop is unable to handle keyboard accelerators. Keyboard accelerators The Microsoft documentation for keyboard accelerators can be found here. To use keyboard accelerators in a program, the following code steps must be implemented: Create a keyboard accelerator struct to store information Fill in the accelerator key structure with information Create an accelerator table with CreateAcceleratorTable() Include TranslateAccelerator() in the message loop Include a WM_COMMAND message handler in the window procedure Includes\WinMsgLoop.au3 (2020-04-26) WinMsgLoop.au3 implements the functions to use keyboard accelerators and to create a Windows message loop: #include-once ; Message structure Global Const $tagMSG = "hwnd hwnd;uint message;wparam wParam;lparam lParam;dword time;int X;int Y" ; Keyboard accelerator structure Global Const $tagACCEL = "byte fVirt;word key;word cmd;" ; Values of the fVirt field Global Const $FVIRTKEY = TRUE Global Const $FNOINVERT = 0x02 Global Const $FSHIFT = 0x04 Global Const $FCONTROL = 0x08 Global Const $FALT = 0x10 #cs ; One accelerator key Local $tAccel = DllStructCreate( $tagACCEL ) DllStructSetData( $tAccel, "fVirt", $FVIRTKEY ) DllStructSetData( $tAccel, "key", $VK_ESCAPE ) DllStructSetData( $tAccel, "cmd", $VK_ESCAPE ) ; cmd = key to keep it simple ; Two accelerator keys Local $tAccel = DllStructCreate( $tagACCEL & $tagACCEL ) DllStructSetData( $tAccel, 1, $FVIRTKEY ) DllStructSetData( $tAccel, 2, $VK_KEY1 ) DllStructSetData( $tAccel, 3, $VK_KEY1 ) DllStructSetData( $tAccel, 4, $FVIRTKEY ) DllStructSetData( $tAccel, 5, $VK_KEY2 ) DllStructSetData( $tAccel, 6, $VK_KEY2 ) #ce ; Error handling ; @error = 0: No errors ; 1: Parameter error ; Create a keyboard accelerator table Func WinMsgLoop_CreateAcceleratorTable( $tAccel ) Local $iSize = DllStructGetSize( $tAccel ) If Mod( $iSize, 6 ) Then Return SetError(1,0,0) ; SetError ( code [, extended = 0 [, return value]] ) Return DllCall( "User32.dll", "handle", "CreateAcceleratorTableW", "struct*", $tAccel, "int", $iSize/6 )[0] EndFunc ; Retrieve a message from the message queue Func WinMsgLoop_GetMessage( ByRef $tMsg ) Return DllCall( "User32.dll", "bool", "GetMessageW", "struct*", $tMsg, "hwnd", 0, "uint", 0, "uint", 0 )[0] EndFunc ; Processes accelerator keystrokes Func WinMsgLoop_TranslateAccelerator( $hWnd, $hAccel, ByRef $tMsg ) Return DllCall( "User32.dll", "int", "TranslateAcceleratorW", "hwnd", $hWnd, "handle", $hAccel, "struct*", $tMsg )[0] EndFunc ; Processes dialog box messages Func WinMsgLoop_IsDialogMessage( $hWnd, ByRef $tMsg ) Return DllCall( "User32.dll", "bool", "IsDialogMessageW", "hwnd", $hWnd, "struct*", $tMsg )[0] EndFunc ; Translate a virtual-key message into a character message Func WinMsgLoop_TranslateMessage( ByRef $tMsg ) DllCall( "User32.dll", "bool", "TranslateMessage", "struct*", $tMsg ) EndFunc ; Send a message to the window procedure Func WinMsgLoop_DispatchMessage( ByRef $tMsg ) DllCall( "User32.dll", "lresult", "DispatchMessageW", "struct*", $tMsg ) EndFunc ; Destroy a keyboard accelerator table Func WinMsgLoop_DestroyAcceleratorTable( $hAccel ) DllCall( "User32.dll", "bool", "DestroyAcceleratorTable", "handle", $hAccel ) EndFunc ; Posts a WM_QUIT message to the message queue ; WinMsgLoop_GetMessage() returns 0 on WM_QUIT and the message loop terminates Func WinMsgLoop_PostQuitMessage( $iExitCode = 0 ) Return DllCall( "User32.dll", "none", "PostQuitMessage", "int", $iExitCode )[0] EndFunc 1) Windows message loop.au3 In this example, the Esc and End keys can be used to exit the program. It contains a complete Windows message loop. The script contains a number of ConsoleWrites so you can see what's going on in SciTE console. Keyboard accelerators: #cs ; Esc accelerator key to Exit ; Create keyboard accelerator structure Local $tAccel = DllStructCreate( $tagACCEL ) DllStructSetData( $tAccel, "fVirt", $FVIRTKEY ) DllStructSetData( $tAccel, "key", $VK_ESCAPE ) DllStructSetData( $tAccel, "cmd", $VK_ESCAPE ) ; cmd = key to keep it simple #ce ; Esc/End accelerator keys to Exit ; Create keyboard accelerator structure Local $tAccel = DllStructCreate( $tagACCEL & $tagACCEL ) DllStructSetData( $tAccel, 1, $FVIRTKEY ) DllStructSetData( $tAccel, 2, $VK_ESCAPE ) DllStructSetData( $tAccel, 3, $VK_ESCAPE ) ; cmd = key to keep it simple DllStructSetData( $tAccel, 4, $FVIRTKEY ) DllStructSetData( $tAccel, 5, $VK_END ) DllStructSetData( $tAccel, 6, $VK_END ) ; Create a keyboard accelerator table Local $hAccel = WinMsgLoop_CreateAcceleratorTable( $tAccel ) ConsoleWrite( "$hAccel = " & $hAccel & @CRLF & @CRLF ) Using dialog box keys (2020-04-26) To use dialog box keys, the message loop must contain the IsDialogMessage() function. The function identifies and processes the keys. Windows message loop: (2020-04-26) ; Windows message loop Local $tMsg = DllStructCreate( $tagMSG ) While WinMsgLoop_GetMessage( $tMsg ) ; Retrieve a message from the message queue ConsoleWrite( "0x" & Hex( DllStructGetData( $tMsg, "message" ), 4 ) & @CRLF ) If Not WinMsgLoop_TranslateAccelerator( $hWnd, $hAccel, $tMsg ) And _ ; Processes accelerator keystrokes Not WinMsgLoop_IsDialogMessage( $hWnd, $tMsg ) Then ; Processes dialog box messages WinMsgLoop_TranslateMessage( $tMsg ) ; Translate a virtual-key message into a character message WinMsgLoop_DispatchMessage( $tMsg ) ; Send a message to the window procedure EndIf If $bExit Then ExitLoop WEnd WM_COMMAND message handler: (2020-04-26) Case $WM_COMMAND ConsoleWrite( @CRLF & "$WM_COMMAND" & @CRLF ) Switch BitShift( $wParam, 16 ) ; HiWord Case 1 ; Accelerator key ConsoleWrite( "Accelerator key" & @CRLF ) Switch BitAND( $wParam, 0xFFFF ) ; LoWord Case $VK_ESCAPE ConsoleWrite( "$VK_ESCAPE" & @CRLF ) _WinAPI_DestroyWindow( $hWnd ) Return 0 ; Don't call DefWindowProc() Case $VK_END ConsoleWrite( "$VK_END" & @CRLF ) _WinAPI_DestroyWindow( $hWnd ) Return 0 EndSwitch EndSwitch Program termination code: (2020-04-26) Case $WM_CLOSE ConsoleWrite( @CRLF & "$WM_CLOSE" & @CRLF ) If MsgBox( $MB_OKCANCEL, "Really close?", "My application", 0, $hWnd ) = $IDOK Then _WinAPI_DestroyWindow( $hWnd ) Else ConsoleWrite( @CRLF ) EndIf Return 0 ; Don't call DefWindowProc() Case $WM_DESTROY ConsoleWrite( @CRLF & "$WM_DESTROY" & @CRLF ) $bExit = True Return 0 2) Windows message loop 2.au3 (2020-04-26) Optimized version of the message loop because DllCall() is used directly instead of more time-consuming functions in WinMsgLoop.au3 UDF: ; Windows message loop Local $tMsg = DllStructCreate( $tagMSG ) While DllCall( "User32.dll", "bool", "GetMessageW", "struct*", $tMsg, "hwnd", 0, "uint", 0, "uint", 0 )[0] ; Retrieve a message from the message queue ConsoleWrite( "0x" & Hex( DllStructGetData( $tMsg, "message" ), 4 ) & @CRLF ) If Not DllCall( "User32.dll", "int", "TranslateAcceleratorW", "hwnd", $hWnd, "handle", $hAccel, "struct*", $tMsg )[0] And _ ; Processes accelerator keystrokes Not DllCall( "User32.dll", "bool", "IsDialogMessageW", "hwnd", $hWnd, "struct*", $tMsg )[0] Then ; Processes dialog box messages DllCall( "User32.dll", "bool", "TranslateMessage", "struct*", $tMsg ) ; Translate a virtual-key message into a character message DllCall( "User32.dll", "lresult", "DispatchMessageW", "struct*", $tMsg ) ; Send a message to the window procedure EndIf If $bExit Then ExitLoop WEnd 3) Navigating with Tab key.au3 (2020-04-26) When IsDialogMessage() is added to the code in the message loop, dialog box keys work immediately. Eg. Tab and Shift+Tab. Demonstrated in the example with three buttons. 4) Adding virtual ListView.au3 A virtual listview with cell background colors is created in the window. As it's a virtual list view, a WM_NOTIFY message handler is needed to handle LVN_GETDISPINFO notifications. Background colors are drawn through NM_CUSTOMDRAW notifications. A virtual and custom drawn listview is very message intensive and therefore interesting to test. ; Create ListView $hListView = _GUICtrlListView_Create( $hWnd, "", 10, 10, 800, 538, $LVS_DEFAULT+$LVS_OWNERDATA-$LVS_SINGLESEL, $WS_EX_CLIENTEDGE ) _GUICtrlListView_SetExtendedListViewStyle( $hListView, $LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT ) ; Add columns For $i = 0 To $iCols - 1 _GUICtrlListView_AddColumn( $hListView, "Col " & $i, 96, 2 ) ; 2 = Centered text Next ; ListView items For $i = 0 To $iRows - 1 For $j = 0 To $iCols - 1 $aItems[$i][$j] = $i & "/" & $j Next Next ; ListView colors Local $aLVColors = [ 0xCCCCFF, 0xCCFFFF, 0xCCFFCC, 0xFFFFCC, 0xFFCCCC, 0xFFCCFF ] ; BGR For $i = 0 To $iRows - 1 For $j = 0 To $iCols - 1 $aColors[$i][$j] = $aLVColors[Random( 0,5,1 )] Next Next ; Set number of rows in virtual ListView DllCall( "user32.dll", "lresult", "SendMessageW", "hwnd", $hListView, "uint", $LVM_SETITEMCOUNT, "wparam", $iRows, "lparam", 0 ) Case $WM_NOTIFY Switch DllStructGetData( DllStructCreate( $tagNMHDR, $lParam ), "Code" ) Case $LVN_GETDISPINFOW ; Fill virtual listview Local Static $tText = DllStructCreate( "wchar[100]" ), $pText = DllStructGetPtr( $tText ) Local $tNMLVDISPINFO = DllStructCreate( $tagNMLVDISPINFO, $lParam ) If Not BitAND( DllStructGetData( $tNMLVDISPINFO, "Mask" ), $LVIF_TEXT ) Then Return Local $sItem = $aItems[DllStructGetData($tNMLVDISPINFO,"Item")][DllStructGetData($tNMLVDISPINFO,"SubItem")] DllStructSetData( $tText, 1, $sItem ) DllStructSetData( $tNMLVDISPINFO, "TextMax", StringLen( $sItem ) ) DllStructSetData( $tNMLVDISPINFO, "Text", $pText ) Return 0 ; Don't call DefWindowProc() Case $NM_CUSTOMDRAW ; Draw back colors Local $tNMLVCUSTOMDRAW = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam ) Local $dwDrawStage = DllStructGetData( $tNMLVCUSTOMDRAW, "dwDrawStage" ), $iItem Switch $dwDrawStage ; Holds a value that specifies the drawing stage Case $CDDS_PREPAINT ; Before the paint cycle begins Return $CDRF_NOTIFYITEMDRAW ; Notify the parent window of any item-related drawing operations Case $CDDS_ITEMPREPAINT ; Before painting an item Return $CDRF_NOTIFYSUBITEMDRAW ; Notify the parent window of any subitem-related drawing operations Case $CDDS_ITEMPREPAINT + $CDDS_SUBITEM ; Before painting a subitem $iItem = DllStructGetData( $tNMLVCUSTOMDRAW, "dwItemSpec" ) DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", $aColors[$iItem][DllStructGetData($tNMLVCUSTOMDRAW,"iSubItem")] ) Return $CDRF_NEWFONT ; $CDRF_NEWFONT must be returned after changing font or colors EndSwitch EndSwitch Usage of the code I don't think there's such a great need for code like this. At least the code shows that translating Windows API functions into AutoIt works pretty well. Implementing the code in the WinMsgLoop.au3 UDF was straightforward. There is a question about using keyboard accelerators in non-AutoIt GUIs in this post. If you use AutoIt for prototyping, you might get some ideas here. Because the examples do not contain internal AutoIt functions but only Windows API functions, they are easy to translate into C/C++ and other languages. When translating back and forth between AutoIt and other languages, the internal functions are always the problem. How to translate these functions? Recent performance issue Recently, a problem was raised in this post regarding a multiple 100% performance degradation on Windows 10 versions later than 1803 as soon as a GUI element became visible in a script. The problem persisted throughout the rest of the code, even though the GUI element was deleted. I've tested the issue under Windows 10 1809 with all the examples here. All of the examples suffer from the problem. How much of the code needs to be translated into C/C++ before the problem disappears? Only the line which contains the _WinAPI_CreateWindowEx() function that creates and displays the window? Or does the problem still exist when all code is translated? That could be interesting. I've already done examples of translating AutoIt code into C/C++ eg. in this example and this example so it's not that hard. 7z-file The 7z-file contains source code for the UDFs and examples. 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. WinMsgLoop.7z
    1 point
  2. 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.7z
    1 point
  3. Yes, I can confirm that (for the sake of completeness only ). It is also easier to handle compared to _Date_Time_SetFileTime.
    1 point
  4. DoDragDropGUI.au3 #include"DoDragDrop.au3" #include<ClipBoard.au3> #include<WindowsConstants.au3> Global Const $DROPFILES = "DWORD pFiles; int pt[2]; int fNC; int fWide;" ;=============================================================================== ; ; Function Name: _CreateHDROP_FORMATETC() ; Description:: Creates a FORMATETC-structure with the needed values to do a HDROP (Drag Files like explorer) ; Parameter(s): none ; Requirement(s): COM/OLE UDF ; Return Value(s): FORMATETC DLL-structure ; Author(s): prog@ndy ; ;=============================================================================== ; Func _CreateHDROP_FORMATETC() Local $FMTETC = DllStructCreate($tagFORMATETC) DllStructSetData($FMTETC,1,$CF_HDROP) DllStructSetData($FMTETC,2,0) DllStructSetData($FMTETC,3,$DVASPECT_CONTENT) DllStructSetData($FMTETC,4,-1) DllStructSetData($FMTETC,5,$TYMED_HGLOBAL) Return $FMTETC EndFunc ;=============================================================================== ; ; Function Name: _CreateDROPFILES ; Description:: Creates a DROPFILES-structure ; Parameter(s): $Files - Pipe-separated list of files to copy: example: C:\File1.bin|D:\AnotherFile.dat ; Requirement(s): COM/OLE UDF ; Return Value(s): HGLOBAL-Pointer to a DROPFILES structure ; Author(s): prog@ndy ; ;=============================================================================== ; Func _CreateDROPFILES($Files) $Files = String($Files) $hMem = _MemGlobalAlloc(_DragDrop_SIZEOF($DROPFILES) + ((StringLen($Files)+2)*2),$GPTR) $Files = StringSplit($Files,"|") $stDROPFILES = DllStructCreate($DROPFILES,$hMem) $hPtr = $hMem + DllStructGetSize($stDROPFILES) DllStructSetData($stDROPFILES, "fWide", 1) DllStructSetData($stDROPFILES, 1, DllStructGetSize($stDROPFILES)) For $i = 1 To $Files[0] $next = DllStructCreate("wchar[" & StringLen($Files[$i])+1 & "]", $hPtr) DllStructSetData($next,1,$Files[$i] & ChrW(0)) $hPtr += (StringLen($Files[$i])+1)*2 Next $next = DllStructCreate("wchar[1]", $hPtr) DllStructSetData($next,1,ChrW(0)) Return $hMem EndFunc ;=============================================================================== ; ; Function Name: _CreateDROPFILES_STGMEDIUM ; Description:: Creates a STGMEDIUM with a DROPFILES-structure ; Parameter(s): $Files - Pipe-separated list of files to copy: example: C:\File1.bin|D:\AnotherFile.dat ; Requirement(s): COM/OLE UDF ; Return Value(s): STGMEDIUM-DLLStruct ; Author(s): prog@ndy ; ;=============================================================================== ; Func _CreateDROPFILES_STGMEDIUM($Files) Local $STGMD = DllStructCreate($tagSTGMEDIUM) DllStructSetData($STGMD,1,$TYMED_HGLOBAL) Local $DF = _CreateDROPFILES($Files) If Not $DF Then Return SetError(1,0,0) DllStructSetData($STGMD,2,$DF) Return $STGMD EndFunc #include <GuiConstantsEx.au3> #include <GuiListView.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> #include <Constants.au3> Global $hDragDropGUI ,$iListView, $_GLOB_fDragInitiated=False ; do on Startup _OLEInitialize() ; init DropSource Handler Global $objIDropSource = _CreateIDropSource() Global Const $DI_GETDRAGIMAGE = "ShellGetDragImage" Global Const $WM_DI_GETDRAGIMAGE = _WinAPI_RegisterWindowMessage($DI_GETDRAGIMAGE) Global Const $CFSTR_PERFORMEDDROPEFFECT = "Performed DropEffect" Global Const $CF_PERFORMEDDROPEFFECT = _WinAPI_RegisterWindowMessage($CFSTR_PERFORMEDDROPEFFECT) Global Const $tagSHDRAGIMAGE = "long sizeDragImage[2];long ptOffset[2]; ptr hbmpDragImage; dword crColorKey;" Global $CLSID_DragDropHelper = _GUID("4657278A-411B-11D2-839A-00C04FD918D0") Global $IID_IDragSourceHelper = _GUID("DE5BF786-477A-11D2-839D00C04FD918D0") Global $IID_IDropTargetHelper = _GUID("4657278B-411B-11D2-839A00C04FD918D0") Global $IDragSourceHelper_vTable = $IUnknown_vTable & "ptr InitializeFromBitmap; ptr InitializeFromWindow;" Func _SetBMP(ByRef $IDragSourceHelper, ByRef $IDataObject) Local $SHDRAGIMAGE = DllStructCreate($tagSHDRAGIMAGE) ;~ Local $deskDC = _WinAPI_GetDC(_WinAPI_GetDesktopWindow()) ;~ Local $hBMP = _WinAPI_CreateCompatibleBitmap($deskDC,96,96) ;~ _WinAPI_ReleaseDC(_WinAPI_GetDesktopWindow(),$deskDC) Local $hBMP = _WinAPI_LoadImage(0,"C:\Windows\Feder.bmp",0,0,0,$LR_LOADFROMFILE) DllStructSetData($SHDRAGIMAGE,"hbmpDragImage",$hBMP) DllStructSetData($SHDRAGIMAGE,"sizeDragImage",96,1) DllStructSetData($SHDRAGIMAGE,"sizeDragImage",96,2) DllStructSetData($SHDRAGIMAGE,"ptOffset",45,1) DllStructSetData($SHDRAGIMAGE,"ptOffset",69,2) DllStructSetData($SHDRAGIMAGE,"crColorKey",0x00FF00FF) _ObjFuncCall($HRESULT, $IDragSourceHelper, "InitializeFromBitmap", "ptr", DllStructGetPtr($SHDRAGIMAGE), "ptr", _ObjGetObjPtr($IDataObject)) EndFunc _Main() ; Author: Prog@ndy Func _MemGlobalGetValue($hMem, $DataType, $Offset=0) If _MemGlobalSize($hMem) < __MemArray_SIZEOF($DataType) Then Return SetError(1,0,0) Local $hPtr = _MemGlobalLock($hMem) If Not $hPtr Then Return SetError(2,0,0) Local $Data = DllStructGetData(DllStructCreate($DataType,$hPtr+$Offset),1) If @error Then Return SetError(1,_MemGlobalUnlock($hMem)) _MemGlobalUnlock($hMem) Return $Data EndFunc Func OnAutoItExit() ; release the DropSource Handler _ReleaseIDropSource($objIDropSource) _OLEUnInitialize() EndFunc Func MY_GETDRAGIMAGE($hWnd, $Msg, $wParam, $lParam) Local $SHDRAGIMAGE = DllStructCreate($tagSHDRAGIMAGE,$lParam) ;~ Local $deskDC = _WinAPI_GetDC(_WinAPI_GetDesktopWindow()) ;~ Local $hBMP = _WinAPI_CreateCompatibleBitmap($deskDC,96,96) ;~ _WinAPI_ReleaseDC(_WinAPI_GetDesktopWindow(),$deskDC) Local $hBMP = _WinAPI_LoadImage(0,"C:\Windows\Feder.bmp",0,0,0,$LR_LOADFROMFILE) DllStructSetData($SHDRAGIMAGE,"hbmpDragImage",$hBMP) DllStructSetData($SHDRAGIMAGE,"sizeDragImage",128,1) DllStructSetData($SHDRAGIMAGE,"sizeDragImage",128,2) DllStructSetData($SHDRAGIMAGE,"ptOffset",45,1) DllStructSetData($SHDRAGIMAGE,"ptOffset",69,2) DllStructSetData($SHDRAGIMAGE,"crColorKey",0x00FF00FF) Return True EndFunc Func _Main() Local $hGUI, $hItemChild, $hImage, $iImage, $hItem, $hListView, $btnDelete, $btnExit $hGUI = GUICreate("DragDrop Example", 400, 450,-1,-1,Default,0) GUICtrlCreateLabel("Drag files to the ListView and drop them" & @CRLF &" ... ... or the other way round ;)", 10,10,380,60) GUICtrlSetFont(-1,14,600) $hDragDropGUI = GUICreate("DropOnlyHere",380,300,10,80,$WS_CHILD,BitOR($WS_EX_ACCEPTFILES,$WS_EX_CONTROLPARENT),$hGUI) ; This Child-GUI is a work-around, so you can only drop files in this area $iListView = GUICtrlCreateListView("Dropped files",0,0,380,300,$LVS_SHOWSELALWAYS) $hListView = GUICtrlGetHandle($iListView) _GUICtrlListView_SetColumnWidth($hListView,0,$LVSCW_AUTOSIZE_USEHEADER) GUISetState() GUISwitch($hGUI) $btnDelete = GUICtrlCreateButton("Remove selected items from list",10,400,200,40) $btnExit = GUICtrlCreateButton("Exit",330,400,60,40) ;~ Const $WM_DROPFILES = 0x233 GUIRegisterMsg($WM_DROPFILES, "WM_DROPFILES") GUIRegisterMsg($WM_NOTIFY, "MY_NOTIFY") GUIRegisterMsg($WM_DI_GETDRAGIMAGE, "MY_GETDRAGIMAGE") GUISetState() Global $IDragSourceHelper = _ObjCoCreateInstance($CLSID_DragDropHelper,$IID_IDragSourceHelper,$IDragSourceHelper_vTable) ; Loop until user exits While 1 If $_GLOB_fDragInitiated Then $_GLOB_fDragInitiated = False ; Array needed for FORMATETC Local $FMTETCs[1] = [_CreateHDROP_FORMATETC()] ; get the Filenames to a pipe separated list. Local $Items = _GUICtrlListView_GetSelectedIndices($iListView,True) Local $Files = "" For $i = 1 To $Items[0] $Files &= _GUICtrlListView_GetItemText($iListView,$Items[$i]) & "|" Next $Files = StringTrimRight($Files,1) ; Array needed for STGMEDIUM Local $STGMDs[1] = [_CreateDROPFILES_STGMEDIUM($Files)] ; Create the Object with FORMATETC and STGMEDIUM (Attention: if you use multiple ones, the corresponding FMTETC and STGMD must be at the same position in the Array) $objIDataSource = _CreateIDataObject($FMTETCs,$STGMDs) If Not _ObjGetObjPtr($objIDataSource) Then ; Just continue, if the creation has failed _ReleaseStgMedium($STGMDs[0]) ; but first delete the created STGMedium ContinueLoop EndIf _SetBMP($IDragSourceHelper,$objIDataSource) ;~ Local $ptr = _IUnknown_QueryInterface($objIDataSource, $IID_IDataObject) ;~ $ptr = _ObjCreateFromPtr($ptr,$IDataObject_vTable) ;~ $result = _ObjFuncCall($HRESULT, $IDragSourceHelper, "InitializeFromWindow", "ptr", $hGUI, "ptr", 0, "ptr", _ObjGetObjPtr($ptr )) ; Perform the DragDrop operation Local $Effect Local $result = _DoDragDrop($objIDataSource, $objIDropSource, BitOR($DROPEFFECT_MOVE,$DROPEFFECT_COPY,$DROPEFFECT_LINK), $Effect) ;~ Local $result = _SHDoDragDrop($hGUI, $objIDataSource, $objIDropSource, BitOR($DROPEFFECT_MOVE,$DROPEFFECT_COPY,$DROPEFFECT_LINK), $Effect) ; check the result If $result = $DRAGDROP_S_DROP Then $Effect = _GetUnoptimizedEffect($objIDataSource, $Effect) Switch $Effect Case $DROPEFFECT_MOVE ; items moved ; Delete the items that were moved For $i = $Items[0] To 1 Step -1 $File = _GUICtrlListView_GetItemText($hListView,$Items[$i]) If Not FileExists($File) Then _GUICtrlListView_DeleteItem($hListView,$Items[$i]) EndIf Next MsgBox(0, '', "Move") Case $DROPEFFECT_COPY ; items copied MsgBox(0, '', "Copy") Case $DROPEFFECT_LINK ; links created MsgBox(0, '', "Link") Case $DROPEFFECT_NONE ; on Win 9x nothing, but NT/2000 and above have MOVE-operaion here, too ; on NT/200 and above, a move-action will also return DROPEFFECT_NONE. So you have to check that manually: Local $deletedAnything=False If @OSType = "WIN32_NT" Then ; just for the "new" NT-Systems Local $File For $i = $Items[0] To 1 Step -1 $File = _GUICtrlListView_GetItemText($hListView,$Items[$i]) If Not FileExists($File) Then ; if the file has been moved,... _GUICtrlListView_DeleteItem($hListView,$Items[$i]) ; delete it from LV $deletedAnything = True ; set the deleted flag to TRUE EndIf Next If $deletedAnything Then MsgBox(0, '', "Workaround detect: Move") ; if something was deleted --> MOVE EndIf If $deletedAnything = False Then MsgBox(0, '', "Nothing Done") EndIf EndSwitch ElseIf $result = $DRAGDROP_S_CANCEL Then MsgBox(0, '', "DoDragDrop cancelled") Else MsgBox(0, '', "Error on DoDragDrop") EndIf _ReleaseIDataObject($objIDataSource) ; release the DataObject ; DO NOT RELEASE THE STGMEDIUM, since it belongs to the IDataObject EndIf ; $_GLOB_fDragInitiated Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $btnExit ExitLoop Case $btnDelete _GUICtrlListView_DeleteItemsSelected($hListView) EndSwitch WEnd _IUnknown_Release($IDragSourceHelper) GUIDelete() EndFunc ;==>_Main ; Prog@ndy Func _GetUnoptimizedEffect(ByRef $objIDataSource, $Effect) Local $FormatEtc = _CreateHDROP_FORMATETC() DllStructSetData($FormatEtc,1,$CF_PERFORMEDDROPEFFECT) Local $result = _ObjFuncCall($HRESULT, $objIDataSource, "QueryGetData", "ptr", DllStructGetPtr($FormatEtc)) If $S_OK = $result[0] Then Local $StgMedium = DllStructCreate($tagSTGMEDIUM) $result = _ObjFuncCall($HRESULT, $objIDataSource, "GetData", "ptr", DllStructGetPtr($FormatEtc), "ptr", DllStructGetPtr($StgMedium)) If $S_OK = $result[0] Then $Effect = _MemGlobalGetValue(DllStructGetData($StgMedium,"hGlobal"),"dword") EndIf _ReleaseStgMedium($StgMedium) EndIf Return $Effect EndFunc Func _SHDoDragDrop($hWnd, ByRef $objIDataSource, ByRef $objIDropSource, $dwDropEffects, ByRef $dwPerformedEffect) Local $result = DllCall("shell32.dll",$HRESULT,"SHDoDragDrop", "hwnd", $hWnd, "ptr", _ObjGetObjPtr($objIDataSource),"ptr", _ObjGetObjPtr($objIDropSource), "dword", BitOR($DROPEFFECT_MOVE,$DROPEFFECT_COPY,$DROPEFFECT_LINK), "dword*", 0) $dwPerformedEffect = $result[5] Return $result[0] EndFunc Func MY_NOTIFY($hWnd, $Msg, $wParam, $lParam) If $hWnd = $hDragDropGUI And $wParam=$iListView Then Local $NMHDR = DllStructCreate($tagNMHDR,$lParam) Switch DllStructGetData($NMHDR,"Code") Case $LVN_BEGINDRAG $_GLOB_fDragInitiated = True Return False EndSwitch EndIf EndFunc ; copied from http://www.autoitscript.com/forum/index.php?s=&showtopic=60308&view=findpost&p=453731 ; modified by Prog@ndy Func WM_DROPFILES($hWnd, $uMsg, $wParam, $lParam) Local $tDrop, $aRet, $iCount, $iSize ;string buffer for file path ;get file count $aRet = DllCall("shell32.dll", "int", "DragQueryFileW", "ptr", $wParam, "uint", 0xFFFFFFFF, "ptr", 0, "uint", 0) $iCount = $aRet[0] ;get file paths Local $CurInfo = GUIGetCursorInfo($hDragDropGUI) If IsArray($CurInfo) And $CurInfo[4] = $iListView Then For $i = 0 To $iCount-1 $iSize = DllCall("shell32.dll", "uint", "DragQueryFileW","ptr", $wParam,"uint", $i,"ptr", 0,"uint", 0) $tDrop = DllStructCreate("wchar[" & $iSize[0]+1 & "]") $aRet = DllCall("shell32.dll", "uint", "DragQueryFileW","ptr", $wParam,"uint", $i,"ptr", DllStructGetPtr($tDrop),"uint", $iSize[0]+1) ;ConsoleWrite(DllStructGetData($tDrop, 1) & @CRLF) If _GUICtrlListView_FindText($iListView,DllStructGetData($tDrop, 1),-1,False) = -1 Then _GUICtrlListView_AddItem($iListView,DllStructGetData($tDrop, 1)) Next EndIf ;finalize DllCall("shell32.dll", "int", "DragFinish", "ptr", $wParam) Return EndFunc DoDragDrop.au3 #include <memory.au3> #include <Misc.au3> #include <WinAPIConstants.au3> #include "MemArray.au3" #include "objbase.au3" #include <Misc.au3> ;+------------------------------------------------------------------------+ ;| | ;| UDF for OLE-DragDrop | ;| Author: Prog@ndy | ;| | ;+------------------------------------------------------------------------+ ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ;!! !! ;!! VARIABLES AND FUNCTIONS WITH DOUBLE UNDERSCORE ARE INTERNAL USE ONLY !! ;!! !! ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Global Const $MK_LBUTTON = 1 Global Const $DRAGDROP_S_DROP = 0x40100 Global Const $DRAGDROP_S_CANCEL = 0x40101 Global Const $DRAGDROP_S_FIRST = 0x40100 Global Const $DRAGDROP_S_LAST = 0x4010F Global Const $DRAGDROP_S_USEDEFAULTCURSORS = 0x40102 Global Const $DRAGDROP_E_NOTREGISTERED = 0x80040100 Global Const $DRAGDROP_E_INVALIDHWND = 0x80040102 Global Const $DRAGDROP_E_LAST = 0x8004010F Global Const $DRAGDROP_E_FIRST = 0x80040100 Global Const $DRAGDROP_E_ALREADYREGISTERED = 0x80040101 Global Const $DRAGLISTMSGSTRING = "commctrl_DragListMsg" ;~ typedef enum tagDROPEFFECT ;~ { Global Const $DROPEFFECT_NONE = 0 Global Const $DROPEFFECT_COPY = 1 Global Const $DROPEFFECT_MOVE = 2 Global Const $DROPEFFECT_LINK = 4 Global Const $DROPEFFECT_SCROLL = 0x80000000 ;~ } Global $IID_IDropTarget = _GUID("{00000122-0000-0000-C000-000000000046}") ; -- #Region IDropSource ------------------------------------------------------------- #Region IDropSource Global Const $IDropSource_vTable = $IUnknown_vTable & "ptr QueryContinueDrag; ptr GiveFeedback;" Global Const $tagIDropSource = "ptr vTable; dword dwRefCount;" Global $IID_IDropSource = _GUID("{00000121-0000-0000-C000-000000000046}") Global Const $__IDropSource_vTable = DllStructCreate($IDropSource_vTable) Func _CreateIDropSource() Local $hMem = _MemGlobalAlloc(_DragDrop_SIZEOF($tagIDropSource),$GPTR) Local $IDropSource[3] = [$hMem, DllStructCreate($tagIDropSource,$hMem), $__IDropSource_vTable] DllStructSetData($IDropSource[1], 1, DllStructGetPtr($__IDropSource_vTable)) __IDropSource_AddRef($hMem) Return $IDropSource EndFunc Func _ReleaseIDropSource(ByRef $IDropSource) Local $res = _ObjFuncCall("ulong",$IDropSource,"Release") If @error Then Return SetError(1,0,-1) If $res[0] = 0 Then $IDropSource = 0 EndIf Return $res[0] EndFunc Global Const $__IDropSource_QueryInterface = DllCallbackRegister("__IDropSource_QueryInterface", $HRESULT, "ptr;ptr;ptr") DllStructSetData($__IDropSource_vTable, "QueryInterface", DllCallbackGetPtr($__IDropSource_QueryInterface)) Global Const $__IDropSource_AddRef = DllCallbackRegister("__IDropSource_AddRef", $HRESULT, "ptr") DllStructSetData($__IDropSource_vTable, "AddRef", DllCallbackGetPtr($__IDropSource_AddRef)) Global Const $__IDropSource_Release = DllCallbackRegister("__IDropSource_Release", $HRESULT, "ptr") DllStructSetData($__IDropSource_vTable, "Release", DllCallbackGetPtr($__IDropSource_Release)) Global Const $__IDropSource_QueryContinueDrag = DllCallbackRegister("__IDropSource_QueryContinueDrag", $HRESULT, "ptr;int;dword") DllStructSetData($__IDropSource_vTable, "QueryContinueDrag", DllCallbackGetPtr($__IDropSource_QueryContinueDrag)) Global Const $__IDropSource_GiveFeedback = DllCallbackRegister("__IDropSource_GiveFeedback", $HRESULT, "ptr;dword") DllStructSetData($__IDropSource_vTable, "GiveFeedback", DllCallbackGetPtr($__IDropSource_GiveFeedback)) Func __IDropSource_QueryInterface($pObject, $iid, $ppvObject) If $ppvObject = 0 Or $iid = 0 Then Return $E_NOINTERFACE Local $stIID = DllStructCreate($tagIID, $iid), $pvObject = DllStructCreate("ptr", $ppvObject) If _GUID_Compare($stIID, $IID_IDropSource) Or _GUID_Compare($stIID, $IID_IUnknown) Then DllStructSetData($pvObject, 1, $pObject) __IDropSource_AddRef($pObject) Return $S_OK EndIf DllStructSetData($pvObject,1, 0) Return $E_NOINTERFACE EndFunc ;==>__IDropSource_QueryInterface Func __IDropSource_AddRef($pObject) Local $st = DllStructCreate("ptr;dword", $pObject) Local $iCount = DllStructGetData($st, 2) + 1 DllStructSetData($st, 2, $iCount) Return $iCount EndFunc ;==>__IDropSource_AddRef Func __IDropSource_Release($pObject) Local $st = DllStructCreate("ptr;dword", $pObject) Local $iCount = DllStructGetData($st, 2) - 1 If $iCount < 0 Then Return 0 DllStructSetData($st,2,$iCount) Return $iCount EndFunc ;==>__IDropSource_Release Func __IDropSource_QueryContinueDrag($pObject, $fEscapePressed, $grfKeyState) Select Case $fEscapePressed <> 0 Return $DRAGDROP_S_CANCEL Case Not BitAND($grfKeyState, $MK_LBUTTON) Return $DRAGDROP_S_DROP Case Else Return $S_OK EndSelect EndFunc ;==>__IDropSource_QueryContinueDrag Func __IDropSource_GiveFeedback($pObject, $dwEffect) Select Case $dwEffect = $DROPEFFECT_NONE Case BitAND($dwEffect, $DROPEFFECT_LINK) = $DROPEFFECT_LINK Case BitAND($dwEffect, $DROPEFFECT_MOVE) = $DROPEFFECT_MOVE Case BitAND($dwEffect, $DROPEFFECT_COPY) = $DROPEFFECT_COPY Case BitAND($dwEffect, $DROPEFFECT_SCROLL) = $DROPEFFECT_SCROLL Case Else Return $E_INVALIDARG EndSelect Return $DRAGDROP_S_USEDEFAULTCURSORS EndFunc ;==>__IDropSource_GiveFeedback #EndRegion ; -- #EndRegion IDropSource ------------------------------------------------------------- ; -- #Region IDataObject ------------------------------------------------------------- #Region IDataObject Global Const $tagFORMATETC = "dword cfFormat; ptr ptd; DWORD dwAspect; LONG lindex; DWORD tymed;" Global Const $tagSTGMEDIUM = "DWORD tymed; ptr hGlobal; ptr pUnkForRelease;" Global Const $sizeFORMATETC = _DragDrop_SIZEOF($tagFORMATETC) Global Const $sizeSTGMEDIUM = _DragDrop_SIZEOF($tagSTGMEDIUM) Global Const $tagDVTARGETDEVICE = "DWORD tdSize; USHORT tdDriverNameOffset; USHORT tdDeviceNameOffset; USHORT tdPortNameOffset; USHORT tdExtDevmodeOffset; BYTE tdData[1];" Global Const $tagIDataObject = "ptr vTable; dword dwRefCount; dword Count; ptr pFORMATETC; ptr pSTGMEDIUM;" Global Const $TYMED_HGLOBAL = 1 Global Const $TYMED_FILE = 2 Global Const $TYMED_ISTREAM = 4 Global Const $TYMED_ISTORAGE = 8 Global Const $TYMED_GDI = 16 Global Const $TYMED_MFPICT = 32 Global Const $TYMED_ENHMF = 64 Global Const $TYMED_NULL = 0 Global Const $DVASPECT_CONTENT = 1 Global Const $DVASPECT_THUMBNAIL = 2 Global Const $DVASPECT_ICON = 4 Global Const $DVASPECT_DOCPRINT = 8 Global Const $DATADIR_GET = 1 Global Const $DATADIR_SET = 2 Global $IID_IDataObject = _GUID("{0000010E-0000-0000-C000-000000000046}") Global Const $DV_E_FORMATETC = 0x80040064 Global Const $DATA_E_FORMATETC = $DV_E_FORMATETC Global Const $DV_E_TYMED = 0x80040069 Global Const $OLE_S_USEREG = 0x00040000 Global Const $IDataObject_vTable = $IUnknown_vTable & _ "ptr GetData; ptr GetDataHere; ptr QueryGetData; ptr GetCanonicalFormatEtc; " & _ "ptr SetData; ptr EnumFormatEtc; ptr DAdvise; ptr DUnadvise; ptr EnumDAdvise; " Global Const $__IDataObj_QueryInterface = DllCallbackRegister( "__IDataObj_QueryInterface", $HRESULT, "ptr;ptr;ptr") Global Const $__IDataObj_AddRef = DllCallbackRegister( "__IDataObj_AddRef", "ULONG", "ptr") Global Const $__IDataObj_Release = DllCallbackRegister( "__IDataObj_Release", "ULONG", "ptr") Global Const $__IDataObj_GetData = DllCallbackRegister( "__IDataObj_GetData", $HRESULT, "ptr;ptr;ptr") Global Const $__IDataObj_GetDataHere = DllCallbackRegister( "__IDataObj_GetDataHere", $HRESULT, "ptr;ptr;ptr") Global Const $__IDataObj_QueryGetData = DllCallbackRegister( "__IDataObj_QueryGetData", $HRESULT, "ptr;ptr") Global Const $__IDataObj_GetCanonicalFormatEtc = DllCallbackRegister( "__IDataObj_GetCanonicalFormatEtc", $HRESULT, "ptr;ptr;ptr") Global Const $__IDataObj_SetData = DllCallbackRegister( "__IDataObj_SetData", $HRESULT, "ptr;ptr;ptr;int") Global Const $__IDataObj_EnumFormatEtc = DllCallbackRegister( "__IDataObj_EnumFormatEtc", $HRESULT, "ptr;dword;ptr") Global Const $__IDataObj_DAdvise = DllCallbackRegister( "__IDataObj_DAdvise", $HRESULT, "ptr;ptr;DWORD;ptr;ptr") Global Const $__IDataObj_DUnadvise = DllCallbackRegister( "__IDataObj_DUnadvise", $HRESULT, "ptr;dword") Global Const $__IDataObj_EnumDAdvise = DllCallbackRegister( "__IDataObj_EnumDAdvise", $HRESULT, "ptr;ptr") Global Const $__IDataObj_vTable = DllStructCreate($IDataObject_vTable) DllStructSetData($__IDataObj_vTable, "QueryInterface", DllCallbackGetPtr($__IDataObj_QueryInterface)) DllStructSetData($__IDataObj_vTable, "AddRef", DllCallbackGetPtr($__IDataObj_AddRef)) DllStructSetData($__IDataObj_vTable, "Release", DllCallbackGetPtr($__IDataObj_Release)) DllStructSetData($__IDataObj_vTable, "GetData", DllCallbackGetPtr($__IDataObj_GetData)) DllStructSetData($__IDataObj_vTable, "GetDataHere", DllCallbackGetPtr($__IDataObj_GetDataHere)) DllStructSetData($__IDataObj_vTable, "QueryGetData", DllCallbackGetPtr($__IDataObj_QueryGetData)) DllStructSetData($__IDataObj_vTable, "GetCanonicalFormatEtc", DllCallbackGetPtr($__IDataObj_GetCanonicalFormatEtc)) DllStructSetData($__IDataObj_vTable, "SetData", DllCallbackGetPtr($__IDataObj_SetData)) DllStructSetData($__IDataObj_vTable, "EnumFormatEtc", DllCallbackGetPtr($__IDataObj_EnumFormatEtc)) DllStructSetData($__IDataObj_vTable, "DAdvise", DllCallbackGetPtr($__IDataObj_DAdvise)) DllStructSetData($__IDataObj_vTable, "DUnadvise", DllCallbackGetPtr($__IDataObj_DUnadvise)) DllStructSetData($__IDataObj_vTable, "EnumDAdvise", DllCallbackGetPtr($__IDataObj_EnumDAdvise)) ; Author: Prog@ndy Func __IDataObj_QueryInterface($pObject, $iid, $ppvObject) Local $stIID = DllStructCreate($tagIID, $iid), $pvObject = DllStructCreate("ptr", $ppvObject) ;~ ConsoleWrite(_WinAPI_StringFromGUID($iid) & @CRLF) If _GUID_Compare($stIID, $IID_IDataObject) Or _GUID_Compare($stIID, $IID_IUnknown) Then __IDataObj_AddRef($pObject) DllStructSetData($pvObject,1, $pObject) Return $S_OK EndIf DllStructSetData($pvObject,1, 0) Return $E_NOINTERFACE EndFunc ;==>__IDataObj_QueryInterface ; Author: Prog@ndy Func __IDataObj_AddRef($pObject) Local $st = DllStructCreate($tagIDataObject, $pObject) Local $iCount = DllStructGetData($st, "dwRefCount") + 1 DllStructSetData($st, "dwRefCount", $iCount) Return $iCount EndFunc ;==>__IDataObj_AddRef ; Author: Prog@ndy Func __IDataObj_Release($pObject) Local $st = DllStructCreate($tagIDataObject, $pObject) Local $iCount = DllStructGetData($st, "dwRefCount") - 1 DllStructSetData($st, "dwRefCount", $iCount) If $iCount = 0 Then ;[[[ Array Local $pFORMATETC = DllStructGetData($st, "pFORMATETC") Local $pSTGMEDIUM = DllStructGetData($st, "pSTGMEDIUM") Local $STGMED = DllStructCreate($tagSTGMEDIUM) Local $FMTETC = DllStructCreate($tagFORMATETC) ;~ Local $STGMED Local $pSTGMED = DllStructGetPtr($STGMED) Local $pFMTETC = DllStructGetPtr($FMTETC) For $i = 0 To DllStructGetData($st, "Count")-1 _MemArrayGet($pFORMATETC, $i, $pFMTETC) If DllStructGetData($FMTETC, "ptd") Then _CoTaskMemFree(DllStructGetData($FMTETC, "ptd")) _MemArrayGet($pSTGMEDIUM, $i, $pSTGMED) _ReleaseStgMedium($STGMED) Next _MemArrayFree($pFORMATETC) _MemArrayFree($pSTGMEDIUM) ;]]] Array _MemGlobalFree($pObject) EndIf Return $iCount EndFunc ;==>__IDataObj_Release ; Author: Prog@ndy Func __IDataObj_GetData($pObject, $pFormatEtc, $pMedium) If $pMedium = 0 Or $pFormatEtc = 0 Then Return $E_POINTER Local $st = DllStructCreate($tagIDataObject, $pObject) Local $dwCount = DllStructGetData($st, "Count") Local $pArrFormatEtc = DllStructGetData($st, "pFORMATETC") Local $idx = __DataObj_LookupFormatEtc($pFormatEtc, $pArrFormatEtc, $dwCount) If $idx == -1 Then Return $DV_E_FORMATETC Local $stFORMATETC = DllStructCreate($tagFORMATETC, $pFormatEtc) ;~ Local $tymed = DllStructGetData(DllStructCreate($tagFORMATETC,$pArrFormatEtc+ $idx*$sizeFORMATETC),"tymed") ;[[[ Array Local $tymed = DllStructGetData(_MemArrayGet($pArrFormatEtc, $idx, $tagFORMATETC),"tymed") ;]]] Array Local $Medium = DllStructCreate($tagSTGMEDIUM,$pMedium) DllStructSetData($Medium,"tymed", $tymed) DllStructSetData($Medium,"pUnkForRelease", 0) Switch $tymed Case $TYMED_ENHMF, $TYMED_GDI, $TYMED_HGLOBAL, $TYMED_MFPICT, $TYMED_NULL, $TYMED_ISTREAM, $TYMED_ISTORAGE ;~ Local $IntMedium = DllStructCreate($tagSTGMEDIUM,DllStructGetData($st,"pSTGMEDIUM") + $idx*$sizeSTGMEDIUM) ;[[[ Array Local $IntMedium = _MemArrayGet(DllStructGetData($st,"pSTGMEDIUM"), $idx, $tagSTGMEDIUM) ;]]] Array ;~ DllStructSetData($Medium,"hGlobal", DupGlobalMemMem(DllStructGetData($IntMedium,"hGlobal"))) If Not DeepCopyStgMedium($pMedium, DllStructGetPtr($IntMedium)) Then Return $DV_E_FORMATETC Case Else return $DV_E_FORMATETC; EndSwitch Return $S_OK EndFunc ;==>__IDataObj_GetData ; Author: Prog@ndy Func __IDataObj_GetDataHere($pObject, $pFormatEtc, $pMedium) Return $DATA_E_FORMATETC; EndFunc ;==>__IDataObj_GetDataHere ; Author: Prog@ndy Func __IDataObj_QueryGetData($pObject, $pFormatEtc) Local $st = DllStructCreate($tagIDataObject, $pObject) Return _Iif( __DataObj_LookupFormatEtc($pFormatEtc, DllStructGetData($st, "pFORMATETC"), DllStructGetData($st, "Count")) = -1, $DV_E_FORMATETC, $S_OK); EndFunc ;==>__IDataObj_QueryGetData ; Author: Prog@ndy Func __IDataObj_GetCanonicalFormatEtc($pObject, $pFormatEtc, $pFormatEtcOut) ;~ // Apparently we have to set this field to NULL even though we don't do anything else Local $FormatEtcOut = DllStructCreate($tagFORMATETC, $pFormatEtcOut) DllStructSetData($FormatEtcOut, "ptd", 0); Return $E_NOTIMPL; EndFunc ;==>__IDataObj_GetCanonicalFormatEtc ; Author: Prog@ndy Func __IDataObj_SetData($pObject, $pFormatEtc, $pMedium, $fRelease) ;~ Return $E_NOTIMPL; Local $STGMED = DllStructCreate($tagSTGMEDIUM,$pMedium) Switch DllStructGetData($STGMED,"tymed") Case $TYMED_ENHMF, $TYMED_GDI, $TYMED_HGLOBAL, $TYMED_MFPICT, $TYMED_NULL, $TYMED_ISTREAM, $TYMED_ISTORAGE ; they are accepted Case Else If Not $fRelease And DllStructGetData($STGMED,"tymed")=$TYMED_FILE Then Return $DV_E_FORMATETC EndSwitch If Not $fRelease Then $STGMED = DllStructCreate($tagSTGMEDIUM) Local $FormatEtc = DllStructCreate($tagFORMATETC) If Not DeepCopyStgMedium(DllStructGetPtr($STGMED) , $pMedium) Then Return $E_OUTOFMEMORY DeepCopyFormatEtc(DllStructGetPtr($FormatEtc) , $pFormatEtc) $pMedium = DllStructGetPtr($STGMED) $pFormatEtc = DllStructGetPtr($FormatEtc) EndIf Local $st = DllStructCreate($tagIDataObject, $pObject) Local $pArrFormatEtc = DllStructGetData($st, "pFORMATETC") Local $pArrStgMedium = DllStructGetData($st, "pSTGMEDIUM") Local $dwCount = DllStructGetData($st, "Count") Local $idx = __DataObj_LookupFormatEtc($pFormatEtc, $pArrFormatEtc, $dwCount) If $idx == -1 Then _MemArrayAdd($pArrFormatEtc, $pFormatEtc) _MemArrayAdd($pArrStgMedium, $pMedium) DllStructSetData($st, "Count", $dwCount+1) Else Local $ptd = DllStructGetData(_MemArrayGet($pArrFormatEtc, $idx, $tagFORMATETC),"ptd") If $ptd Then _CoTaskMemFree($ptd) _MemArraySet($pArrFormatEtc, $idx, $pFormatEtc) Local $Med = _MemArrayGet($pArrStgMedium, $idx, $tagSTGMEDIUM) _ReleaseStgMedium($Med) _MemArraySet($pArrStgMedium, $idx, $pMedium) EndIf If DllStructGetData($STGMED,"pUnkForRelease") = $pObject Then Local $IUnk = _ObjCreateFromPtr($pMedium,$IUnknown_vTable) _IUnknown_Release($IUnk) EndIf Return $S_OK EndFunc ;==>__IDataObj_SetData ; Author: Prog@ndy Func __IDataObj_EnumFormatEtc($pObject, $dwDirection, $ppEnumFormatEtc) Switch $dwDirection Case $DATADIR_GET Local $st = DllStructCreate($tagIDataObject, $pObject) ;~ Local $result = DllCall("shell32.dll", $HRESULT, "SHCreateStdEnumFmtEtc", "uint", DllStructGetData($st, "Count"), "ptr", DllStructGetData($st, "pFORMATETC"), "ptr*", 0) ;[[[ Array Local $pFORMATETC = DllStructGetData($st, "pFORMATETC") Local $result = DllCall("shell32.dll", $HRESULT, "SHCreateStdEnumFmtEtc", "uint", DllStructGetData($st, "Count"), "ptr", __MemArrayLockedPtr($pFORMATETC), "ptr*", 0) __MemArrayUnLock($pFORMATETC) ;]]] Array Local $pEnumFormatEtc = DllStructCreate("ptr",$ppEnumFormatEtc) DllStructSetData($pEnumFormatEtc,1,$result[3]) Return _Iif($result[3]=0, $E_OUTOFMEMORY, $S_OK) Case Else ;~ Return $E_NOTIMPL Return $OLE_S_USEREG ; No support for all formats, but this is easier :P EndSwitch EndFunc ;==>__IDataObj_EnumFormatEtc ; Author: Prog@ndy Func __IDataObj_DAdvise($pObject, $pFormatEtc, $advf, $pAdvSink, $pdwConnection) Return $OLE_E_ADVISENOTSUPPORTED; EndFunc ;==>__IDataObj_DAdvise ; Author: Prog@ndy Func __IDataObj_DUnadvise($pObject, $dwConnection) Return $OLE_E_ADVISENOTSUPPORTED; EndFunc ;==>__IDataObj_DUnadvise ; Author: Prog@ndy Func __IDataObj_EnumDAdvise($pObject, $ppEnumAdvise) Return $OLE_E_ADVISENOTSUPPORTED; EndFunc ;==>__IDataObj_EnumDAdvise ; Author: Prog@ndy Func _DragDrop_SIZEOF($tagStruct) Return DllStructGetSize(DllStructCreate($tagStruct, 1)) EndFunc ;==>_DragDrop_SIZEOF ; Author: Prog@ndy Func _CreateIDataObject(ByRef $fmtetc, ByRef $stgmed) If Not IsArray($fmtetc) Or UBound($fmtetc) <> UBound($stgmed) Then Return SetError(1, 0, 0) Local $iCount = UBound($fmtetc) Local $sizeIDataObj = _DragDrop_SIZEOF($tagIDataObject) ;~ Local $pObj = _MemGlobalAlloc($sizeIDataObj + ($iCount * $sizeFORMATETC) + ($iCount * $sizeSTGMEDIUM), $GPTR) ;[[[ Array Local $pObj = _MemGlobalAlloc($sizeIDataObj, $GPTR) Local $pFORMATETC = _MemArrayCreate($tagFORMATETC) Local $pSTGMEDIUM = _MemArrayCreate($tagSTGMEDIUM) ;]]] Array Local $stObj = DllStructCreate($tagIDataObject, $pObj) DllStructSetData($stObj, "vTable", DllStructGetPtr($__IDataObj_vTable)) DllStructSetData($stObj, "dwRefCount", 1) ;~ Local $pPtr = $pObj + $sizeIDataObj DllStructSetData($stObj, "Count", $iCount) ;~ DllStructSetData($stObj, "pFORMATETC", $pPtr) DllStructSetData($stObj, "pFORMATETC", $pFORMATETC) For $i = 0 To $iCount - 1 ;~ _MemMoveMemory(DllStructGetPtr($fmtetc[$i]), $pPtr, $sizeFORMATETC) ;~ _RtlCopyMemory(DllStructGetPtr($fmtetc[$i]), $pPtr, $sizeFORMATETC) _MemArrayAdd($pFORMATETC, $fmtetc[$i]) ;~ $pPtr += $sizeFORMATETC Next ;~ DllStructSetData($stObj, "pSTGMEDIUM", $pPtr) DllStructSetData($stObj, "pSTGMEDIUM", $pSTGMEDIUM) For $i = 0 To $iCount - 1 ;~ _MemMoveMemory(DllStructGetPtr($stgmed[$i]), $pPtr, $sizeSTGMEDIUM) ;~ _RtlCopyMemory(DllStructGetPtr($stgmed[$i]), $pPtr, $sizeSTGMEDIUM) _MemArrayAdd($pSTGMEDIUM, $stgmed[$i]) ;~ $pPtr += $sizeSTGMEDIUM Next Local $result[3] = [$pObj, $stObj, $__IDataObj_vTable] Return $result EndFunc ;==>_CreateIDataObject ; Author: Prog@ndy Func _ReleaseIDataObject(ByRef $IDataObj) Local $res = _ObjFuncCall("ulong",$IDataObj,"Release") If @error Then Return SetError(1,0,-1) If $res[0] = 0 Then $IDataObj = 0 EndIf Return $res[0] EndFunc ; Author: Prog@ndy Func _RtlCopyMemory($pSource, $pDest, $iLength) DllCall("msvcrt.dll", "none:cdecl", "memcpy", "ptr", $pDest, "ptr", $pSource, "dword", $iLength) EndFunc ;==>_RtlCopyMemory ; Author: Prog@ndy ; translated from C++ Func DupGlobalMemMem($hMem) Local $len = _MemGlobalSize($hMem); Local $source = _MemGlobalLock($hMem); If $source = 0 Then $source = $hMem ;~ Local $dest = _MemGlobalAlloc($len, BitOR($GMEM_MOVEABLE,$GMEM_SHARE)); Local $dest = _MemGlobalAlloc($len, BitOR($GMEM_FIXED,$GMEM_SHARE)); ;~ _MemMoveMemory($source, _MemGlobalLock($dest), $len); _RtlCopyMemory($source, _MemGlobalLock($dest), $len); _MemGlobalUnlock($dest); _MemGlobalUnlock($hMem); Return $dest; EndFunc ;==>DupGlobalMemMem Func DeepCopyStgMedium($pDest, $pSource) __MemCopyMemory($pSource,$pDest,$sizeSTGMEDIUM) Local $stSource = DllStructCreate($tagSTGMEDIUM,$pSource) Local $Souce_tymed = DllStructGetData($stSource,"tymed") Local $data = DllStructGetData($stSource,"hGlobal"), $newData Switch $Souce_tymed Case $TYMED_NULL Return True Case $TYMED_HGLOBAL $newData = _CloneHGLOBAL($data) Case $TYMED_GDI $newData = _CloneBitmap($data) Case $TYMED_ENHMF $newData = _CloneEnhMetaFile($data) Case $TYMED_MFPICT $newData = _CloneMetaFile($data) Case $TYMED_ISTREAM, $TYMED_ISTORAGE Local $IUnk = _ObjCreateFromPtr($data,$IUnknown_vTable) _IUnknown_AddRef($IUnk) Return True Case Else Return False EndSwitch If DllStructGetData($stSource,"pUnkForRelease") Then Local $IUnk = _ObjCreateFromPtr(DllStructGetData($stSource,"pUnkForRelease"),$IUnknown_vTable) _IUnknown_AddRef($IUnk) EndIf DllStructSetData(DllStructCreate($tagSTGMEDIUM,$pDest),"hGlobal",$newData) Return True EndFunc ; Author: Prog@ndy Func _CloneBitmap($hBmp) Local $result = DllCall("user32.dll", "ptr", "CopyImage", "ptr", $hBmp, "uint", 0, "int",0, "int",0, "uint", 0) Return $result[0] EndFunc ; Author: Prog@ndy Func _CloneEnhMetaFile($hemfSrc) Local $result = DllCall("Gdi32.dll", "ptr", "CopyEnhMetaFileW", "ptr", $hemfSrc, "ptr", 0) Return $result[0] EndFunc ; Author: Prog@ndy Func _CloneMetaFile($hemfSrc) Local $result = DllCall("Gdi32.dll", "ptr", "CopyMetaFileW", "ptr", $hemfSrc, "ptr", 0) Return $result[0] EndFunc ; Author: Prog@ndy Func _CloneHGLOBAL($hMem) Local $Size = _MemGlobalSize($hMem) Local $Flags = __MemGlobalFlags($hMem) If $Flags = $GMEM_INVALID_HANDLE Then Return SetError(1,0,0) Local $hNewMem = _MemGlobalAlloc($Size,$Flags) Local $pNewMem = _MemGlobalLock($hNewMem) Local $pMem = _MemGlobalLock($hMem) __MemCopyMemory($pMem, $pNewMem, $Size) _MemGlobalUnlock($hNewMem) _MemGlobalUnlock($hMem) Return $hNewMem EndFunc ; Author: Prog@ndy ; translated from C++ Func DeepCopyFormatEtc($pDest, $pSource) ;// copy the source FORMATETC into dest __MemCopyMemory($pSource,$pDest,$sizeFORMATETC) Local $Souce_ptd = DllStructGetData(DllStructCreate($tagFORMATETC,$pSource),"ptd") if($Souce_ptd) Then ;// allocate memory for the DVTARGETDEVICE if necessary Local $dest_ptd = _CoTaskMemAlloc(_DragDrop_SIZEOF($tagDVTARGETDEVICE)); ;// copy the contents of the source DVTARGETDEVICE into dest->ptd __MemCopyMemory($Souce_ptd, $dest_ptd, _DragDrop_SIZEOF($tagDVTARGETDEVICE)) ;*(dest->ptd) = *(source->ptd); DllStructSetData(DllStructCreate($tagFORMATETC,$pDest),"ptd",$dest_ptd) EndIf EndFunc ; Author: Prog@ndy ; translated from C++ Func __DataObj_LookupFormatEtc($pFormatEtc, $pAvailableFormats, $dwCount) Local $FormatEtc = DllStructCreate($tagFORMATETC, $pFormatEtc), $next ;// check each of our formats in turn to see if one matches ;~ Local $pPtr = $pAvailableFormats For $i = 0 To $dwCount - 1 ;~ $next = DllStructCreate($tagFORMATETC, $pPtr) $next = _MemArrayGet($pAvailableFormats, $i, $tagFORMATETC) ; "dword cfFormat; ptr ptd; DWORD dwAspect; LONG lindex; DWORD tymed;" If ( ( DllStructGetData($next, 1) = DllStructGetData($FormatEtc, 1) ) And _ ( DllStructGetData($next, 3) = DllStructGetData($FormatEtc, 3) ) And _ ( DllStructGetData($next, 4) = DllStructGetData($FormatEtc, 4) ) And _ ( BitAND(DllStructGetData($next, 5), DllStructGetData($FormatEtc, 5)) <> 0 ) ) Then ;// return index of stored format Return $i; ;~ $pPtr += $sizeFORMATETC EndIf Next ;// error, format not found Return -1; EndFunc ;==>__DataObj_LookupFormatEtc ; Author: Prog@ndy Func _ReleaseStgMedium(ByRef $stgmed) Local $ptr If IsDllStruct($stgmed) Then $ptr = DllStructGetPtr($stgmed) ElseIf IsPtr($stgmed) Then $ptr = $stgmed Else Return SetError(1) EndIf DllCall("ole32.dll","none", "ReleaseStgMedium", "ptr", $ptr) EndFunc #EndRegion IDataObject ; -- #EndRegion IDataObject ------------------------------------------------------------- ; Author: Prog@ndy Func _DoDragDrop(ByRef $objIDataSource, ByRef $objIDropSource, $dwDropEffects, ByRef $dwPerformedEffect) Local $result = DllCall($OLE32,$HRESULT,"DoDragDrop", "ptr", _ObjGetObjPtr($objIDataSource),"ptr", _ObjGetObjPtr($objIDropSource), "dword", BitOR($DROPEFFECT_MOVE,$DROPEFFECT_COPY,$DROPEFFECT_LINK), "dword*", 0) $dwPerformedEffect = $result[4] Return $result[0] EndFunc Func _Iif($FTEST, $VTRUEVAL, $VFALSEVAL) If $FTEST Then Return $VTRUEVAL Else Return $VFALSEVAL EndIf EndFunc objbase.au3 Global Const $OLE32 = DllOpen("ole32.dll") ; Prog@ndy Func MAKE_HRESULT($sev,$fac,$code) Return BitOR(BitShift($sev,-31) , BitOR(BitShift($fac,-16), $code)) EndFunc Global Const $CLSCTX_INPROC_SERVER = 1 Global Const $CLSCTX_LOCAL_SERVER = 4 Global Const $CLSCTX_SERVER = BitOR($CLSCTX_INPROC_SERVER , $CLSCTX_LOCAL_SERVER) Global Const $HRESULT = "lresult" ;~ Global Const $S_OK = 0 ;~ Global Const $E_NOINTERFACE = 0x80004002 ;~ Global Const $E_ABORT = 0x80004004 ;~ Global Const $E_ACCESSDENIED = 0x80070005 ;~ Global Const $E_FAIL = 0x80004005 ;~ Global Const $E_INVALIDARG = 0x80070057 ;~ Global Const $E_HANDLE = 0x80070006 ;~ Global Const $E_NOTIMPL = 0x80004001 ;~ Global Const $E_OUTOFMEMORY = 0x8007000E ;~ Global Const $E_PENDING = 0x8000000A ;~ Global Const $E_POINTER = 0x80004003 ;~ Global Const $E_UNEXPECTED = 0x8000FFFF Global Const $OLE_E_ADVF = 0x80040001 Global Const $OLE_E_ADVISENOTSUPPORTED = 0x80040003 Global Const $OLE_E_BLANK = 0x80040007 Global Const $OLE_E_CANT_BINDTOSOURCE = 0x8004000A Global Const $OLE_E_CANT_GETMONIKER = 0x80040009 Global Const $OLE_E_CANTCONVERT = 0x80040011 Global Const $OLE_E_CLASSDIFF = 0x80040008 Global Const $OLE_E_ENUM_NOMORE = 0x80040002 Global Const $OLE_E_FIRST = 0x80040000 Global Const $OLE_E_INVALIDHWND = 0x8004000F Global Const $OLE_E_INVALIDRECT = 0x8004000D Global Const $OLE_E_LAST = 0x800400FF Global Const $OLE_E_NOCACHE = 0x80040006 Global Const $OLE_E_NOCONNECTION = 0x80040004 Global Const $OLE_E_NOSTORAGE = 0x80040012 Global Const $OLE_E_NOT_INPLACEACTIVE = 0x80040010 Global Const $OLE_E_NOTRUNNING = 0x80040005 Global Const $OLE_E_OLEVERB = 0x80040000 Global Const $OLE_E_PROMPTSAVECANCELLED = 0x8004000C Global Const $OLE_E_STATIC = 0x8004000B Global Const $OLE_E_WRONGCOMPOBJ = 0x8004000E Global $IID_IUnknown = _GUID("{00000000-0000-0000-C000-000000000046}") Global Const $tagIID = "DWORD Data1; ushort Data2; ushort Data3; BYTE Data4[8];" ; Prog@ndy Func _GUID($IID) $IID = StringRegExpReplace($IID,"([}{])","") $IID = StringSplit($IID,"-") Local $_GUID = "DWORD Data1; ushort Data2; ushort Data3; BYTE Data4[8];" Local $GUID = DllStructCreate($_GUID) If $IID[0] = 5 Then $IID[4] &= $IID[5] If $IID[0] > 5 Or $IID[0] < 4 Then Return SetError(1,0,0) DllStructSetData($GUID,1,Dec($IID[1])) DllStructSetData($GUID,2,Dec($IID[2])) DllStructSetData($GUID,3,Dec($IID[3])) DllStructSetData($GUID,4,Binary("0x"&$IID[4])) Return $GUID EndFunc ; Prog@ndy ; compares two GUID / IID DLLStructs Func _GUID_Compare(ByRef $IID1, ByRef $IID2) Local $a,$b For $i = 1 To 4 $a = DllStructGetData($IID1,$i) If @error Then Return SetError(1,0,0) $b = DllStructGetData($IID2,$i) If @error Then Return SetError(1,0,0) If $a <> $b Then Return 0 Next Return 1 EndFunc ; The IUnknown-Interface ; description: http://www.reactos.org/generated/doxygen/d8/de9/interfaceIUnknown.html Global Const $IUnknown = "ptr IUnknown;" Global Const $IUnknown_vTable = "ptr QueryInterface; ptr AddRef; ptr Release;" ;~ /*** IUnknown methods ***/ ;~ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; ; Prog@ndy Func _IUnknown_QueryInterface(ByRef $ObjArr, ByRef $REFIID) Local $ret = _ObjFuncCall($HRESULT, $ObjArr, "QueryInterface", "ptr", DllStructGetPtr($REFIID), "ptr*", 0) If @error Then Return SetError(1,0,0) Return SetError($ret[0],0,$ret[3]) EndFunc ; Prog@ndy Func _IUnknown_AddRef(ByRef $ObjArr) Local $ret = _ObjFuncCall("ULONG", $ObjArr, "AddRef") If @error Then Return SetError(1,0,0) Return SetError($ret[0]<1,0,$ret[0]) EndFunc ; Prog@ndy Func _IUnknown_Release(ByRef $ObjArr) Local $ret = _ObjFuncCall("ULONG", $ObjArr, "Release") If @error Then Return SetError(1,0,0) Return SetError($ret[0],0,$ret[0]=0) EndFunc ; -- #Region MemoryCalls ----------------------------------- #Region Call ObjectFuncs ; _ObjFunc.. are the MemoryFunc... functions from http://www.autoitscript.com/forum/index.php?showtopic=77463 ;~ Global $__COMFN_HookPtr, $__COMFN_HookBak, $__COMFN_HookApi = "LocalFlags", $__COMFN_Kernel32Dll = DllOpen("kernel32.dll") Global $__COMFN_HookPtr, $__COMFN_HookBak, $__COMFN_HookApi = "LocalCompact", $__COMFN_Kernel32Dll = DllOpen("kernel32.dll") ; by Ward Func _ObjFuncInit() Local $KernelHandle = DllCall($__COMFN_Kernel32Dll, "ptr", "LoadLibrary", "str", "kernel32.dll") Local $HookPtr = DllCall($__COMFN_Kernel32Dll, "ptr", "GetProcAddress", "ptr", $KernelHandle[0], "str", $__COMFN_HookApi) $__COMFN_HookPtr = $HookPtr[0] $__COMFN_HookBak = DllStructCreate("ubyte[7]") DllCall($__COMFN_Kernel32Dll, "int", "WriteProcessMemory", "ptr", -1, "ptr", DllStructGetPtr($__COMFN_HookBak), "ptr", $__COMFN_HookPtr, "uint", 7, "uint*", 0) DllCall($__COMFN_Kernel32Dll, "int", "WriteProcessMemory", "ptr", -1, "ptr", $__COMFN_HookPtr, "byte*", 0xB8, "uint", 1, "uint*", 0) DllCall($__COMFN_Kernel32Dll, "int", "WriteProcessMemory", "ptr", -1, "ptr", $__COMFN_HookPtr + 5, "ushort*", 0xE0FF, "uint", 2, "uint*", 0) EndFunc ; by Ward ; modified by Prog@ndy ; Return array: [0] - result ; [1] - Object Pointer ; [2] - first parameter ; [n+1] - n-th Parameter Func _ObjFuncCall($RetType, ByRef $ObjArr, $sFuncName, $Type1 = "", $Param1 = 0, $Type2 = "", $Param2 = 0, $Type3 = "", $Param3 = 0, $Type4 = "", $Param4 = 0, $Type5 = "", $Param5 = 0, $Type6 = "", $Param6 = 0, $Type7 = "", $Param7 = 0, $Type8 = "", $Param8 = 0, $Type9 = "", $Param9 = 0, $Type10 = "", $Param10 = 0, $Type11 = "", $Param11 = 0, $Type12 = "", $Param12 = 0, $Type13 = "", $Param13 = 0, $Type14 = "", $Param14 = 0, $Type15 = "", $Param15 = 0, $Type16 = "", $Param16 = 0, $Type17 = "", $Param17 = 0, $Type18 = "", $Param18 = 0, $Type19 = "", $Param19 = 0, $Type20 = "", $Param20 = 0) If Not IsDllStruct($__COMFN_HookBak) Then _ObjFuncInit() Local $Address = _ObjGetFuncPtr($ObjArr,$sFuncName) If @error Then Return SetError(1,-1,0) If $Address = 0 Then Return SetError(3,-1,0) _ObjFuncSet($Address) Local $Ret Switch @NumParams Case 3 $Ret = DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0]) Case 5 $Ret = DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0], $Type1, $Param1) Case 7 $Ret = DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0], $Type1, $Param1, $Type2, $Param2) Case 9 $Ret = DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0], $Type1, $Param1, $Type2, $Param2, $Type3, $Param3) Case 11 $Ret = DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0], $Type1, $Param1, $Type2, $Param2, $Type3, $Param3, $Type4, $Param4) Case 13 $Ret = DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0], $Type1, $Param1, $Type2, $Param2, $Type3, $Param3, $Type4, $Param4, $Type5, $Param5) Case Else If Mod(@NumParams,2)=0 Then Return SetError(2,-1,0) Local $DllCallStr = 'DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0]', $n, $i For $i = 5 To @NumParams Step 2 $n = ($i - 3) / 2 $DllCallStr &= ', $Type' & $n & ', $Param' & $n Next $DllCallStr &= ')' $Ret = Execute($DllCallStr) EndSwitch SetError(@error,@extended) Return $Ret EndFunc ; by Ward Func _ObjFuncSet($Address) DllCall($__COMFN_Kernel32Dll, "int", "WriteProcessMemory", "ptr", -1, "ptr", $__COMFN_HookPtr + 1, "uint*", $Address, "uint", 4, "uint*", 0) EndFunc ; by Ward Func _ObjFuncExit() DllCall($__COMFN_Kernel32Dll, "int", "WriteProcessMemory", "ptr", -1, "ptr", $__COMFN_HookPtr, "ptr", DllStructGetPtr($__COMFN_HookBak), "uint", 7, "uint*", 0) $__COMFN_HookBak = 0 EndFunc #EndRegion ; -- #EndRedion MemoryCalls ----------------------------------- ; Prog@ndy Func _ObjCreateFromPtr($ObjPointer, $vTable) If Not $ObjPointer Then Return SetError(1,0,0) Local $object[3] = [$ObjPointer] $object[1] = DllStructCreate("ptr lpvTable",Ptr($object[0])) If @error Then Return SetError(2,0 ,0) $object[2] = DllStructCreate($vTable,DllStructGetData($object[1],1)) If @error Then Return SetError(3,0,0) Return $object EndFunc ; Prog@ndy Func _ObjCoCreateInstance(ByRef $CLSID, ByRef $IID,$ObjvTable) ;~ Local $ret = DllCall($OLE32,"long_ptr","CoCreateInstance","ptr",DllStructGetPtr($CLSID),"ptr",0,"dword",$CLSCTX_SERVER, "ptr",DllStructGetPtr($IID),"ptr*",0) Local $ret = DllCall($OLE32,"long_ptr","CoCreateInstance","ptr",DllStructGetPtr($CLSID),"ptr",0,"dword",$CLSCTX_INPROC_SERVER, "ptr",DllStructGetPtr($IID),"ptr*",0) Local $object[3] = [$ret[5],0,0] ; get the interface $object[1] = DllStructCreate("ptr lpvTable",$object[0]) $object[2] = DllStructCreate($ObjvTable,DllStructGetData($object[1],1)) Return $object EndFunc ; Prog@ndy Func _ObjCoInitialize() Local $result = DllCall($OLE32,$HRESULT,"CoInitialize","ptr",0) Return $result[0] EndFunc ; Prog@ndy Func _ObjCoUninitialize() Local $result = DllCall($OLE32,$HRESULT,"CoUninitialize") Return $result[0] EndFunc ; Prog@ndy Func _ObjGetFuncPtr(ByRef $ObjArr, $FuncName) If UBound($ObjArr)<>3 Then Return SetError(1,0,0) Return DllStructGetData($ObjArr[2],$FuncName) EndFunc ; Prog@ndy Func _ObjGetObjPtr(ByRef $ObjArr) If UBound($ObjArr)<>3 Then Return SetError(1,0,0) If DllStructGetData($ObjArr[1],1)=0 Then Return SetError(2,0,0) Return $ObjArr[0] EndFunc ; Prog@ndy Func _OLEInitialize() Local $result = DllCall($OLE32,$HRESULT,"OleInitialize","ptr",0) Return $result[0] EndFunc ; Prog@ndy Func _OLEUnInitialize() Local $result = DllCall($OLE32,$HRESULT,"OleUninitialize") Return $result[0] EndFunc Func _CoTaskMemAlloc($iSize) Local $result = DllCall($OLE32, "ptr", "CoTaskMemAlloc", "ulong", $iSize) Return $result[0] EndFunc Func _CoTaskMemFree($pMem) DllCall($OLE32, "none", "CoTaskMemFree", "ptr", $pMem) EndFunc Func _CoTaskMemRealloc($pMem, $iSize) Local $result = DllCall($OLE32, "ptr", "CoTaskMemRealloc", "ptr", $pMem, "ulong", $iSize) Return $result[0] EndFunc MemArray.au3 #include<Memory.au3> #include<Array.au3> Global Const $__MemArray_HEAD = "dword iElSize;" Global Const $__MemArray_HEADSIZE = __MemArray_SIZEOF($__MemArray_HEAD) ; Author: Prog@ndy Func __MemArray_SIZEOF($tagStruct) Return DllStructGetSize(DllStructCreate($tagStruct, 1)) EndFunc ;==>__MemArray_SIZEOF Func __MemArrayLockedPtr($hMem) If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1,0,0) Return _MemGlobalLock($hMem)+$__MemArray_HEADSIZE EndFunc Func __MemArrayUnLock($hMem) If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1,0,0) _MemGlobalUnlock($hMem) EndFunc ; Author: Prog@ndy Func _MemArrayCreate($tagStruct) Local $iSize = __MemArray_SIZEOF($tagStruct) If $iSize = 0 Then Return SetError(1, 0, 0) Local $hMem = _MemGlobalAlloc($__MemArray_HEADSIZE, $GMEM_MOVEABLE) If $hMem = 0 Then Return SetError(2, 0, 0) DllStructSetData(DllStructCreate($__MemArray_HEAD, _MemGlobalLock($hMem)), 1, $iSize) _MemGlobalUnlock($hMem) Return $hMem EndFunc ;==>_MemArrayCreate ; Author: Prog@ndy Func __MemArrayElementSize($hMem) If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, 0) Local $iSize = DllStructGetData(DllStructCreate($__MemArray_HEAD, _MemGlobalLock($hMem)), 1) _MemGlobalUnlock($hMem) Return $iSize EndFunc ;==>__MemArrayElementSize ; Author: Prog@ndy Func _MemArrayFree($hMem) Return _MemGlobalFree($hMem) EndFunc ;==>_MemArrayFree ; Author: Prog@ndy Func _MemArrayAdd($hMem, ByRef $stEntry) If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, -1) If Not (IsDllStruct($stEntry) Or IsPtr($stEntry)) Then Return SetError(2, 0, -1) Local $size = _MemGlobalSize($hMem) Local $iElSize = __MemArrayElementSize($hMem) Local $result = __MemGlobalReAlloc($hMem, $size + $iElSize, $GHND) If Not $result Then Return SetError(2, 0, 0) Local $indX = (($size - $__MemArray_HEADSIZE) / $iElSize) If IsPtr($stEntry) Then __MemCopyMemory($stEntry, _MemGlobalLock($hMem) + $size, $iElSize) Else __MemCopyMemory(DllStructGetPtr($stEntry), _MemGlobalLock($hMem) + $size, $iElSize) EndIf _MemGlobalUnlock($hMem) Return $indX EndFunc ;==>_MemArrayAdd ; Author: Prog@ndy Func _MemArrayDelete($hMem, $indX) If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, 0) Local $size = _MemGlobalSize($hMem) Local $iElSize = __MemArrayElementSize($hMem) Local $maxIndX = ($size - $__MemArray_HEADSIZE) / $iElSize If $indX < 0 Or $indX > $maxIndX Then Return SetError(2, 0, 0) If $size > ($__MemArray_HEADSIZE + $iElSize) Then Local $hPtr = _MemGlobalLock($hMem) Local $deletedElementOffset = ($indX * $iElSize) + $__MemArray_HEADSIZE _MemMoveMemory($hPtr + $deletedElementOffset + $iElSize, $hPtr + $deletedElementOffset, $size - ($deletedElementOffset + $iElSize)) _MemGlobalUnlock($hMem) EndIf __MemGlobalReAlloc($hMem, $size - $iElSize, $GMEM_MOVEABLE) Return 1 EndFunc ;==>_MemArrayDelete ; Author: Prog@ndy Func _MemArrayGet($hMem, $indX, $tagStruct) If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, 0) Local $size = _MemGlobalSize($hMem) Local $iElSize = __MemArrayElementSize($hMem) Local $maxIndX = ($size - $__MemArray_HEADSIZE) / $iElSize If $indX < 0 Or $indX > $maxIndX Then Return SetError(2, 0, 0) If IsPtr($tagStruct) Then __MemCopyMemory(_MemGlobalLock($hMem) + $__MemArray_HEADSIZE + $indX * $iElSize, $tagStruct, $iElSize) Local $struct = $tagStruct Else Local $struct = DllStructCreate($tagStruct) If @error Then Return SetError(2,0,0) __MemCopyMemory(_MemGlobalLock($hMem) + $__MemArray_HEADSIZE + $indX * $iElSize, DllStructGetPtr($struct), $iElSize) EndIf _MemGlobalUnlock($hMem) Return $struct EndFunc ;==>_MemArrayGet ; Author: Prog@ndy Func _MemArrayGetDelete($hMem, $indX, $tagStruct) If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, 0) Local $size = _MemGlobalSize($hMem) Local $iElSize = __MemArrayElementSize($hMem) Local $maxIndX = ($size - $__MemArray_HEADSIZE) / $iElSize If $indX < 0 Or $indX > $maxIndX Then Return SetError(2, 0, 0) Local $hPtr = _MemGlobalLock($hMem) If IsPtr($tagStruct) Then __MemCopyMemory($hPtr + $__MemArray_HEADSIZE + $indX * $iElSize, $tagStruct, $iElSize) Else Local $struct = DllStructCreate($tagStruct) If @error Then Return SetError(2,_MemGlobalUnlock($hMem),0) __MemCopyMemory($hPtr + $__MemArray_HEADSIZE + $indX * $iElSize, DllStructGetPtr($struct), $iElSize) EndIf If $size > ($__MemArray_HEADSIZE + $iElSize) Then Local $deletedElementOffset = ($indX * $iElSize) + $__MemArray_HEADSIZE _MemMoveMemory($hPtr + $deletedElementOffset + $iElSize, $hPtr + $deletedElementOffset, $size - ($deletedElementOffset + $iElSize)) EndIf _MemGlobalUnlock($hMem) __MemGlobalReAlloc($hMem, $size - $iElSize, $GMEM_MOVEABLE) Return $struct EndFunc ;==>_MemArrayGet #cs Func _MemArrayGetToArray($hMem) If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1,0,0) Local $size = _MemGlobalSize($hMem) Local $maxIndX = $size/$__MemArray_PTRSIZE If $maxIndX < 1 Then Return SetError(2,0,0) Local $struct = DllStructCreate("ptr[" & $maxIndX & "]", _MemGlobalLock($hMem) ) Local $array[$maxIndX] For $i = 1 To $maxIndX $array[$i-1] = DllStructGetData($struct,1,$i) Next _MemGlobalUnlock($hMem) Return $array EndFunc #ce ; Author: Prog@ndy Func _MemArraySet($hMem, $indX, ByRef $stEntry) If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, 0) Local $size = _MemGlobalSize($hMem) Local $iElSize = __MemArrayElementSize($hMem) Local $maxIndX = ($size - $__MemArray_HEADSIZE) / $iElSize If $indX < 0 Or $indX > $maxIndX Then Return SetError(2, 0, 0) Local $pEntry = _MemGlobalLock($hMem) + $__MemArray_HEADSIZE + $indX * $iElSize __MemZeroMemory($pEntry, $iElSize) If IsPtr($stEntry) Then __MemCopyMemory($stEntry, $pEntry, $iElSize) ElseIf IsDllStruct($stEntry) Then __MemCopyMemory(DllStructGetPtr($stEntry), $pEntry, $iElSize) Else Return SetError(2,0,0) EndIf _MemGlobalUnlock($hMem) Return 1 EndFunc ;==>_MemArraySet ; Author: Prog@ndy Func _MemArrayUBound($hMem) If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, 0) Local $iElSize = __MemArrayElementSize($hMem) Return ((_MemGlobalSize($hMem) - $__MemArray_HEADSIZE) / $iElSize) EndFunc ;==>_MemArrayUBound ; Author: Prog@ndy Func __MemIsGlobal($hMem) Local $result = __MemGlobalFlags($hMem) If @error Or $result == $GMEM_INVALID_HANDLE Then Return 0 Return 1 EndFunc ;==>__MemIsGlobal ; Author: Prog@ndy Func __MemGlobalReAlloc($hMem, $iBytes, $iFlags) Local $aResult = DllCall("Kernel32.dll", "ptr", "GlobalReAlloc", "ptr", $hMem, "ulong", $iBytes, "uint", $iFlags) Return $aResult[0] EndFunc ;==>__MemGlobalReAlloc ; Author: Prog@ndy Func __MemGlobalFlags($hMem) Local $aResult = DllCall("Kernel32.dll", "uint", "GlobalFlags", "ptr", $hMem) Return $aResult[0] EndFunc ;==>__MemGlobalFlags ; Author: Prog@ndy Func __MemGlobalDiscard($hMem) Return __MemGlobalReAlloc($hMem, 0, $GMEM_MOVEABLE) EndFunc ;==>__MemGlobalDiscard ; Author: Prog@ndy Func __MemCopyMemory($pSource, $pDest, $iLength) DllCall("msvcrt.dll", "none:cdecl", "memcpy", "ptr", $pDest, "ptr", $pSource, "dword", $iLength) EndFunc ;==>__MemCopyMemory ; Author: Prog@ndy Func __MemFillMemory($pDest, $ubFill, $iLength) DllCall("kernel32.dll", "none", "RtlFillMemory", "ptr", $pDest, "dword", $iLength, "ubyte", $ubFill) EndFunc ;==>__MemFillMemory ; Author: Prog@ndy Func __MemZeroMemory($pDest, $iLength) DllCall("kernel32.dll", "none", "RtlZeroMemory", "ptr", $pDest, "dword", $iLength) EndFunc ;==>__MemZeroMemory ๐Ÿ˜ท
    1 point
  5. If you set Per-Monitor or Per-Monitor (V2) DPI Awareness then you must to resize and reposition the controls each time when receive WM_DPICHANGED message. Otherwise, the controls will match the DPI of the primary monitor, while other monitors may have different DPI.
    1 point
  6. It's not that easy to translate a script. The old functions connect to Excel on every call. The new UDF does it once by calling _Excel_Open. I suggest to either use the old or the new UDF. Mixing them by writing wrappers takes time and is hard to debug.
    1 point
  7. I see some emotions popping up and that was not the intention, merely needed verification I understood what is expected. So let me answer my own last request using the last example giving: So we have this script and somebody hits F5/F7 on this "before" script: #AutoIt3Wrapper_Res_HiDpi=y Opt('GUICloseOnESC', 1) Global $TestApp $TestApp = GUICreate('testing', 500, 300, -1, -1) ;if x,y coordinates are specified, they need the scaling also. GUICtrlCreateButton("<This is just a test>", 38, 140, 200, 25) GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case -3 Exit EndSwitch WEnd .. and the expectation is that it will be changed to something like this "after" script adding/changing all the missing bits: #AutoIt3Wrapper_Res_HiDpi=y #include <GDIPlus.au3> ;### Added by Res_HiDpi Opt('GUICloseOnESC', 1) Global $TestApp ;### Start Added by Res_HiDpi ### Global Const $iScale = DPIRatio() Func DPIRatio() _GDIPlus_Startup() Local $hGfx = _GDIPlus_GraphicsCreateFromHWND($TestApp) Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0) _GDIPlus_GraphicsDispose($hGfx) _GDIPlus_Shutdown() If $aResult[2] = 0 Or '' Then Return 1 Else Return $aResult[2] / 96 EndIf EndFunc ;==>DPIRatio ;### End Added by Res_HiDpi ### ;### Commented by Res_HiDpi: $TestApp = GUICreate('testing', 500, 300, -1, -1) ;if x,y coordinates are specified, they need the scaling also. $TestApp = GUICreate('testing', 500 * $iScale, 300 * $iScale, -1, -1) ;### Added by Res_HiDpi ;### Commented by Res_HiDpi: GUICtrlCreateButton("<This is just a test>", 38, 140, 200, 25) GUICtrlCreateButton("<This is just a test>", 38 * $iScale, 140 * $iScale, 200 * $iScale, 25 * $iScale) ;### Added by Res_HiDpi GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case -3 Exit EndSwitch WEnd Well that is not going to happen in autoit3wrapper itself as I feel it doesn't belong there, but when someone has the drive to write a utility for it, it could easily be included like I've done with Tidy/Au3Stripper which also modify the source file. Looking at it I don't think this will be a trivial thing as you need to detect which parts are missing and need to be added in the right spots, but anything is possible when you put your mind to it! Jos
    1 point
  8. Just move your ChildForm() line at the very end of Func WndMain() Because the way it is placed now, all buttons are created in the child form, not in the main GUI ! After that, it should be easy for you to add a close button in the child form (as you already did in the main GUI). Also the example found in the zip file contains a function to create a 2nd GUI Good luck
    1 point
  9. @Danp2 Excellent! Thank you so much! If you don't have a https://www.buymeacoffee.com/ account set up, please get one so I can buy you a drink!
    1 point
  10. @NSearch This works for me -- #include "wd_core.au3" #include "wd_helper.au3" Local $sDesiredCapabilities, $sSession SetupChrome() _WD_Startup() If @error <> $_WD_ERROR_Success Then Exit -1 EndIf $sSession = _WD_CreateSession($sDesiredCapabilities) _WD_Navigate($sSession, "https://www.fedex.com/apps/onlineclaims/?locale=en_US") _WD_LoadWait($sSession, 3000) $Tracking_Number = '962515408056' $Lost_Damaged = "Shipment not received" $sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//input[@id='trackingNumber']") _WD_ElementAction($sSession, $sElement, 'value', $Tracking_Number) _WD_ElementOptionSelect($sSession, $_WD_LOCATOR_ByXPath, "//div/select/option[@value='LC']") _WD_LoadWait($sSession, 3000) $sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//button[@id='tracking_nbr_cont_btn']") _WD_ElementAction($sSession, $sElement, 'click') MsgBox(0,"stop here","") _WD_DeleteSession($sSession) _WD_Shutdown() Func SetupChrome() _WD_Option('Driver', 'chromedriver.exe') _WD_Option('Port', 9515) _WD_Option('DriverParams', '--log-path="' & @ScriptDir & '\chrome.log"') $sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "args":["--disable-blink-features=AutomationControlled"]}}}}' EndFunc ;==>SetupChrome Note -- The argument passed in the DesiredCapacities string helped Without the 2nd _WD_LoadWait, the website still didn't function properly
    1 point
  11. Guys, you are miles ahead of me, which I have tried to explain now several times. I need to understand first what needs to happen where before I can even start considering solutions, so can we please start there with some simple example and answers to my questions? So what about we take a simple helpfile example as basis and you explain what would need to be done to it for this all to work? Thanks!
    1 point
  12. I know my code when I see it. That example was taken from the post below. The inclusion of winhhtp.au3 udf is not needed when using the winhttp.winhttprequest com object. What's the web server's domain name that you are trying to connect to? That web server is requiring a certificate as it says. If it's an in-house web server or one that's under your control and you don't think that it should be requesting a certificate to connect, then it may be misconfigured. If it's a publicly accessible server, then it could be some other reason like a proxy issue or something else completely unrelated. You have not provided enough information to know. Also, why are you trying to capture the return value ($hrequest) from the open method and use it as the post data in the send method? That's wrong for multiple reasons. First, that particular BeyondTrust API (Auth/SignAppin) does not require any post data. Secondly, if it did, it wouldn't usually be the return from the open method. Lastly, the open method doesn't return any value, just an empty string. From the BeyondTrust API Guide 7.2: POST Auth/SignAppin Purpose Authenticates the provided credentials and creates a user session. Required Permissions A user group to which the user belongs must be granted access to the API key given in authorization header. Must be running script from a valid source address as configured in API Registration for the given API key. Request Body None Response Body Content-Type: application/json By the way, do you just create a new account every time you have a new question? ๐Ÿคจ๐Ÿ˜‰
    1 point
  13. I did not find a way to modify font with built-in tooltip but I made it work witn UDF : #include <GUIToolTip.au3> #include <WinAPITheme.au3> #include <SendMessage.au3> #include <WinAPIGdiDC.au3> #include <FontConstants.au3> #include <WindowsConstants.au3> Global $bShow = True HotKeySet("{ESC}", _Exit) Local $hToolTip = _GUIToolTip_Create(0) Local $hDC = _WinAPI_GetDC(0) _WinAPI_SetWindowTheme($hToolTip, "0", "0") _GUIToolTip_SetTipTextColor($hToolTip, 0xFF) _GUIToolTip_SetTipBkColor($hToolTip,0xFF0000) Local $hFont = _WinAPI_CreateFont(32, 0, 0, 0, 800, False, False, False, $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, $DEFAULT_QUALITY, 0, 'Tahoma') _WinAPI_SelectObject($hDC, $hFont) _SendMessage($hToolTip, $WM_SETFONT, $hFont, True) _GUIToolTip_AddTool($hToolTip, 0, "This is a ToolTip Test", 0, 0, 0, 0, 0, BitOR($TTF_TRACK, $TTF_ABSOLUTE)) _GUIToolTip_TrackActivate($hToolTip) While $bShow Sleep(10) _GUIToolTip_TrackPosition($hToolTip,MouseGetPos(0), MouseGetPos(1)) WEnd _GUIToolTip_Destroy($hToolTip) _WinAPI_DeleteObject($hFont) _WinAPI_ReleaseDC(0, $hDC) Func _Exit() $bShow = False EndFunc
    1 point
  14. I can confirm this problem on 3.3.15.3 (on 3.3.14.5 it's OK) , but disabling X64 solves this problem: Add this at top of script: #pragma compile(x64, false) So problem is probably with not X64 compatible code somewhere inside (new?) UDFs ... EDIT2: rechecked now compile as X32 helps only on Win10 (on Win7 it doesn't help) compile as X32 doesn't help neither on Win10 nor on Win7
    1 point
  15. Hi @mLipok Really interesting work on this. I downloaded v2.1.15 beta, and attempting to use your MSSQL example - this is a server I am running locally Func _Example_MSSQL() Local $sDriver = 'SQL Server' Local $sDatabase = 'newserver' ; change this string to YourDatabaseName Local $sServer = 'localhost\SQLEXPRESS' ; change this string to YourServerLocation Local $sUser = 'XXXXX' ; change this string to YourUserName Local $sPassword = 'XXXXXX' ; change this string to YourPassword Local $sConnectionString = 'DRIVER={' & $sDriver & '};SERVER=' & $sServer & ';DATABASE=' & $sDatabase & ';UID=' & $sUser & ';PWD=' & $sPassword & ';' _Example_1_RecordsetToConsole($sConnectionString, "Select * from [RIM_Image_Info]") _Example_2_RecordsetDisplay($sConnectionString, "Select * from SOME_TABLE") _Example_3_ConnectionProperties($sConnectionString) _Example_4_MSSQL($sServer, $sDatabase, $sUser, $sPassword, "Select * from SOME_TABLE") EndFunc ;==>_Example_MSSQL However, when I run it, I get this output, referring to the ADO.au3 UDF file: "C:\Temp\CHW\ADO.au3"(381,89) : error: _ArrayDisplay() called with wrong number of args. _ArrayDisplay($aSelect, $sTitle, "", 0, '|', $sArrayHeader, Default, $iAlternateColors) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ "C:\JRStuff\MyDocs\JR Programs\Macros\autoit-v3-SciTE\Include\Array.au3"(480,176) : REF: definition of _ArrayDisplay(). Func _ArrayDisplay(Const ByRef $aArray, $sTitle = Default, $sArrayRange = Default, $iFlags = Default, $vUser_Separator = Default, $sHeader = Default, $iMax_ColWidth = Default) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ "C:\Temp\CHW\ADO.au3"(385,90) : error: _ArrayDisplay() called with wrong number of args. _ArrayDisplay($aRecordset, $sTitle, "", 0, Default, Default, Default, $iAlternateColors) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ "C:\JRStuff\MyDocs\JR Programs\Macros\autoit-v3-SciTE\Include\Array.au3"(480,176) : REF: definition of _ArrayDisplay(). Func _ArrayDisplay(Const ByRef $aArray, $sTitle = Default, $sArrayRange = Default, $iFlags = Default, $vUser_Separator = Default, $sHeader = Default, $iMax_ColWidth = Default) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ "C:\Temp\CHW\ADO_EXAMPLE.au3"(40,80) : warning: $sFileFullPath: possibly used before declaration. Local $sConnectionString = 'Driver={' & $sDriver & '};Dbq="' & $sFileFullPath & ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ "C:\Temp\CHW\ADO_EXAMPLE.au3"(42,107) : warning: $sConnectionString already declared/assigned Local $sConnectionString = _ADO_ConnectionString_Access($sMDB_FileFullPath, $sUser, $sPassword, $sDriver) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ "C:\Temp\CHW\ADO_EXAMPLE.au3"(40,80) : error: $sFileFullPath: undeclared global variable. Local $sConnectionString = 'Driver={' & $sDriver & '};Dbq="' & $sFileFullPath & ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ C:\Temp\CHW\ADO_EXAMPLE.au3 - 3 error(s), 2 warning(s) !>15:03:25 AU3Check ended. Press F4 to jump to next error.rc:2 Any thoughts? What am I doing wrong? ------------- I fixed it by adding: '_DebugArrayDisplay' instead of '_ArrayDisplay' needed the debug.au3 though.
    1 point
  16. Hiya! I'm currently working on a project which involves the mouse and its properties. For this I was in need for a mouse UDF which could capture certain events. I have found some of the many here on the forums, but quite some are using DLL's. I'm not saying this is bad, it's good! But, my application crashed for unknown reasons when compiled to x64. The way this UDF works, is that it checks every tick for certain conditions to be met. For example: if you have registered a double click event, it will check every frame for double click condition and then call the given function if necessary. So I decided to write my own little _Mouse_UDF powered in autoit itself and share it with the rest of the community. Feel free to leave any feedback, negative or positive. Current events $EVENT_MOUSE_IDLE - triggers when the mouse is idle $EVENT_MOUSE_MOVE - triggers when the mouse moves $EVENT_PRIMARY_CLICK - triggers when the primary button is clicked $EVENT_PRIMARY_DBLCLICK - triggers when the primary button is double clicked $EVENT_PRIMARY_RELEASED - triggers when the primary button is released $EVENT_PRIMARY_DOWN - triggers when the primary button is pressed $EVENT_PRIMARY_UP - triggers when the primaty button is not pressed $EVENT_SECONDARY_CLICK - same as primary conditions, but for this button $EVENT_SECONDARY_DBLCLICK - same as primary conditions, but for this button $EVENT_SECONDARY_RELEASED - same as primary conditions, but for this button $EVENT_SECONDARY_DOWN - same as primary conditions, but for this button $EVENT_SECONDARY_UP - same as primary conditions, but for this button $EVENT_MIDDLE_CLICK - same as primary conditions, but for this button $EVENT_MIDDLE_DBLCLICK - same as primary conditions, but for this button $EVENT_MIDDLE_RELEASED - same as primary conditions, but for this button $EVENT_MIDDLE_DOWN - same as primary conditions, but for this button $EVENT_MIDDLE_UP - same as primary conditions, but for this button $EVENT_X1_CLICK - same as primary conditions, but for this button $EVENT_X1_DBLCLICK - same as primary conditions, but for this button $EVENT_X1_RELEASED - same as primary conditions, but for this button $EVENT_X1_DOWN - same as primary conditions, but for this button $EVENT_X1_UP - same as primary conditions, but for this button $EVENT_X2_CLICK - same as primary conditions, but for this button $EVENT_X2_DBLCLICK - same as primary conditions, but for this button $EVENT_X2_RELEASED - same as primary conditions, but for this button $EVENT_X2_DOWN - same as primary conditions, but for this button $EVENT_X2_UP - same as primary conditions, but for this button Current properties $MOUSE_X - current mouse x $MOUSE_Y current mouse y $MOUSE_PREV_X - previous mouse x $MOUSE_PREV_Y - previous mouse y $MOUSE_VEL_X - current mouse x velocity $MOUSE_VEL_Y - current mouse y velocity Current functions _Mouse_RegisterEvent($iEventType, $sCallBack, $avArgs = -1) - registers a function to an event, use an array for arguments _Mouse_UnRegisterEvent($iEventType) - unregister a function from an event _Mouse_Update() - the main update loop, updates the mouse udf logic _Mouse_GetColor($iColorType, $hWnd = Default) - gets the current mouse xy pixel color, in 3 different color type available; decimal, hex and rgb Mouse UDF.zip
    1 point
  17. akurakkauaaa

    myImageSearch

    description: search image in desktop / picture. not require dll. include: myImageSearch.au3 #include-once #include <ScreenCapture.au3> ; #INDEX# ======================================================================================================================= ; Title .........: myImageSearch ; AutoIt Version: 3.3.6.1 ; Script Version: 1.0 (31.10.2011) ; Language: English, Polski. ; Description: Search image. ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ; myImageSearch_Desktop ; myImageSearch_Picture ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name...........: myImageSearch_Desktop ; Description ...: Znajdz obrazek na pulpicie. ; Syntax.........: myImageSearch_Desktop($Image, $x = 0, $y = 0, $iIW = @DesktopWidth, $iIH = @DesktopHeight, $TransColorRGB = '', $OnlyFirst = True) ; Parameters ....: $Image - znajdz obrazek: adres do szuaknego obrazka, lub bitmapa (format .bmp 24-bit) ; $x - lewe koordynaty [Default is 0 (pierwszy pixel).] ; $y - gorne koordynaty. [Default is 0 (pierwszy pixel).] ; $iIW - prawe koordynaty. [Default is @DesktopWidth.] ; $iIH - dolne koordynaty. [Default is @DesktopHeight.] ; $TransColorRGB - Kolor przezroczystosci / Ignorowany kolor. Musi byc string i format RGB. a.g: "0xFFFFFF".[Default is "".] ; $OnlyFirst - [Default is True.] ; |True = Success: Zwraca tablice 2-elementowa z koordynatami. ; $array[0] = x koordynaty ; $array[1] = y koordynaty ; |False = Success: Zwraca 2D tablice z koordynatami. ; $array[0][0] = 1st x coordinate ; $array[0][1] = 1st y coordinate ; $array[1][0] = 2nd x coordinate ; $array[1][1] = 2nd y coordinate ; $array[3][0] = 3rd x coordinate ; $array[3][1] = 3rd y coordinate ; $array[n][0] = nth x coordinate ; $array[n][1] = nth y coordinate ; ; UWAGA: Jesli uzyjesz "False" to max obszar przeszukiwania moze wynosic 800x600 pixeli, lub ekwiwalent max 480.000 pixeli!!! ; Nie wiecej. ; ; Return values . : On Success - Zwrot tablica 2-elementowa z koordynatami lub 2D tablica z koordynatami. ; On Failure - @Error = 1 - Sciezka do pliku jest bledna, lub bitmapa/obrazek jest bledna. ; @Error = 2 - Obrazka nie znaleziono (na pulpicie). ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name...........: myImageSearch_Desktop ; Description ...: Image search in desktop. ; Syntax.........: myImageSearch_Desktop($Image, $x = 0, $y = 0, $iIW = @DesktopWidth, $iIH = @DesktopHeight, $TransColorRGB = '', $OnlyFirst = True) ; Parameters ....: $Image - search image: string adress for file, or bitmat (format .bmp 24-bit) ; $x - left coordinate. [Default is 0 (first pixel).] ; $y - top coordinate. [Default is 0 (first pixel).] ; $iIW - right coordinate. [Default is @DesktopWidth.] ; $iIH - bottom coordinate. [Default is @DesktopHeight.] ; $TransColorRGB - Color transparancy / Ignore color. Must be string and format RGB. a.g: "0xFFFFFF".[Default is "".] ; $OnlyFirst - [Default is True.] ; |True = Success: Returns a two-element array coordinates. ; $array[0] = x coordinate ; $array[1] = y coordinate ; |False = Success: Returns a 2D array coordinates. ; $array[0][0] = 1st x coordinate ; $array[0][1] = 1st y coordinate ; $array[1][0] = 2nd x coordinate ; $array[1][1] = 2nd y coordinate ; $array[3][0] = 3rd x coordinate ; $array[3][1] = 3rd y coordinate ; $array[n][0] = nth x coordinate ; $array[n][1] = nth y coordinate ; ; ATTENTION: If u use "False" max area for search must be 800x600 pixels, or equivalent maximal 480.000 pixels!!! ; No more. ; ; Return values . : On Success - Returns two-element array coordinates, or 2D array coordinates. ; On Failure - @Error = 1 - Path not found or invalid image/bitmap. ; @Error = 2 - Image not exist (in desktop). ; =============================================================================================================================== Func myImageSearch_Desktop($Image, $x = 0, $y = 0, $iIW = @DesktopWidth, $iIH = @DesktopHeight, $TransColorRGB = '', $OnlyFirst = True) Local $hBMP, $hImage1, $aReturn, $error, $i _GDIPlus_Startup() $hBMP = _ScreenCapture_Capture("", $x, $y, $iIW + $x, $iIH + $y, False) $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) $aReturn = myImageSearch_Picture($hImage1, $Image, 0, 0, $iIW, $iIH, $TransColorRGB, $OnlyFirst) $error = @error _GDIPlus_ImageDispose($hImage1) _WinAPI_DeleteObject($hBMP) _GDIPlus_Shutdown() Switch $error Case 0 If $OnlyFirst Then $aReturn[0] += $x $aReturn[1] += $y Else For $i = 0 To UBound($aReturn, 1) - 1 $aReturn[$i][0] += $x $aReturn[$i][1] += $y Next EndIf Return $aReturn Case 2 Return SetError(1, 1, '') Case Else Return SetError(2, 2, '') EndSwitch EndFunc ;==>myImageSearch_Desktop ; #FUNCTION# ==================================================================================================================== ; Name...........: myImageSearch_Picture ; Description ...: Znajdz obrazek na obrazku. ; Syntax.........: myImageSearch_Picture($hImage1, $hImage2, $x = 0, $y = 0, $iIW = 0, $iIH = 0, $TransColorRGB = '', $OnlyFirst = True) ; Parameters ....: $hImage1 - bazowy obrazek: adres do szuaknego obrazka, lub bitmapa (format .bmp 24-bit) ; $hImage2 - znajdz obrazek: adres do szuaknego obrazka, lub bitmapa (format .bmp 24-bit) ; $x - lewe koordynaty [Default is 0 (pierwszy pixel).] ; $y - gorne koordynaty. [Default is 0 (pierwszy pixel).] ; $iIW - prawe koordynaty. [Default is 0 (0 to ostani pixel (caly obrazek).] ; $iIH - dolne koordynaty. [Default is 0 (0 to ostani pixel (caly obrazek).] ; $TransColorRGB - Kolor przezroczystosci / Ignorowany kolor. Musi byc string i format RGB. a.g: "0xFFFFFF".[Default is "".] ; $OnlyFirst - [Default is True.] ; |True = Success: Zwraca tablice 2-elementowa z koordynatami. ; $array[0] = x koordynaty ; $array[1] = y koordynaty ; |False = Success: Zwraca 2D tablice z koordynatami. ; $array[0][0] = 1st x coordinate ; $array[0][1] = 1st y coordinate ; $array[1][0] = 2nd x coordinate ; $array[1][1] = 2nd y coordinate ; $array[3][0] = 3rd x coordinate ; $array[3][1] = 3rd y coordinate ; $array[n][0] = nth x coordinate ; $array[n][1] = nth y coordinate ; ; UWAGA: Jesli uzyjesz "False" to max obszar przeszukiwania moze wynosic 800x600 pixeli, lub ekwiwalent max 480.000 pixeli!!! ; Nie wiecej. ; ; Return values . : On Success - Zwrot tablica 2-elementowa z koordynatami lub 2D tablica z koordynatami. ; On Failure - @Error = 1 - 1 sciezka do pliku jest bledna, lub bitmapa/obrazek jest bledna. ; @Error = 2 - 2 sciezka do pliku jest bledna, lub bitmapa/obrazek jest bledna. ; @Error = 3 - Obrazka nie znaleziono (na obrazku). ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name...........: myImageSearch_Picture ; Description ...: Image search in picture. ; Syntax.........: myImageSearch_Picture($hImage1, $hImage2, $x = 0, $y = 0, $iIW = 0, $iIH = 0, $TransColorRGB = '', $OnlyFirst = True) ; Parameters ....: $hImage1 - base image: string adress for file, or bitmat (format .bmp 24-bit) ; $hImage2 - search image: string adress for file, or bitmat (format .bmp 24-bit) ; $x - left coordinate. [Default is 0 (first pixel).] ; $y - top coordinate. [Default is 0 (first pixel).] ; $iIW - right coordinate. [Default is 0 (0 is last pixel (full imege).] ; $iIH - bottom coordinate. [Default is 0 (0 is last pixel (full imege).] ; $TransColorRGB - Color transparancy / Ignore color. Must be string and format RGB. a.g: "0xFFFFFF".[Default is "".] ; $OnlyFirst - [Default is True.] ; |True = Success: Returns a two-element array coordinates. ; $array[0] = x coordinate ; $array[1] = y coordinate ; |False = Success: Returns a 2D array coordinates. ; $array[0][0] = 1st x coordinate ; $array[0][1] = 1st y coordinate ; $array[1][0] = 2nd x coordinate ; $array[1][1] = 2nd y coordinate ; $array[3][0] = 3rd x coordinate ; $array[3][1] = 3rd y coordinate ; $array[n][0] = nth x coordinate ; $array[n][1] = nth y coordinate ; ; ATTENTION: If u use "False" max area for search must be 800x600 pixels, or equivalent maximal 480.000 pixels!!! ; No more. ; ; Return values . : On Success - Returns two-element array coordinates, or 2D array coordinates. ; On Failure - @Error = 1 - 1st path not found or invalid image/bitmap. ; @Error = 2 - 2nd path not found or invalid image/bitmap. ; @Error = 3 - Image not exist (in picture). ; =============================================================================================================================== Func myImageSearch_Picture($hImage1, $hImage2, $x = 0, $y = 0, $iIW = 0, $iIH = 0, $TransColorRGB = '', $OnlyFirst = True) Local $testiIW, $testiIH Local $hBitmap1, $Reslt, $width, $height, $stride, $format, $Scan0 Local $iIW_2, $iIH_2, $hBitmap2, $Reslt2, $width2, $height2, $stride2, $format2, $Scan02 Local $sREResult1, $sREResult2, $sREResult3 _GDIPlus_Startup() If IsString($hImage1) Then $hImage1 = _GDIPlus_ImageLoadFromFile($hImage1) EndIf $testiIW = _GDIPlus_ImageGetWidth($hImage1) $testiIH = _GDIPlus_ImageGetHeight($hImage1) If $hImage2 = "" Or $testiIW = 0 Or $testiIH = 0 Then Return SetError(1, 1, '') EndIf If $iIW = 0 Or $testiIW < $iIW Then $iIW = $testiIW If $iIH = 0 Or $testiIH < $iIH Then $iIH = $testiIH $hBitmap1 = _GDIPlus_BitmapCloneArea($hImage1, 0, 0, $iIW, $iIH, $GDIP_PXF32ARGB) $Reslt = _GDIPlus_BitmapLockBits($hBitmap1, $x, $y, $iIW - $x, $iIH - $y, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB) $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") $sREResult1 = DllStructCreate("byte[" & $height * $width * 4 & "]", $Scan0); Create DLL structure for all pixels $sREResult1 = DllStructGetData($sREResult1, 1) _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt); releases the locked region _GDIPlus_ImageDispose($hImage1) _GDIPlus_ImageDispose($hBitmap1) If IsString($hImage2) Then $hImage2 = _GDIPlus_ImageLoadFromFile($hImage2) EndIf $iIW_2 = _GDIPlus_ImageGetWidth($hImage2) $iIH_2 = _GDIPlus_ImageGetHeight($hImage2) If $hImage2 = "" Or $iIW_2 = 0 Or $iIH_2 = 0 Then Return SetError(2, 2, '') EndIf $hBitmap2 = _GDIPlus_BitmapCloneArea($hImage2, 0, 0, $iIW_2, $iIH_2, $GDIP_PXF32ARGB) $Reslt2 = _GDIPlus_BitmapLockBits($hBitmap2, 0, 0, $iIW_2, $iIH_2, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB) $width2 = DllStructGetData($Reslt2, "width") $height2 = DllStructGetData($Reslt2, "height") $stride2 = DllStructGetData($Reslt2, "stride") $format2 = DllStructGetData($Reslt2, "format") $Scan02 = DllStructGetData($Reslt2, "Scan0") $sREResult2 = DllStructCreate("byte[" & $height2 * $width2 * 4 & "]", $Scan02); Create DLL structure for all pixels $sREResult2 = DllStructGetData($sREResult2, 1) _GDIPlus_BitmapUnlockBits($hBitmap2, $Reslt2); releases the locked region _GDIPlus_ImageDispose($hImage2) _GDIPlus_ImageDispose($hBitmap2) _GDIPlus_Shutdown() $sREResult1 = StringTrimLeft($sREResult1, 2) $sREResult2 = StringTrimLeft($sREResult2, 2) If IsString($TransColorRGB) Then ; ignore color $TransColorRGB = StringRegExpReplace($TransColorRGB, "0x(.{2})(.{2})(.{2})", "\3\2\1FF") If $TransColorRGB Then $sREResult2 = StringRegExpReplace($sREResult2, "(.{8})", "\1 ") $sREResult2 = StringReplace($sREResult2, $TransColorRGB, "........") $sREResult2 = StringReplace($sREResult2, " ", "") EndIf EndIf ;ConsoleWrite($sREResult2 & @CRLF) $sREResult2 = StringRegExpReplace($sREResult2, "(.{" & $iIW_2 * 8 & "})", "\\Q\1\\E.\{" & ($iIW - $iIW_2) * 8 & "\}") $sREResult2 = StringTrimRight($sREResult2, StringLen(($iIW - $iIW_2) * 8) + 3) ;ConsoleWrite($sREResult2 & @CRLF) If $TransColorRGB Then $sREResult2 = StringReplace($sREResult2, "........", "\E........\Q") $sREResult2 = StringReplace($sREResult2, "\Q\E", "") $sREResult2 = StringRegExpReplace($sREResult2, "([.}{\w]*)([\\].*[E])([.}{\w]*)", "\2") ; obcina kropki EndIf ;ConsoleWrite($sREResult2 & @CRLF) If $OnlyFirst Then $sREResult2 = '(?i)(.*?)' & $sREResult2 & ".*" ;ConsoleWrite($sREResult2 & @CRLF) $sREResult3 = StringRegExpReplace($sREResult1, $sREResult2, "\1") ; test pathern ("first") If Not @extended Then Return SetError(3, 3, '') ; extendet zero to nie znaleziono nic $sREResult3 = StringLen($sREResult3) / 8 Local $pozycja_Y = Int($sREResult3 / $iIW) + $y Local $pozycja_X = Int($sREResult3 - $pozycja_Y * $iIW) + ($y * $iIW) Local $aReturn[2] = [$pozycja_X, $pozycja_Y] Else $sREResult2 = '(?i)(.*?)(' & $sREResult2 & ".*?)" ; wersja dla wielu winikow ;ConsoleWrite($sREResult2 & @CRLF) $sREResult3 = StringRegExp($sREResult1, $sREResult2, 3) ; test pathern ("mulit") If @error Or Not IsArray($sREResult3) Then Return SetError(3, 3, '') Local $ile = UBound($sREResult3) Local $i Local $aReturn[$ile / 2][2] Local $sREResult4 = 0 Local $pozycja_Y Local $pozycja_X For $i = 0 To $ile - 1 Step 2 $sREResult4 += StringLen($sREResult3[$i]) / 8 If $i > 0 Then $sREResult4 += StringLen($sREResult3[$i + 1]) / 8 $pozycja_Y = Int($sREResult4 / $iIW) + $y $pozycja_X = Int($sREResult4 - $pozycja_Y * $iIW) + ($y * $iIW) $aReturn[$i / 2][0] = $pozycja_X $aReturn[$i / 2][1] = $pozycja_Y Next EndIf Return $aReturn EndFunc ;==>myImageSearch_Picture example: #include <array.au3> #include <myImageSearch.au3> ;Opt('MustDeclareVars', 1) ;########## test 1 Desktop ########## Global $pozycja1 Global $time1 Global $ImageSearch = @ScriptDir & "\recycle.bmp" Global $x = 0 Global $y = 0 Global $w = @DesktopWidth Global $h = @DesktopHeight Global $ColorTrans = '' Global $mOnlyFirst = True Sleep(10) $time1 = TimerInit() $pozycja1 = myImageSearch_Desktop($ImageSearch, $x, $y, $w, $h, $ColorTrans, $mOnlyFirst) If @error Then ConsoleWrite("sorry image not exist" & @CRLF) ConsoleWrite("time 1: " & TimerDiff($time1) / 1000 & ' sek.' & @CRLF) If IsArray($pozycja1) Then _ArrayDisplay($pozycja1) EndIf ;################################## ;########## test 2 Scren ########## Global $pozycja2 Global $time2 Global $ImageBazowe = @ScriptDir & "\where is wally.bmp" Global $ImageSearch = @ScriptDir & "\wanted wally.bmp" Global $x = 0 Global $y = 0 Global $w = 0 Global $h = 0 Global $ColorTrans = "0x00ffff" Global $mOnlyFirst = False ;False = search more image, but not all.., ; ;If u use "False" max area for search must be 800x600 pixels, ; ;or equivalent maximal 480.000 pixels!!! ; ;No more. ; ;Recommended is "True" Sleep(10) $time2 = TimerInit() $pozycja2 = myImageSearch_Picture($ImageBazowe, $ImageSearch, $x, $y, $w, $h, $ColorTrans, $mOnlyFirst) If @error Then ConsoleWrite("sorry image not exist" & @CRLF) ConsoleWrite("time 2: " & TimerDiff($time2) / 1000 & ' sek.' & @CRLF) If IsArray($pozycja2) Then _ArrayDisplay($pozycja2) EndIf ;##################################myImageSearch.au3 myImageSearch (Examples).au3 recycle.bmp where is wally.bmp wanted wally.bmp
    1 point
  18. After many attempts that solve it     Local $source = _IEBodyReadHTML($oIE)     If StringInStr($source, 'um_client') Then       MsgBox(0, 'Great'," Found",0,0)     EndIf ty
    0 points
×
×
  • Create New...