Popular Post toasterking Posted January 28, 2014 Popular Post Posted January 28, 2014 (edited) DllCall is a powerful way to use AutoIt code to run functions that were created in other languages and are stored in shared libraries outside of AutoIt. With DllCall, you can call Windows APIs directly, execute pieces of code that shipped with another vendor's product, and pass information between that code and your own script.However, DllCall is intended for the advanced user who is already familiar with how that stuff works. That definitely isn't me, and I find the process of converting variable types, handling ByRefs with odd syntax, and keeping track of return values in an array cumbersome. So I wrote a script to help me with it. It should help beginners get started with DllCall too. I was a little surprised that I didn't find something like this on the forum already. Maybe the intended audience doesn't have the same trouble that I do, or maybe those who don't "get" it don't care enough to. I'm hoping to bridge that gap a little.With this script, you can input the information from the MSDN documentation on a DLL function straight into the GUI and it will generate AutoIt code to call it and return its data. You can choose whether to report debugging information via ConsoleWrite or MsgBox or neither. It doesn't handle fancy things like DllStructs and callbacks, but it may help you get started.A great tutorial I used when I was starting to learn this stuff myself is Dealing with DLLs in AutoIt by Andreas Karlsson. My script is intended as a programmatic approximation of the concepts on pages 1 to 8 of that document. It is not a replacement for a good tutorial and self-learning. I wrote it as a shortcut for my own future use because I only wanted to learn it once. :-)Here it is. I'm curious to know what you all think.expandcollapse popup#include <ComboConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <ListViewConstants.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form=C:\Library\Repositories #NO BACKUP#\Google Drive - Toastyking\Development\Snippet Library\AutoIt\CodeWizards\DllCallCodegen\FormMain.kxf $FormMain = GUICreate("DllCall Code Generator", 825, 421) $Label1 = GUICtrlCreateLabel("DLL Name", 16, 32, 55, 17) $InputDll = GUICtrlCreateInput("user32.dll", 120, 29, 121, 21) $Label2 = GUICtrlCreateLabel("Function Name", 16, 59, 76, 17) $InputFunc = GUICtrlCreateInput("", 120, 56, 121, 21) $RadioFuncAnsi = GUICtrlCreateRadio("ANSI", 256, 57, 49, 17) $RadioFuncUnicode = GUICtrlCreateRadio("Unicode", 312, 56, 73, 17) GUICtrlSetState(-1, $GUI_CHECKED) $Label3 = GUICtrlCreateLabel("Return Type", 16, 85, 63, 17) $InputReturnType = GUICtrlCreateInput("int", 120, 82, 121, 21) $ComboCallConv = GUICtrlCreateCombo("", 120, 110, 121, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "stdcall|cdecl") $ListViewParams = GUICtrlCreateListView("#|Type|Value|Method", 16, 245, 362, 126, BitOR($GUI_SS_DEFAULT_LISTVIEW,$LVS_NOSORTHEADER)) GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 50) GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 50) GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 2, 50) GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 3, 50) $Label4 = GUICtrlCreateLabel("For all types, use the type name specified on MSDN.", 16, 8, 251, 17) $Label5 = GUICtrlCreateLabel("Parameters:", 16, 136, 60, 17) $Label6 = GUICtrlCreateLabel("Type", 24, 157, 28, 17) $Label7 = GUICtrlCreateLabel("Value (0 for null)", 152, 157, 80, 17) $Label8 = GUICtrlCreateLabel("Method", 280, 157, 39, 17) $InputParamType = GUICtrlCreateInput("", 24, 176, 121, 21) $InputParamValue = GUICtrlCreateInput("", 152, 176, 121, 21) $ComboParamByref = GUICtrlCreateCombo("", 280, 176, 89, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "Input/ByVal|Output/ByRef") $ButtonParamAdd = GUICtrlCreateButton("Add Parameter", 24, 213, 91, 25) $ButtonParamDelete = GUICtrlCreateButton("Clear All", 128, 213, 107, 25) $Label9 = GUICtrlCreateLabel("Calling convention", 16, 112, 91, 17) $Label10 = GUICtrlCreateLabel("Generated AutoIt code:", 409, 8, 115, 17) $EditCode = GUICtrlCreateEdit("", 408, 29, 401, 342, BitOR($ES_READONLY,$WS_HSCROLL,$WS_VSCROLL)) $ButtonTest = GUICtrlCreateButton("Test Code", 344, 381, 107, 25) $ButtonCopy = GUICtrlCreateButton("Copy to Clipboard", 464, 381, 107, 25) $ButtonInsert = GUICtrlCreateButton("Insert in SciTE", 586, 381, 107, 25) $ButtonGenonly = GUICtrlCreateButton("Nothing Else", 704, 381, 107, 25) $ComboOutput = GUICtrlCreateCombo("", 98, 383, 121, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "ConsoleWrite|MsgBox|$vDllCallReturn only") $Label11 = GUICtrlCreateLabel("Output method:", 16, 387, 77, 17) $Label12 = GUICtrlCreateLabel("Generate code and:", 232, 387, 99, 17) ;~ GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### Global $aParams[1][3] GUICtrlSetData($ComboParamByref,"Input/ByVal") GUICtrlSetData($ComboOutput,"ConsoleWrite") GUICtrlSetData($ComboCallConv,"stdcall") GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $ButtonParamAdd _ConvertType(GUICtrlRead($InputParamType)) ; Use the parameter type selected If @error Then If MsgBox(49,"Unrecognized Type","Unrecognized parameter type """ & GUICtrlRead($InputParamType) & """. Make sure you are using an MSDN return type." & @CRLF & @CRLF & "If you are certain that the parameter type is correct and you happen to know the equivalent AutoIt parameter type, click OK. You will be prompted later for the AutoIt parameter type.",0,$FormMain) = 2 Then ContinueLoop EndIf If GUICtrlRead($ComboParamByref) = "Output/ByRef" And StringLeft(GUICtrlRead($InputParamValue),1) <> "$" Then MsgBox(48,"Error","To use this parameter value as a ByRef, you must specify the name of a variable used in your AutoIt script, which must begin with a '$' symbol.",0,$FormMain) ContinueLoop EndIf ; Input seems okay; proceed. ReDim $aParams[UBound($aParams) + 1][3] ; Add a "row" to the array $aParams[UBound($aParams) - 1][0] = GUICtrlRead($InputParamType) $aParams[UBound($aParams) - 1][1] = GUICtrlRead($InputParamValue) $aParams[UBound($aParams) - 1][2] = GUICtrlRead($ComboParamByref) ; Clear input fields and refocus GUICtrlSetData($InputParamType,"") GUICtrlSetData($InputParamValue,"") GUICtrlSetData($ComboParamByref,"Input/ByVal") GUICtrlCreateListViewItem(UBound($aParams) - 1 & "|" & $aParams[UBound($aParams) - 1][0] & "|" & $aParams[UBound($aParams) - 1][1] & "|" & $aParams[UBound($aParams) - 1][2],$ListViewParams) ControlFocus($FormMain,"",$InputParamType) Case $ButtonParamDelete ; Delete all items _GUICtrlListView_DeleteAllItems($ListViewParams) ReDim $aParams[1][3] Case $ButtonTest $sDllCallOut = _GenerateCode("MsgBox") ; Always use MsgBox for output when generating for testing. GUICtrlSetData($EditCode,$sDllCallOut) If $sDllCallOut <> "" Then GUISetState(@SW_DISABLE,$FormMain) GUICtrlSetData($ButtonTest,"Executing...") FileDelete(@TempDir & "\DllCallExec.au3") FileWrite(@TempDir & "\DllCallExec.au3",$sDllCallOut); Write code to temporary file to be executed. $nExit = RunWait(@AutoItExe & ' /AutoIt3ExecuteScript "' & @TempDir & '\DllCallExec.au3"',@TempDir) ; Execute the temporary file. If $nExit <> 0 Then Switch $nExit Case 1 MsgBox(16,"DLL Code Generator","The AutoIt interpreter encountered an error while parsing or executing the generated code." & @CRLF & "Exit code: " & $nExit,0,$FormMain) Case Else MsgBox(16,"DLL Code Generator","There was a problem with the DllCall (possibly incorrect parameters). The AutoIt interpreter ended unexpectedly." & @CRLF & "Exit code: " & $nExit,0,$FormMain) EndSwitch EndIf GUICtrlSetData($ButtonTest,"Test Code") GUISetState(@SW_ENABLE,$FormMain) FileDelete(@TempDir & "\DllCallExec.au3") WinActivate($FormMain) EndIf Case $ButtonGenonly $sDllCallOut = _GenerateCode(GUICtrlRead($ComboOutput)) GUICtrlSetData($EditCode,$sDllCallOut) Case $ButtonCopy $sDllCallOut = _GenerateCode(GUICtrlRead($ComboOutput)) GUICtrlSetData($EditCode,$sDllCallOut) If ClipPut($sDllCallOut) Then ToolTip("Copied!") Else ToolTip("Copy failed!") EndIf Sleep(1000) ToolTip("") Case $ButtonInsert $sDllCallOut = _GenerateCode(GUICtrlRead($ComboOutput)) GUICtrlSetData($EditCode,$sDllCallOut) If ClipPut($sDllCallOut) Then ControlSend("[CLASS:SciTEWindow]","","Scintilla1","^v") Case $InputFunc If StringRight(GUICtrlRead($InputFunc),1) == "W" Then ; Check if last character of entered function name is a capital "W" GUICtrlSetState($RadioFuncUnicode,$GUI_CHECKED) Else GUICtrlSetState($RadioFuncAnsi,$GUI_CHECKED) EndIf Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func _GenerateCode($sOutputType = "") Local $sArch, $sReturnTypeOut, $sParamTypeOut, $sDllFuncName, $sDllCallOut, $sCmdOutStart, $sCmdOutEnd, $fOutputGen Switch $sOutputType Case "ConsoleWrite" $sCmdOutStart = 'ConsoleWrite(' $sCmdOutEnd = ' & @CRLF)' $fOutputGen = 1 Case "MsgBox" $sCmdOutStart = 'MsgBox(0,"DllCall Code Generator",' $sCmdOutEnd = ')' $fOutputGen = 1 Case Else $sCmdOutStart = "" $sCmdOutEnd = "" $fOutputGen = 0 EndSwitch If GUICtrlRead($RadioFuncAnsi) = $GUI_CHECKED Then $sArch = "a" If GUICtrlRead($RadioFuncUnicode) = $GUI_CHECKED Then $sArch = "w" $sDllFuncName = GUICtrlRead($InputDll) & "/" & GUICtrlRead($InputFunc) $sReturnTypeOut = _ConvertType(GUICtrlRead($InputReturnType)) If @error Then $sReturnTypeOut = InputBox("Unrecognized Type","Unrecognized return type """ & GUICtrlRead($InputReturnType) & """. Make sure you are using an MSDN return type." & @CRLF & @CRLF & "If you are certain that the return type is correct and you happen to know the equivalent AutoIt return type, you may enter the AutoIt return type here.","","",Default,220,Default,Default,0,$FormMain) If $sReturnTypeOut = "" Then Return SetError(1,0,"") EndIf $sReturnTypeOut = _ConvertTypeArch($sReturnTypeOut,$sArch) If GUICtrlRead($ComboCallConv) <> "stdcall" Then $sReturnTypeOut &= ':' & GUICtrlRead($ComboCallConv) $sDllCallOut = 'Local $aDllCallReturn,$vDllCallReturn' $sDllCallOut = '$aDllCallReturn = DllCall("' & GUICtrlRead($InputDll) & '","' & $sReturnTypeOut & '","' & GUICtrlRead($InputFunc) & '"' If UBound($aParams) > 1 Then For $x = 1 To UBound($aParams) - 1 $sParamTypeOut = '' $sParamTypeOut = _ConvertTypeArch(_ConvertType($aParams[$x][0]),$sArch) If $sParamTypeOut = '' Then $sParamTypeOut = InputBox("Unrecognized Type","Unrecognized parameter type """ & $aParams[$x][0] & """. Make sure you are using an MSDN parameter type." & @CRLF & @CRLF & "If you are certain that the parameter type is correct and you happen to know the equivalent AutoIt parameter type, you may enter the AutoIt parameter type here.","","",Default,220,Default,Default,0,$FormMain) If $sParamTypeOut = "" Then Return(SetError(1,0,"")) If StringRight($sParamTypeOut,1) = "*" Then $sParamTypeOut = StringTrimRight($sParamTypeOut,1) ; If the user added an asterisk to the end of the parameter type, remove it; it will be added back later if necessary. EndIf $sDllCallOut &= ',"' & $sParamTypeOut If $aParams[$x][2] = "Output/ByRef" Then $sDllCallOut &= '*' $sDllCallOut &= '","' & $aParams[$x][1] & '"' Next EndIf $sDllCallOut &= ')' & @CRLF ; Generate code to check for DllCall execution error. If $fOutputGen = 1 Then $sDllCallOut &= _ 'If @error Then' & @CRLF & _ ' Switch @error' & @CRLF & _ ' Case 1' & @CRLF & _ ' ' & $sCmdOutStart & '"DllCall error (' & $sDllFuncName & '): Unable to use the DLL file. Possibly a problem with the parameters."' & $sCmdOutEnd & @CRLF & _ ' Case 2' & @CRLF & _ ' ' & $sCmdOutStart & '"DllCall error (' & $sDllFuncName & '): Unknown return type."' & $sCmdOutEnd & @CRLF & _ ' Case 3' & @CRLF & _ ' ' & $sCmdOutStart & '"DllCall error (' & $sDllFuncName & '): Function not found in DLL file. Remember that function names are case sensitive."' & $sCmdOutEnd & @CRLF & _ ' Case 4' & @CRLF & _ ' ' & $sCmdOutStart & '"DllCall error (' & $sDllFuncName & '): Incorrect number of parameters."' & $sCmdOutEnd & @CRLF & _ ' Case 5' & @CRLF & _ ' ' & $sCmdOutStart & '"DllCall error (' & $sDllFuncName & '): Bad parameter."' & $sCmdOutEnd & @CRLF & _ ' Case Else' & @CRLF & _ ' ' & $sCmdOutStart & '"DllCall error (' & $sDllFuncName & '): Unknown/unspecified error."' & $sCmdOutEnd & @CRLF & _ ' EndSwitch' & @CRLF & _ ' $vDllCallReturn = ""' & @CRLF & _ 'Else' & @CRLF If $fOutputGen = 1 Then $sDllCallOut &= ' ' $sDllCallOut &= '$vDllCallReturn = $aDllCallReturn[0]' & @CRLF ; Generate code to assign returned ByRef values back to their AutoIt variables. If UBound($aParams) > 1 Then For $x = 1 To UBound($aParams) - 1 If $aParams[$x][2] = "Output/ByRef" Then If $fOutputGen = 1 Then $sDllCallOut &= ' ' $sDllCallOut &= $aParams[$x][1] & ' = $aDllCallReturn[' & $x & ']' & @CRLF EndIf Next EndIf ; Generate code to output values of the variables passed to the DllCall via ByRef. If $fOutputGen = 1 Then $sDllCallOut &= ' ' & $sCmdOutStart If UBound($aParams) > 1 Then For $x = 1 To UBound($aParams) - 1 If $aParams[$x][2] = "Output/ByRef" Then $sDllCallOut &= '"' & $aParams[$x][1] & ' = " & ' & $aParams[$x][1] & ' & @CRLF & ' EndIf Next EndIf $sDllCallOut &= '"DllCall return value: " & $vDllCallReturn' & $sCmdOutEnd & @CRLF $sDllCallOut &= "EndIf" & @CRLF EndIf Return $sDllCallOut EndFunc ; Convert the MSDN variable type to AutoIt variable type Func _ConvertType($MSDN_Type) Switch $MSDN_Type Case 'ATOM' Return 'WORD' Case 'BOOL' Return 'BOOL' Case 'BOOLEAN' Return 'BOOLEAN' Case 'BYTE' Return 'BYTE' Case 'CHAR' Return 'str' Case 'COLORREF' Return 'DWORD' Case 'CONST' Return 'const' Case 'DWORD' Return 'DWORD' Case 'DWORDLONG' Return 'ULONG' Case 'DWORD_PTR' Return 'DWORD_PTR' Case 'DWORD32' Return 'UINT' Case 'DWORD64' Return 'INT64' Case 'FLOAT' Return 'FLOAT' Case 'HACCEL' Return 'HANDLE' Case 'HALF_PTR' Return 'ptr' Case 'HANDLE' Return 'HANDLE' Case 'HBITMAP' Return 'HANDLE' Case 'HBRUSH' Return 'HANDLE' Case 'HCONV' Return 'HANDLE' Case 'HCONVLIST' Return 'HANDLE' Case 'HCURSOR' Return 'HICON' Case 'HDC' Return 'HANDLE' Case 'HDDEDATA' Return 'HANDLE' Case 'HDESK' Return 'HANDLE' Case 'HDROP' Return 'HANDLE' Case 'HDWP' Return 'HANDLE' Case 'HENHMETAFILE' Return 'HANDLE' Case 'HFILE' Return 'int' Case 'HFONT' Return 'HANDLE' Case 'HGIDOBJ' Return 'HANDLE' Case 'HGLOBAL' Return 'HANDLE' Case 'HHOOK' Return 'HANDLE' Case 'HICON' Return 'HANDLE' Case 'HINSTANCE' Return 'HANDLE' Case 'HKEY' Return 'HANDLE' Case 'HKL' Return 'HANDLE' Case 'HLOCAL' Return 'HANDLE' Case 'HMENU' Return 'HANDLE' Case 'HMETAFILE' Return 'HANDLE' Case 'HMODULE' Return 'HANDLE' Case 'HMONITOR' Return 'HANDLE' Case 'HPALETTE' Return 'HANDLE' Case 'HPEN' Return 'HANDLE' Case 'HRESULT' Return 'LONG' Case 'HRGN' Return 'HANDLE' Case 'HRSRC' Return 'HANDLE' Case 'HSZ' Return 'HANDLE' Case 'HWINSTA' Return 'HANDLE' Case 'HWND' Return 'HWND' Case 'INT_PTR' Return 'INT_PTR' Case 'INT32' Return 'int' Case 'INT' Return 'int' Case 'INT64' Return 'INT64' Case 'LANGID' Return 'WORD' Case 'LARGE_INTEGER' Return 'INT64' Case 'LCID' Return 'DWORD' Case 'LGRPID' Return 'DWORD' Case 'LONG' Return 'LONG' Case 'LONGLONG' Return 'INT64' Case 'LONG_PTR' Return 'LONG_PTR' Case 'LONG32' Return 'int' Case 'LONG64' Return 'INT64' Case 'LPARAM' Return 'LPARAM' Case 'LPBOOL' Return 'int' Case 'LPBYTE' Return 'int' Case 'LPCOLORREF' Return 'DWORD' Case 'LPCSTR' Return 'str' Case 'LPCTSTR' Return 'str' Case 'LPCWSTR' Return 'wstr' Case 'LPDWORD' Return 'DWORD' Case 'LPHANDLE' Return 'HANDLE' Case 'LPINT' Return 'int' Case 'LPLONG' Return 'long' Case 'LPSTR' Return 'str' Case 'LPTSTR' Return 'str' Case 'LPVOID' Return 'ptr' Case 'LPWORD' Return 'WORD' Case 'LPWSTR' Return 'wstr' Case 'LRESULT' Return 'LRESULT' Case 'PBOOL' Return 'BOOL' Case 'PBOOLEAN' Return 'BOOLEAN' Case 'PBYTE' Return 'BYTE' Case 'PCHAR' Return 'str' Case 'PCSTR' Return 'str' Case 'PCTSTR' Return 'str' Case 'PCWSTR' Return 'wstr' Case 'PDWORD' Return 'DWORD' Case 'PDWORDLONG' Return 'UINT64' Case 'PDWORD_PTR' Return 'DWORD_PTR' Case 'PDWORD32' Return 'UINT' Case 'PDWORD64' Return 'INT64' Case 'PFLOAT' Return 'FLOAT' Case 'PHALF_PTR' Return 'ptr' Case 'PHANDLE' Return 'HANDLE' Case 'PHKEY' Return 'HANDLE' Case 'PINT' Return 'int' Case 'PINT_PTR' Return 'INT_PTR' Case 'PINT32' Return 'int' Case 'PINT64' Return 'INT64' Case 'PLCID' Return 'DWORD' Case 'PLONG' Return 'LONG' Case 'PLONGLONG' Return 'INT64' Case 'PLONG_PTR' Return 'LONG_PTR' Case 'PLONG32' Return 'long' Case 'PLONG64' Return 'INT64' Case 'POINTER_32' Return 'ptr' Case 'POINTER_64' Return 'ptr' Case 'POINTER_SIGNED' Return 'ptr' Case 'POINTER_UNSIGNED' Return 'ULONG_PTR' Case 'PSHORT' Return 'SHORT' Case 'PSIZE_T' Return 'ULONG_PTR' Case 'PSSIZE_T' Return 'LONG_PTR' Case 'PSTR' Return 'str' Case 'PTBYTE' Return 'BYTE' Case 'PTCHAR' Return 'wstr' Case 'PTSTR' Return 'wstr' Case 'PUCHAR' Return 'BYTE' Case 'PUHALF_PTR' Return 'ptr' Case 'PUINT' Return 'UINT' Case 'PUINT_PTR' Return 'UINT_PTR' Case 'PUINT32' Return 'UINT' Case 'PUINT64' Return 'UINT64' Case 'PULARGE_INTEGER' Return 'UINT64' Case 'PULONG' Return 'ULONG' Case 'PULONGLONG' Return 'UINT64' Case 'PULONG_PTR' Return 'ULONG_PTR' Case 'PULONG32' Return 'ULONG' Case 'PULONG64' Return 'UINT64' Case 'PUSHORT' Return 'USHORT' Case 'PVOID' Return 'ptr' Case 'PWCHAR' Return 'wstr' Case 'PWORD' Return 'WORD' Case 'PWSTR' Return 'wstr' Case 'SC_HANDLE' Return 'HANDLE' Case 'SC_LOCK' Return 'ptr' Case 'SERVICE_STATUS_HANDLE' Return 'HANDLE' Case 'SHORT' Return 'SHORT' Case 'SIZE_T' Return 'ULONG_PTR' Case 'SSIZE_T' Return 'LONG_PTR' Case 'TBYTE' Return 'wstr' Case 'TCHAR' Return 'wstr' Case 'UCHAR' Return 'BYTE' Case 'UHALF_PTR' Return 'ptr' Case 'UINT' Return 'UINT' Case 'UINT_PTR' Return 'UINT_PTR' Case 'UINT32' Return 'UINT' Case 'UINT64' Return 'UINT64' Case 'ULARGE_INTEGER' Return 'UINT64' Case 'ULONG' Return 'ULONG' Case 'ULONGLONG' Return 'UINT64' Case 'ULONG_PTR' Return 'ULONG_PTR' Case 'ULONG32' Return 'ULONG' Case 'ULONG64' Return 'UINT64' Case 'UNICODE_STRING' Return 'ptr' Case 'USHORT' Return 'USHORT' Case 'USN' Return 'INT64' Case 'VOID' Return 'none' Case 'WCHAR' Return 'wstr' Case 'WORD' Return 'WORD' Case 'WPARAM' Return 'WPARAM' Case Else SetError(1) Return "" EndSwitch EndFunc ;==> ; Some variable types should be converted from their ANSI to Unicode types or vice versa. Func _ConvertTypeArch($MSDN_Type,$sArch) Switch $MSDN_Type Case 'STR' If $sArch = "a" Then Return "str" If $sArch = "w" Then Return "wstr" Case 'WSTR' If $sArch = "a" Then Return "str" If $sArch = "w" Then Return "wstr" Case Else Return $MSDN_Type EndSwitch EndFuncHere is an example:Function: GetDiskFreeSpaceW (MSDN page: http://msdn.microsoft.com/en-us/library/aa364935(VS.85).aspx)Input this:Click Test Code, and get this:Click Insert in SciTE to insert the code into your script.Updated 2014/01/28: Add: MSDN Types: LARGE_INTEGER ULARGE_INTEGER PULARGE_INTEGERAdd: Prompt for correct AutoIt return type if MSDN type is unknown.Add: Warn when adding parameter with unknwon MSDN type.Add: Prompt for correct AutoIt parameter type if MSDN type is unknown.Add: Automatically select ANSI or Unicode depending on if the function name ends in "W".Chg: Does not generate code twice when "Test Code" is clicked; always generates once with MsgBox as output.Fix: Problems returning $vDllCallReturn in some cases.Fix: MessageBoxW should not be prepopulated as function name.Fix: If _GenerateCode() failed, returned 0. Should return "" and @error=1. Edit 2015/11/25: Fixed broken link Edited November 25, 2015 by toasterking Fixed broken link mLipok, Skysnake, jaberwacky and 3 others 6
funkey Posted January 28, 2014 Posted January 28, 2014 Thanks. Works fine for easy DLL calls and is good for beginners. If there are more difficult DLL functions with pointer to structs then it will not work anymore, but it's a good start. Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning.
JohnOne Posted January 28, 2014 Posted January 28, 2014 (edited) Can't argue with that, I'm sure this will be very useful to a lot of people. Since your screenshot and link refer to "GetDiskFreeSpace", you probably should start with that in the appropriate input field rather than MessagBox. Good work. EDIT: After trying your linked example "GetDiskFreeSpace" I turned my attentions to "GetDiskFreeSpaceEx" and seen that the PULARGE_INTEGER type is not supported in your early script, I believe it is "uint64*" in AutoIt. I'm sure there will be more to add if you continue to support the tool. Edited January 28, 2014 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans.
nend Posted January 28, 2014 Posted January 28, 2014 Thanks, I think it's very handy for me. toasterking 1
toasterking Posted January 28, 2014 Author Posted January 28, 2014 (edited) J1, Thanks for your compliments! Since your screenshot and link refer to "GetDiskFreeSpace", you probably should start with that in the appropriate input field rather than MessagBox. I agree. I didn't actually mean to leave MessageBoxW as the default field value there. I was using that for testing and forgot to remove it. Fixed. After trying your linked example "GetDiskFreeSpace" I turned my attentions to "GetDiskFreeSpaceEx" and seen that the PULARGE_INTEGER type is not supported in your early script, I believe it is "uint64*" in AutoIt. You are correct. I somehow missed PULARGE_INTEGER, ULARGE_INTEGER, and LARGE_INTEGER in the conversion function. I added them. If you enter an unknown MSDN type now, it prompts for the correct AutoIt type in case you are smarter than it is. Edit: GetDiskFreeSpaceEx works for me now. Edited January 28, 2014 by toasterking
toasterking Posted January 28, 2014 Author Posted January 28, 2014 Thanks. Works fine for easy DLL calls and is good for beginners. If there are more difficult DLL functions with pointer to structs then it will not work anymore, but it's a good start. Thanks! It is not complete and it may never be. But I wanted to put it out there in the hopes that it can benefit someone as-is. Skysnake 1
Skysnake Posted November 11, 2015 Posted November 11, 2015 (edited) Very nice! Exactly the kind of tool that will come in very handy This link is broken:A great tutorial I used when I was starting to learn this stuff myself is Dealing with DLLs in AutoIt by Andreas Karlsson. Edited November 11, 2015 by Skysnake Skysnake Why is the snake in the sky?
reb Posted November 11, 2015 Posted November 11, 2015 Try this link https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCEQFjAAahUKEwiK9MLh3ojJAhWETCYKHXKKBWw&url=https%3A%2F%2Fwww.autoitscript.com%2Fforum%2Fapplications%2Fcore%2Finterface%2Ffile%2Fattachment.php%3Fid%3D25713&usg=AFQjCNGA4R2RA95c2T1n89qSdpdyNNcfHA&cad=rja MEASURE TWICE - CUT ONCE
toasterking Posted November 25, 2015 Author Posted November 25, 2015 This link is broken:Thanks. I updated the link in the original post with the one Reb provided.
Skysnake Posted November 26, 2015 Posted November 26, 2015 Thx. I posted something about DllCall in the C# section. Care to take a look. It is too complex for me and I cant find the corresponding values in the lookup. I cant do it Skysnake Why is the snake in the sky?
kaesereibe Posted November 27, 2015 Posted November 27, 2015 Looks good for DllCall beginners =)But instand of 1000 cases in _ConvertType, why you dont work with arrays? BIN 2 DEC | ConvertTemp | DEC 2 BIN | GetWeekday | HEX 2 RGB | INT 2 HEX | QueryPerformance
toasterking Posted December 2, 2015 Author Posted December 2, 2015 Looks good for DllCall beginners =)Thanks!But instand of 1000 cases in _ConvertType, why you dont work with arrays?Mostly for speed. It's habit; I make optimizations when I see them. Try this example code. The same lookup operation takes 3 times as long with an array as with a Switch statement.My times:Lookup1 time: 5993.06858483286 msLookup2 time: 15289.7226984924 msexpandcollapse popupGlobal $aLookup[15][2] = [[1,"one"], _ [2,"two"], _ [3,"three"], _ [4,"four"], _ [5,"five"], _ [6,"six"], _ [7,"seven"], _ [8,"eight"], _ [9,"nine"], _ [10,"ten"], _ [11,"eleven"], _ [12,"twelve"], _ [13,"thirteen"], _ [14,"fourteen"], _ [15,"fifteen"]] Local $tTest = TimerInit() For $i = 1 To 1000000 _Lookup1("fifteen") Next ConsoleWrite("Lookup1 time: " & TimerDiff($tTest) & " ms" & @CRLF) $tTest = TimerInit() For $i = 1 To 1000000 _Lookup2("fifteen") Next ConsoleWrite("Lookup2 time: " & TimerDiff($tTest) & " ms" & @CRLF) Func _Lookup1($sName) Switch $sName Case "one" Return 1 Case "two" Return 2 Case "three" Return 3 Case "four" Return 4 Case "five" Return 5 Case "six" Return 6 Case "seven" Return 7 Case "eight" Return 8 Case "nine" Return 9 Case "ten" Return 10 Case "eleven" Return 11 Case "twelve" Return 12 Case "thirteen" Return 13 Case "fourteen" Return 14 Case "fifteen" Return 15 Case Else Return 0 EndSwitch EndFunc Func _Lookup2($sName) For $i = 1 To UBound($aLookup) - 1 If $sName = $aLookup[$i][1] Then Return $aLookup[$i][0] Next Return 0 EndFuncIf you prefer arrays for readability, you're welcome to rewrite it.
toasterking Posted December 2, 2015 Author Posted December 2, 2015 I posted something about DllCall in the C# section. Care to take a look. It is too complex for me and I cant find the corresponding values in the lookup. I cant do it Honestly, I probably don't know any more than you. I stopped when I reached the limit of what this code generator can do because that was all I've needed so far. If the code generator can't solve it and it's not covered on pages 1 to 8 of the linked PDF, I probably can't do it either. Good luck, though! GuyFromNJo 1
Skysnake Posted December 2, 2015 Posted December 2, 2015 Thank you for the reply. Skysnake Why is the snake in the sky?
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now