Jump to content

Tutorial on DllCall() & DllStructs


Recommended Posts

  • Replies 43
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

So I think it's time to publish this little tutorial I have made on using DllCall() and DllStructs. It's not near completion but I think it's a good start at least This tutorial is mostly aimed fo

Null is designed for wstr/str and Objects. I would do it this ways. #include <Array.au3> $calldata = DllCall("Kernel32.dll","int","GetDiskFreeSpaceW","wstr","C:\","dword*",0 ,

Even more fun! Made this after checking out LockWorkStation because of your DLL tutorial: Get notification when session is locked and unlocked: Global Const $NOTIFY_FOR_THIS_SESSION = 0x0

Heh, thank you very much.

Page 6:

Strings in DllCall()

As you should know strings in dlls are in fact arrays of chars, fortunately AutoIt helps us with passing this so all you have to do is to choose “str” or “wstr” and then just put in your string in the paramx param in DllCall(). A very important thing to remember here is that since windows was not fully Unicode until win2000 almost all function that deals with strings is implemented in two versions. They usually have an ‘A’ or a ‘W’ n the end if its name, like this “MyStringFunctionA”, where A stands for ANSI and W stands for wide char, aka as Unicode.

Maybe you've meant in? but I think in is not correct ^_^ at sounds more correct in my opinion. And if -> of?

Page 9:

The first thing you’ll probably notice is the type WORD, this type is not specified in AutoIt so you will have find out what Microsoft means with WORD, a quick googling for “WORD typedef” turns out that WORD is actually an unsigned 16 bit integer aka as “ushort” in AutoIt (check the help file entry for DllCall). So the complete translation of the struct (and the simple call) is as follow:

(\ /)

(o O)

('')('')

Edited by Authenticity
Link to post
Share on other sites
  • 2 months later...

Great tutorial. I haven't really looked into dlls very much because I was too lazy, but now I will because all of the information is in one place.

[font="Verdana"] [size="2"]"[/size][/font]Failure is not an option -- it comes packaged with Windows"[font="Verdana"][size="2"] Gecko Web Browser[/size][/font][font="Verdana"][size="2"], [/size][/font][font="Verdana"][size="2"]Yahtzee![/size][/font][font="Verdana"][size="2"], Toolbar Launcher (like RocketDock)[/size][/font][font="Verdana"][size="2"]Internet Blocker, Simple Calculator, Local Weather, Easy GDI+ GUI [/size][/font][font="Verdana"][size="2"]Triangle Solver, TCP File Transfer, [/size][/font][font="Verdana"][size="2"]Valuater's Autoit Wrappers[/size][/font][font="Verdana"][size="3"][size="2"][size="2"]OOP In AutoIt[/size][/size][/size][/font][font="Verdana"][size="2"][size="1"]Using Windows XP SP3, 1GB RAM, AMD Athlon Processor @ 2.1 GHzCheck me out at gadgets.freehostrocket.com[/size][/size][/font]

Link to post
Share on other sites

Excellent idea and a lot of good work in there. I've learned several new things already.

:D

I don't think this is true, however (Page 4):

This is the exact same function that is being called when you write Sleep(100) in AutoIt, its just that AutoIt acts a layer between you and the function.

The reason I don't think so:

Sleep can be interrupted:

HotKeySet("{ESC}", "_ESC")

Sleep(10000)

MsgBox(64, "Timeout", "Quitting due to timeout")

Func _ESC()
    MsgBox(64, "ESC", "Quitting on ESC")
    Exit
EndFunc

The DLL Sleep call used cannot be interrupted:

HotKeySet("{ESC}", "_ESC")

DllCall("kernel32.dll", "none", "Sleep", "dword", 10000)

MsgBox(64, "Timeout", "Quitting due to timeout")

Func _ESC()
    MsgBox(64, "ESC", "Quitting on ESC")
    Exit
EndFunc

Still good stuff, because I wouldn't have tried that without your tutorial's prompting.

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to post
Share on other sites

@PsaltyDS

AutoIt doesn't do one large sleep, but multiple small sleeps that equal the value in Sleep(). A more fair comparison would have been:

HotKeySet("{ESC}", "_ESC")

For $X = 0 To 100
    DllCall("kernel32.dll", "none", "Sleep", "dword", 100)
Next

MsgBox(64, "Timeout", "Quitting due to timeout")

Func _ESC()
    MsgBox(64, "ESC", "Quitting on ESC")
    Exit
EndFunc

Note that I only guessed the numbers, but this makes it interruptable and supports Monoceres claims.

Edit: Look at THIS to see what i am rambling about :D

Edited by AdmiralAlkex
Link to post
Share on other sites

Even more fun! :D

Made this after checking out LockWorkStation because of your DLL tutorial:

Get notification when session is locked and unlocked:

Global Const $NOTIFY_FOR_THIS_SESSION = 0x0
Global Const $NOTIFY_FOR_ALL_SESSIONS = 0x1
Global Const $WM_WTSSESSION_CHANGE = 0x2B1

Global Const $WTS_CONSOLE_CONNECT = 0x1
Global Const $WTS_CONSOLE_DISCONNECT = 0x2
Global Const $WTS_REMOTE_CONNECT = 0x3
Global Const $WTS_REMOTE_DISCONNECT = 0x4
Global Const $WTS_SESSION_LOGON = 0x5
Global Const $WTS_SESSION_LOGOFF = 0x6
Global Const $WTS_SESSION_LOCK = 0x7
Global Const $WTS_SESSION_UNLOCK = 0x8
Global Const $WTS_SESSION_REMOTE_CONTROL = 0x9

Global $hGUI = GUICreate("Message Sink", 400, 600); GUI to receive notification
Global $sMsg = "$hGUI = " & $hGUI & @CRLF
Global $ctrlEdit = GUICtrlCreateEdit($sMsg, 10, 10, 380, 580)
GUISetState()

GUIRegisterMsg($WM_WTSSESSION_CHANGE, "_WM_WTSSESSION_CHANGE")
DllCall("Wtsapi32.dll", "int", "WTSRegisterSessionNotification", "hwnd", $hGUI, "dword", $NOTIFY_FOR_THIS_SESSION)
DllCall("Kernel32.dll", "none", "Sleep", "dword", 1000)
DllCall("User32.dll", "int", "LockWorkStation")
While 1
    If GUIGetMsg() = -3 Then ExitLoop
WEnd
DllCall("Wtsapi32.dll", "int", "WTSUnRegisterSessionNotification", "hwnd", $hGUI)

Func _WM_WTSSESSION_CHANGE($hWnd, $iMsgID, $wParam, $lParam)
    $sMsg &= @CRLF & @HOUR & ":" & @Min & ":" & @SEC & " = "
    Switch $wParam
        Case $WTS_CONSOLE_CONNECT
            $sMsg &= "A session was connected to the console terminal."
        Case $WTS_CONSOLE_DISCONNECT
            $sMsg &= "A session was disconnected from the console terminal."
        Case $WTS_REMOTE_CONNECT
            $sMsg &= "A session was connected to the remote terminal."
        Case $WTS_REMOTE_DISCONNECT
            $sMsg &= "A session was disconnected from the remote terminal."
        Case $WTS_SESSION_LOGON
            $sMsg &= "A user has logged on to the session."
        Case $WTS_SESSION_LOGOFF
            $sMsg &= "A user has logged off the session."
        Case $WTS_SESSION_LOCK
            $sMsg &= "A session has been locked."
        Case $WTS_SESSION_UNLOCK
            $sMsg &= "A session has been unlocked."
        Case $WTS_SESSION_REMOTE_CONTROL
            $sMsg &= "A session has changed its remote controlled status."
    EndSwitch
    $sMsg &= @CRLF & "$hWnd = " & $hWnd & @CRLF & _
            "$iMsgID = 0x" & Hex($iMsgID, 8) & @CRLF & _
            "$wParam = " & $wParam & @CRLF & _
            "$lParam = " & $lParam & @CRLF
    ControlSetText($hGUI, "", $ctrlEdit, $sMsg)
EndFunc

Thank you, master monoceres, for my DLL-fu grows stronger! There must be great Chi in sitting around eating cereal in your underwear!

:D

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to post
Share on other sites

@PsaltyDS

There are older Autoit's sources so you may look at Sleep implementation

http://www.autoitscript.com/autoit3/files/...-v3.1.0-src.exe

Thanks for the tip, very interesting.

Inside Utility.cpp, the util_sleep() function loops "::sleep(0);" until another counter detects timeout. I assume the double colon "::" makes a library reference to the C++ sleep() function. Is that the same thing as calling the Kernel32.dll version of sleep()?

Another difference I notice is the DLL sleep() accepts -1 as INFINITE (never timeout), but the AutoIt function just ignores any timeout < 0.

:D

Edit: Typo.

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to post
Share on other sites

Why would you want to never timeout?

I don't know enough C++ to say, but I get the impression there are other ways to get the thread to continue besides a timeout. Perhaps registered events or callbacks? When I said "cannot be interrupted" earlier, I meant in AutoIt. It wouldn't be surprising to have more options in C++.

The reference MSDN article mentions SleepEx() for just such usage.

:D

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...