Jon

DllCall

46 posts in this topic

#1 ·  Posted (edited)

DllCall is great. But it can be tricky to use. Here are some syntax notes geared towards using the Windows API. When you manage to get DllCall to work with a new api then please post the syntax you used and the MSDN API syntax so that others may benefit. I'll merge all the posts into this one.

Windows API

All the Windows API details you need can be found by searching at MSDN Library

Common Datatypes

AutoIt has a single datatype - the variant. A variant can hold HWNDs (window handles), integers (32 and 64bit), floating point numbers (doubles). Windows API calls take many different sorts of datatypes and in the DllCall function you must work out which type to use for conversion.

Complete list of Windows Datatypes

Windows Datatype = DllCall Type

BOOL = "int"

COLORREF = "int"

DWORD = "int"

HANDLE = "ptr"

HDC = "ptr"

HFILE = "int"

HFONT = "ptr"

HICON = "ptr"

HINSTANCE = "ptr"

HKEY = "ptr"

HMENU = "ptr"

HMODILE = "ptr"

HWND = "hwnd"

INT = "int"

LONG = "long"

LPARAM = "long"

LPCTSTR = "str" ("wstr" if a UNICODE function)

LPINT = "int_ptr"

LPLONG = "long_ptr"

UINT = "int"

ULONG = "long"

WPARAM = "int"

API List

Here is a list of API functions that have been used successfully in AutoIt and their respective DllCall syntax.

GetAsyncKeyState - DllCall("user32.dll", "int", "GetAsyncKeyState", "int", $hexKey)

GetTickCount - DllCall("kernel32.dll", "long", "GetTickCount")

MessageBeep - DllCall ("user32.dll", "int", "MessageBeep", "int", 0xFFFFFFFF)

MessageBox - DllCall("user32.dll", "int", "MessageBox", "hwnd", 0, "str", "text", "str", "title", "int", 0)

PrintUI /? - DllCall("printui.dll", "none", "PrintUIEntryW", "hwnd", 0, "ptr", 0, "wstr", "/?", "int", @SW_SHOWNORMAL)

Edited by Jon

Share this post


Link to post
Share on other sites

#2 ·  Posted (edited)

I would have prefer a syntax like

DllCall("user32.dll", "int", "MessageBox", "hwnd", 0, "str", "text", "str", "title", "int", 0)
DllCall("printui.dll", "none", "PrintUIEntryW", "hwnd", 0, "ptr", 0, "wstr", "/?", "int", @SW_SHOWNORMAL)

being

DllCall("user32.dll", "int = MessageBox(hwnd,str,str,int)", 0, "text", "title", 0)
DllCall("printui.dll",  "PrintUIEntryW(hwnd,ptr,wstr,int)", 0,  0,  "/?",  @SW_SHOWNORMAL)
Edited by jpm

Share this post


Link to post
Share on other sites

Changing Wallpapers, only with Active Desktop disabled and with .bmp files.

For using other filetypes check topng.exe from bcheck site for converting on-the fly.

Func _ChangeWallpaper($sFile,$iType)
  ; Changes the wallpaper to $sFilename using $iType as:
  ; 1 Tiled
  ; 2 Centered
  ; 3 Stretched
  ; any other value (usually 0) unchanged
  ; Returns
  ; 0 if everything is allright.
  ; -1 if $sFile does not exist. @error is set to 1
  ; -2 if $sFile is not a .bmp file. @error is set to 2

   If Not FileExists($sFile) Then
      SetError(1)
      Return -1
   EndIf
   If StringTrimLeft($sFile,StringInStr($sFile,'.',0,-1)) <> 'bmp' Then
      SetError(2)
      Return -2
   EndIf

   Select
   Case $iType = 1
      RegWrite('HKCU\Control Panel\Desktop','TileWallpaper','reg_sz','1')
      RegWrite('HKCU\Control Panel\Desktop','WallpaperStyle','reg_sz','0')
   Case $iType = 2
      RegWrite('HKCU\Control Panel\Desktop','TileWallpaper','reg_sz','0')
      RegWrite('HKCU\Control Panel\Desktop','WallpaperStyle','reg_sz','0')
   Case $iType = 3
      RegWrite('HKCU\Control Panel\Desktop','TileWallpaper','reg_sz','0')
      RegWrite('HKCU\Control Panel\Desktop','WallpaperStyle','reg_sz','2')
   Case Else
     ;
   EndSelect

   RegWrite('HKCU\Control Panel\Desktop','Wallpaper','reg_sz',$sFile)
   DllCall("user32","int","SystemParametersInfo","int",20,"int",0,"str",$sFile,"int",0)

   Return 0
EndFunc

Installing new fonts:

Func _InstallFont($sFileName)
   If FileMove($sFileName, @WindowsDir & '\Fonts', 1) Then
      $sFileName = @WindowsDir & '\Fonts\' & StringTrimLeft($sFileName, StringInStr($sFileName, '\', 0, -1))
      DllCall('gdi32', 'long', "AddFontResourceA", 'String', $sFileName)
      Return 1
   Else
      Return 0
   EndIf
EndFunc  ;==>_InstallFont

Uninstalling fonts...

Func _UnInstallFonts($sFontsName)
   Local $sFileName = @WindowsDir & '\fonts\' & $sFontsName
   $a = DllCall('gdi32', 'long', "RemoveFontResourceA", 'String', $sFileName)
   If Not @error And $a[0] <> 0 Then
      FileDelete($sFileName)
      Return 1
   Else
      Return 0
   EndIf
EndFunc  ;==>_UnInstallFonts

Returns the number of ms that have elapsed since, Windows has started

$r = DllCall('kernel32','long','GetTickCount')
MsgBox(4096,'Time','Windows started ' & $r[0] & ' ms ago.')

ShellExecute one of the most useful!

Func _ShellExecuteDllCall($sCmd, $sVerb, $sArg, $sFolder)
   Local $aRet
   
   $aRet = DllCall("shell32.dll", "long", "ShellExecute", "hwnd", 0, "string", $sVerb, _
         "string", $sCmd, "string", $sArg, "string", $sFolder, "long", @SW_SHOWNORMAL)
   Return $aRet
   
   If $aRet[0] > 32 Then
      Return 1;All Ok
   Else
      Return 0;Problems
   EndIf
EndFunc  ;==>_ShellExecuteDllCall

Share this post


Link to post
Share on other sites

I would have prefer a syntax like

DllCall("user32.dll", "int", "MessageBox", "hwnd", 0, "str", "text", "str", "title", "int", 0)
DllCall("printui.dll", "none", "PrintUIEntryW", "hwnd", 0, "ptr", 0, "wstr", "/?", "int", @SW_SHOWNORMAL)

being

DllCall("user32.dll", "int = MessageBox(hwnd,str,str,int)", 0, "text", "title", 0)
DllCall("printui.dll",  "PrintUIEntryW(hwnd,ptr,wstr,int)", 0,  0,  "/?",  @SW_SHOWNORMAL)

Bit late for that don't you think?! :idiot:

Share this post


Link to post
Share on other sites

one of Ezzetabi's functions...

Func _IsPressed($hexKey)

  
  Local $aR, $bRv
  $hexKey = '0x' & $hexKey
  $aR = DllCall("user32", "int", "GetAsyncKeyState", "int", $hexKey)
 
  If $aR[0] <> 0 Then
     $bRv = 1
  Else
     $bRv = 0
  EndIf
  
  Return $bRv
EndFunc

Checks if any keys were pressed. :idiot:


FootbaG

Share this post


Link to post
Share on other sites

So how would I use dllcall with this ?

long auxSetVolume(UINT uDeviceID,DWORD dwVolume);

Ive tryed a few varations but nothing works, and theres no reference telling me wether its user32.dll or printui.dll or whatever.dll

Found from Source 1 or Source 2

Plz help

Share this post


Link to post
Share on other sites

about the soruces to see what dll it is... id assume "winmm.dll" because most of the DLL's ive seen have had the same name as the librarys...


FootbaG

Share this post


Link to post
Share on other sites

Bit late for that don't you think?! :idiot:

<{POST_SNAPBACK}>

for me NO, but for Larry ... :">

perhaps we can put an Opt("DllCallFormatMode",1) :D

Share this post


Link to post
Share on other sites

about the soruces to see what dll it is... id assume "winmm.dll" because most of the DLL's ive seen have had the same name as the librarys...

That's listed in MSDN too. Here the the MSDN page for MessageBox - notice down at the bottom it tells you what dll to use.

http://msdn.microsoft.com/library/en-us/wi.../messagebox.asp

Share this post


Link to post
Share on other sites

Why can we just use the dlls as they are ? Why must their form be changed for autoit ?

If this is to somehow make it easier to call dlls, then im very confussed. :idiot:

perhaps we can put an Opt("DllCallFormatMode",1)

Are you suggesting that after setting such an opt to 1, that you could use the dll straight as their shown on the msdn library, without editing ?

Share this post


Link to post
Share on other sites

What he is saying is that the syntax of

DllCall("user32.dll", "int = MessageBox(hwnd,str,str,int)", 0, "text", "title", 0)
is easier to type and read than
DllCall("user32.dll", "int", "MessageBox", "hwnd", 0, "str", "text", "str", "title", "int", 0)


Who else would I be?

Share this post


Link to post
Share on other sites

i know this is simple but if you want to add a beep to your script, use this:

DllCall ("user32.dll", "int", "MessageBeep", "int", 0xFFFFFFFF)

:idiot:


FootbaG

Share this post


Link to post
Share on other sites

i know this is simple but if you want to add a beep to your script, use this:

DllCall ("user32.dll", "int", "MessageBeep", "int", 0xFFFFFFFF)

:idiot:

This should probaby be added as a builtin function too I think.

Share this post


Link to post
Share on other sites

This should probaby be added as a builtin function too I think.

<{POST_SNAPBACK}>

Oh, very well. Perhaps, would be fine a traditional beep like a builtin function. :idiot:

Beep( Frequency, Duration)

DLL's sample:

DllCall ("kernel32.dll", "long", "Beep", "long", 450, "long", 100)
DllCall ("kernel32.dll", "long", "Beep", "long", 360, "long", 100)

Share this post


Link to post
Share on other sites

Oh, very well. Perhaps, would be fine a traditional beep like a builtin function.  :idiot:

Beep( Frequency, Duration)

DLL's sample:

DllCall ("kernel32.dll", "long", "Beep", "long", 450, "long", 100)
DllCall ("kernel32.dll", "long", "Beep", "long", 360, "long", 100)

<{POST_SNAPBACK}>

good idea but i doubt that that would work on most peoples computer... as windows xp computers get more popular... u need to have N.T. 4.0 i think or later in order to run your above code... but maybe im wrong, maybe a lot of people do have N.T... because i had tried that dllcall but it's not compatible with my computer :D

FootbaG

Share this post


Link to post
Share on other sites

good idea but i doubt that that would work on most peoples computer... as windows xp computers get more popular... u need to have N.T. 4.0 i think or later in order to run your above code... but maybe im wrong, maybe a lot of people do have N.T... because i had tried that dllcall but it's not compatible with my computer :idiot:

Should work on anything:

Requirements

Client: Requires Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95.

Share this post


Link to post
Share on other sites

Beep should use the internal PC speaker. Works here on XP Pro.

Addition to Layers DllCall. Maybe usefull?

DllCall ("user32.dll", "int", "MessageBeep", "int", 0x33333333);Exclamation
DllCall ("user32.dll", "int", "MessageBeep", "int", 0x44444444);Error
DllCall ("user32.dll", "int", "MessageBeep", "int", 0xFFFFFFFF);Layers Beep

Share this post


Link to post
Share on other sites

It is not better posting in Func form?

Func _Beep($Frequency, $Duration)
   DllCall ("kernel32.dll", "long", "Beep", "long", $Frequency, "long", $Duration)
EndFunc

So even the noobest can understand.

Share this post


Link to post
Share on other sites

It is not better posting in Func form?

Func _Beep($Frequency, $Duration)
   DllCall ("kernel32.dll", "long", "Beep", "long", $Frequency, "long", $Duration)
EndFunc

So even the noobest can understand.

<{POST_SNAPBACK}>

Maybe. :D

BTW: The "duration" parameter is a mess not to specify it. :idiot:

Share this post


Link to post
Share on other sites

Should work on anything:

<{POST_SNAPBACK}>

hmmm.. funny, i forgot what site i was at and it said it only works on N.T. 4.0 or higher... maybe i read wrong :"> let me see if i can find the site... err can't find it.. damn it, i read wrong :"> sorry for the inconvinience! :idiot:

FootbaG

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.