tarretarretarre

Advanced DllCall and DllStruct AutoIt Code Generator BETA v0.6

37 posts in this topic

#1 ·  Posted (edited)

Hello fellas!

The other night night i was converting a Msdn function to autoit and I stumbled across this topic

 Which inspired me like crazy and I decided to take it a step further and require the user to make almost ZERO effort to export a c++ Msdn function and or a Structure to AutoIt

Shoutout to toasterking

 

So after 18-20 effective hours: 

The GUI is really simple, all you need is a link to a MSDN page and the program does the rest, most of the options is just for user preferences.

On the inside I have spent a decent amount of work to make sure the code come out correctly, any particular event during the conversion will get fed-back to the user, so he or she will know if anything noticeable happen.

 

Regular DllCall example

http://i.imgur.com/HZLijeu.png

Struct example

http://i.imgur.com/l3j6wTR.png
 

Expand spoiler for more pictures

Spoiler

Dllopen + Array return example

http://i.imgur.com/YHVZ5n2.png

Passing dll as array

http://i.imgur.com/Fs587Cd.png

 

In the "Msdn Examples" folder you will find some examples of code i have generated, in most of them I only manually added 2-3 lines to make them work. 

If you dont know where to get these functions you can browse the MSDN Library https://msdn.microsoft.com/en-us/library/ee663300(v=vs.85).aspx and look for any function refrence, or just google "somethingsomething msdn" and the first result will almost always contain the function you are looking for.

Here is some functions you can play around with

https://msdn.microsoft.com/en-us/library/windows/desktop/ms724390(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/windows/desktop/ms633519(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/windows/desktop/ms645505(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/windows/desktop/ms724408(v=vs.85).aspx

 

I would really appreciate any kind of feedback, improvements or requests :D

If you get any type of error just post the MSDN url + the error message and ID and I will troubleshoot it.

 

Update 0.2

  • Fixed some minor issues
  • Added highlight for a more pleasent view 
  • Fixed minor bugs
  • Made it run faster when working with the same URL (It dosent load the page entierly)
  • No struct search is now done when no POINTER is used in the call
  • Added more options for the user

Update 0.3

  • Removed _IeNavigate and fixed the template for DllCall not including function name

Update 0.4

  • Switched method to InetGet from _Ie*
  • H0tfix3s

Update 0.5

  • Added more options for function-layout
  • Removed old code
  • Added more auto detection
  • Now using @TmpDir instead of @ScriptDir for html files etc.

Update 0.6

  • More Output logic added
  • Added a detection for SAL aswell, since it seems to be inconsistent according to MSDN community and myself.
  • Better feedback on what happend with parse
  • Code cleanup / Removed old code

/Tarre

DllCall and Struct Generator V 0.6.zip

DllCall and Struct Generator V 0.5.zip

DllCall and Struct Generator V 0.4.zip

Edited by tarretarretarre
Update
4 people like this

Share this post


Link to post
Share on other sites



Result = Problem while creating the oIE object, check internet connection

But i have a proper connection. And IE is in my pc.


My Contributions

UDF Link Viewer   --- A tool to visit the links of some most important UDFs 

 Includer_2  ----- A tool to type the #include statement automatically 

 Digits To Date  ----- date from 3 integer values

PrintList ----- prints arrays into console for testing.

 Alert  ------ An alternative for MsgBox 

 MousePosition ------- A simple tooltip display of mouse position

GRM Helper -------- A littile tool to help writing code with GUIRegisterMsg function

Access_UDF  -------- An UDF for working with access database files. (.*accdb only)

 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

5 hours ago, JohnOne said:

I admire your patience, I've threatened to do this in the past, but dont have of it.

I'll certainly provide some feedback of testion when I get the time.

Thanks for share.

Thank you, I look forward to see what you think :D

2 hours ago, kcvinu said:

Result = Problem while creating the oIE object, check internet connection

But i have a proper connection. And IE is in my pc.

Oh, i cannot update the script right now, because im not home but for fast fix, you can go into parser.au3 @ line 31 you will find this

; timeout
    _IELoadWait($oIE, 1, 10000)

 

Edited by tarretarretarre
TypOSSss
1 person likes this

Share this post


Link to post
Share on other sites

30+ downloads and no comments?

I have updated the script
 

Update 0.2

  • Fixed some minor issues
  • Added highlight for a more pleasent view (Check OT)
  • Fixed minor bugs
  • Made it run faster when working with the same URL (It dosent load the page entierly)
  • No struct search is now done when no POINTER is used in the call
  • Added more options for the user

 

/Tarre

Share this post


Link to post
Share on other sites
4 minutes ago, JohnOne said:

I have a question.

I notice the pakaged autoitobject dll files were modified less than a week ago, who modified them?

Hmm less than a week ago, that might be GIT removing CRLF when i commit, I dont use the official AO release either, the one in here is from here:

 

Share this post


Link to post
Share on other sites
9 minutes ago, JohnOne said:

"Problem while creating the oIE object, check internet connection"

Win 10 x64, this machine.

thats weird, its  only a Timeout for _ieNavigate

 

Try change line 29 @ parser.au3 to $oIE = _IECreate($sUrl, 0, $___DeveloperMode, 1)

And remove _IELoadWait($oIE, 1, 40000) @ parser.au3

I'm not close to a Win10 machine, so i cannot test this now im afraid.

 

/Tarre

Share this post


Link to post
Share on other sites

"Unable to read <pre>*</pre> from $sHTML"

--> IE.au3 T3.0-2 Warning from function internal function __IEIsObjType, Cannot register internal error handler, cannot trap COM errors (Use _IEErrorHandlerRegister() to register a user error handler)
--> IE.au3 T3.0-2 Warning from function internal function __IEIsObjType, Cannot register internal error handler, cannot trap COM errors (Use _IEErrorHandlerRegister() to register a user error handler)
--> IE.au3 T3.0-2 Warning from function _IELoadWait, Cannot register internal error handler, cannot trap COM errors (Use _IEErrorHandlerRegister() to register a user error handler)
--> IE.au3 T3.0-2 Warning from function internal function __IEIsObjType, Cannot register internal error handler, cannot trap COM errors (Use _IEErrorHandlerRegister() to register a user error handler)
--> IE.au3 T3.0-2 Warning from function _IEGetObjById, $_IESTATUS_NoMatch (code)
! COM Error ! Number: 0x0, ScriptLine: 102, Reason: Variable must be of type 'Object'.
! COM Error ! Number: 0x0, ScriptLine: 125, Reason: Variable must be of type 'Object'.


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites
5 minutes ago, JohnOne said:

Okay i have the same IE version,

If you run this in a new script

#include <string.au3>
#include <array.au3>
#include <ie.au3>

Local $oIE = _IECreate("https://msdn.microsoft.com/en-us/library/windows/desktop/ms633515%28v=vs.85%29.aspx")
Local $sHTML = _IEBodyReadHTML($oIE)
Local $Try = _StringBetween($sHTML, "<pre>", "</pre>")

_ArrayDisplay($try)

_IEQuit($oIE)

Could you print the array?

And thank you for the input, it really helps!

Share this post


Link to post
Share on other sites
3 minutes ago, JohnOne said:

Actually I get the array intermittently.

about 50/50

Alright, it seems like autoit tries to read the data while the page is not fully loaded.


Could you try this script and see if you get a consistant array

 

#include <string.au3>
#include <array.au3>
#include <ie.au3>

Local $oIE = _IECreate("https://msdn.microsoft.com/en-us/library/windows/desktop/ms633515%28v=vs.85%29.aspx")
Local $sHTML = _IEBodyReadHTML($oIE)
Local $try

Local $timerinit = TimerInit()

Do
    ;Exit loop after 10 sec of failure
    if TimerDiff($timerinit) > 10000 Then ExitLoop
    $try = _StringBetween($sHTML, "<pre>", "</pre>")
    Sleep(100)
Until IsArray($try)

_ArrayDisplay($try)


_IEQuit($oIE)

 

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

why not use InetGet ?

#include <string.au3>
#include <array.au3>

#include <InetConstants.au3>
#include <MsgBoxConstants.au3>
#include <WinAPIFiles.au3>

;~ Local $oIE = _IECreate("https://msdn.microsoft.com/en-us/library/windows/desktop/ms633515%28v=vs.85%29.aspx")
;~ Local $sHTML = _IEBodyReadHTML($oIE)
Local $sHTML = Example( "https://msdn.microsoft.com/en-us/library/windows/desktop/ms633515%28v=vs.85%29.aspx" )
ConsoleWrite($sHTML&@CRLF)
Local $try
Local $timerinit = TimerInit()
Do
    ;Exit loop after 10 sec of failure
    if TimerDiff($timerinit) > 10000 Then ExitLoop
    $try = _StringBetween($sHTML, "<pre>", "</pre>")
    Sleep(100)
Until IsArray($try)
_ArrayDisplay($try)

Func Example($sIn)
    ; Save the downloaded file to the temporary folder.
    Local $sFilePath = _WinAPI_GetTempFileName(@TempDir)
    ; Download the file in the background with the selected option of 'force a reload from the remote site.'
    Local $hDownload = InetGet($sIn, $sFilePath, $INET_FORCERELOAD, $INET_DOWNLOADBACKGROUND)
    ; Wait for the download to complete by monitoring when the 2nd index value of InetGetInfo returns True.
    Do
        Sleep(250)
    Until InetGetInfo($hDownload, $INET_DOWNLOADCOMPLETE)
    ; Retrieve the number of total bytes received and the filesize.
    Local $iBytesSize = InetGetInfo($hDownload, $INET_DOWNLOADREAD)
    Local $iFileSize = FileGetSize($sFilePath)
    ; Close the handle returned by InetGet.
    InetClose($hDownload)
    Local $sTxt = FileRead($sFilePath)
;~     ; Display details about the total number of bytes read and the filesize.
;~     MsgBox($MB_SYSTEMMODAL, "", "The total download size: " & $iBytesSize & @CRLF & _
;~             "The total filesize: " & $iFileSize)
    ; Delete the file.
    FileDelete($sFilePath)
    Return $sTxt
EndFunc   ;==>Example

 

Edited by argumentum
show some code
1 person likes this

Share this post


Link to post
Share on other sites
1 minute ago, argumentum said:

why not use InetGet ?

Yeah I could, but _Ie Library should work on Win10, but if its not consistant at all, i will re-write all the _Ie elements with InetGet, but so far ive only tested on IE 9 and IE 11 on Win 7 64 bit

1 person likes this

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • luckyluke
      By luckyluke
      Hello,
      Im trying to read the output from CMD using Dllcall, here is my code:
      #include <WinAPI.au3> #include <array.au3> Global Const $STD_OUTPUT_HANDLE = -11 Global Const $_CONSOLE_SCREEN_BUFFER_INFO = _ "struct;int dwSizeX;" & _ "short dwSizeY;" & _ "short dwCursorPositionX;" & _ "short dwCursorPositionY;" & _ "short wAttributes;" & _ "short Left;" & _ "short Top;" & _ "short Right;" & _ "short Bottom;" & _ "short dwMaximumWindowSizeX;" & _ "short dwMaximumWindowSizeY;endstruct" $pCmd = Run( "cmd.exe" ) Sleep(1000) $hCmd = WinGetHandle("") ConsoleWrite('handle:' & $hCmd & @CRLF) $aRet = DllCall("kernel32.dll", "int", "AttachConsole", "dword", $pCmd) ;_ArrayDisplay($aRet) If $aRet[0] <> 0 Then $vHandle_data='' $vHandle='' $vHandle_data = DllStructCreate($_CONSOLE_SCREEN_BUFFER_INFO) ; Screen Buffer structure $aRet1 = DllCall("kernel32.dll", "hwnd", "GetStdHandle", "dword", $STD_OUTPUT_HANDLE) if not @error Then $vHandle = $aRet1[0] $aRet = DllCall("kernel32.dll", "int", "GetConsoleScreenBufferInfo", "hwnd", $vHandle, _ "ptr", $vHandle_data) MsgBox(0, '1',DllStructGetData($vHandle_data, 'dwSizeX') & _WinAPI_GetLastErrorMessage()) EndIf It did not work, i got the message 'The handle is invalid'. Please help?
      Thank you in advance!
    • MazeM
      By MazeM
      Hi
      here's another UDF for the serial port. It is very similar to CommAPI using kernel32.dll, but all code is packed into a single file without any dependencies, not even using WinAPI.au3. It differs from existing UDF that it doesn't allow a timeout when reading, instead it always returns immediately, either with the requested amount ob bytes read or with a failure status. And of course there is a function provided to query the amount of available bytes in the receive buffer. The reason behind this design decision: You can do 1000 other things in the main loop while checking from time to time if enough data bytes arrived. There's no point to block the program waiting for the serial port.
      It is currently a work-in-progress, as I didn't test all functions yet. The code was developed and tested on Windows 7 64 bit.  The ComUDF-Tests.au3 shows some tests and basic usage of the UDF. Maybe there's no reason to use this UDF, given the existence of the others UDFs, but I did it to get to know DllCall better - I use structs no only to pass but also to get data back (I don't use the array returned by DllCall to read that data, unless required). You're welcome to test it on older and newer Windows versions.
      Here's a list of the implemented functions:
      ; _ComListPorts ; _ComOpenPort ; _ComSetTimeouts ; _ComClosePort ; ; _ComSetBreak ; _ComClearBreak ; _ComGetInputcount ; _ComGetOutputcount ; _ComClearOutputBuffer ; _ComClearInputBuffer ; ; _ComSendByte ; _ComReadByte ; _ComSendBinary ; _ComReadBinary ; ; _ComSendChar ; _ComReadChar ; _ComSendCharArray ; _ComReadCharArray ; _ComSendString ; _ComReadString ; ; __ComClearCommError ; __PurgeComm Maze
       
      ComUDF.au3
      ComUDF-Tests.au3
    • astrionn
      By astrionn
      So I had this Idea of creating a tooltip which shows me my ping.
      That itself was made quickly and I thought too add a couple features.
      I want the tooltip background to be a different color depending on the ping. (good ping is green, medium ping is yellow,...)
      So how do I color in a tooltip? google brought me to this: 
       
      where in the comments I found this:
      $s = "LOW" ToolTip($s, 0, 0, "Battery Information");, $icon) $H_TOOLTIP1 = WinGetHandle($s) DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", $H_TOOLTIP1, "wstr", "", "wstr", "") DllCall("user32.dll", "int", "SendMessage", "hwnd", $H_TOOLTIP1, "int", 1043, "int", 2552550, "int", 0) Sleep(1000) Which I then used in my code with different color codes... Trial and Error brought me these that I wanted to use:
       
      The Problem is if I loop through my code it only sets the color for the 1st loop and then sticks to it.
      The real problem is tho that I don't exactly understand the dllcalls... And I guess that's why it isn't working
      So if someone would be so awesome to explain to me how they work, or at least can give me a list of these parameters then I would really appreciate that and learn something new
      Obviously a solution to my problem is awesome aswell ^^
      I run this under Windows 8.1
      There is my code in a paste.
      https://pastebin.com/q525f7mS
    • Leo1906
      By Leo1906
      Hello Guys,
      once aggain I need your help on a DLL Topic
      I need to pass arguments to my function via a structure, because I am limited to only one argument that can be passed.
      But I don't think that thats so important.
      So here's my approach:
      C++ Code (just the important part):
      extern "C" { struct ParamStruct { const char* test1; const char* test2; const char* test3; int size; }; int testFunc(struct ParamStruct * params) { return params->size; } } And thats how I try to call the function using Autoit:
      Local $struct = "struct;char shapefile[128];char output[128];char filename[128];int size;endstruct" Local $tTest = DllStructCreate($struct) DllStructSetData($tTest, "test1", "Bla") DllStructSetData($tTest, "test2", "BlaBla") DllStructSetData($tTest, "test3", "BlaBlaBla") DllStructSetData($tTest, "size", 40) $dll = DLLOpen("myDLL.dll") $ret = DllCall($dll, "int:cdecl", "testFunc", "STRUCT*", DllStructGetPtr($tTest)) MsgBox(0, 0, $ret[0]) DllClose($dll) Just for testing I want the function to just return the integer value in the struct.
      But this aint working. I tested many things, but still I'm not able to get it running. I even don't know if the mistakes are in the C++ code or the Autoit code or both .. I'm not that skilled at C++ and also not that skilled at Autoit DLLCalls :-/
      I would really appreciate some help!
      Kind regards,
      leo
    • MagicSpark
      By MagicSpark
      Hello,
      can someone help me out with some DllCall in AU3.
      The relevant source of function and struct definition are as follows (in slightly modified form):
      typedef struct {     char    *host;     char    *key;     char    *value; } test_sender_value_t; /******************************************************************************  * Parameters: address   - [IN] server address                                *  *             port      - [IN] server port                                   *  *             source    - [IN] source IP, optional - can be NULL             *  *             values    - [IN] array of values to send                       *  *             count     - [IN] number of items in values array               *  *             result    - [OUT] the server response/error message, optional  *  *                                                                            *  * Return value: 0 - the values were sent successfully, result contains       *  *                         server response                                    *  *               -1 - an error occurred, result contains error message        *  *                                                                            *  ******************************************************************************/ TEST_API int test_sender_send_values(const char *address, unsigned short port, const char *source, const test_sender_value_t *values, int count, char **result);
      In AutoIt I use the following code to build the struct and call the dll:
      Global $struct = DllStructCreate("ptr ptrtostring1;ptr ptrtostring2;ptr ptrtostring3;") Global $string1 = DllStructCreate("char host[255];") DllStructSetData($string1, "host", "Test_Client") DllStructSetData($struct, "ptrtostring1", DllStructGetPtr($string1)) Global $string2 = DllStructCreate("char key[255];") DllStructSetData($string2, "key", "clientver") DllStructSetData($struct, "ptrtostring2", DllStructGetPtr($string2)) Global $string3 = DllStructCreate("char value[255];") DllStructSetData($string3, "value", "123456") DllStructSetData($struct, "ptrtostring3", DllStructGetPtr($string3)) Global $aCall = DllCall("C:\temp\test.dll", "int", "test_sender_send_values", _     "str", "192.168.1.2", _     "int", 80, _     "str", "192.168.1.3", _     "ptr", DllStructGetPtr($struct), _     "int", 1) If @error Then     ConsoleWrite("Error: " & @error & @CRLF)     exit 1 Else     ConsoleWrite("Success: " & $aCall[0] & @CRLF) EndIf
      If I ran the AU3-Script with SciTE I get the following output:
      !>12:00:00 AutoIt3.exe ended.rc:-1073741783 Can someone point me into the right direction. I must admit, that I'm very new to handling DLL-Calls and structs.
      But I've read down the forum threads and the AutoIt help.
      Thanks in advance.