Jump to content
Sign in to follow this  
murmansk

Problem in _WinAPI_EnumDisplayDevices

Recommended Posts

murmansk

When you launch the example in the help of _WinAPI_EnumDisplayDevices, it never ends.

The problem lies in the way that the WinAPI function informs that there are not more devices: in the MSDN documentation says that it will return 0, but the AutoIt function only checks for @error in the DllCall and not tests if the result of the call==0.

Added a new local variable "$retval" that holds the return value of DllCall, and if $retval==0 sets @error.

Now it works as described in the documentation, but probably will be better to modify the code and documentation to map the MSDN documentation, returning 0 when there are no more displaydevices.

Func _WinAPI_EnumDisplayDevices($sDevice, $iDevNum)
    Local $pName = 0,  $iFlags = 0, $aDevice[5], $retval

    If $sDevice <> "" Then
        Local $tName = DllStructCreate("wchar Text[" & Stringlen($sDevice) + 1 & "]")
        $pName = DllStructGetPtr($tName)
        DllStructSetData($tName, "Text", $sDevice)
    EndIf
    Local $tDevice = DllStructCreate($tagDISPLAY_DEVICE)
    Local $pDevice = DllStructGetPtr($tDevice)
    Local $iDevice = DllStructGetSize($tDevice)
    DllStructSetData($tDevice, "Size", $iDevice)
    $retval = DllCall("user32.dll", "bool", "EnumDisplayDevicesW", "ptr", $pName, "dword", $iDevNum, "ptr", $pDevice, "dword", 1)
    If @error Then Return SetError(@error, @extended, 0)
    If ($retval[0]==0) Then Return SetError(1)

    Local $iN = DllStructGetData($tDevice, "Flags")
    If BitAND($iN, $__WINAPICONSTANT_DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) <> 0 Then $iFlags = BitOR($iFlags, 1)
    If BitAND($iN, $__WINAPICONSTANT_DISPLAY_DEVICE_PRIMARY_DEVICE) <> 0 Then $iFlags = BitOR($iFlags, 2)
    If BitAND($iN, $__WINAPICONSTANT_DISPLAY_DEVICE_MIRRORING_DRIVER) <> 0 Then $iFlags = BitOR($iFlags, 4)
    If BitAND($iN, $__WINAPICONSTANT_DISPLAY_DEVICE_VGA_COMPATIBLE) <> 0 Then $iFlags = BitOR($iFlags, 8)
    If BitAND($iN, $__WINAPICONSTANT_DISPLAY_DEVICE_REMOVABLE) <> 0 Then $iFlags = BitOR($iFlags, 16)
    If BitAND($iN, $__WINAPICONSTANT_DISPLAY_DEVICE_MODESPRUNED) <> 0 Then $iFlags = BitOR($iFlags, 32)
    $aDevice[0] = True
    $aDevice[1] = DllStructGetData($tDevice, "Name")
    $aDevice[2] = DllStructGetData($tDevice, "String")
    $aDevice[3] = $iFlags
    $aDevice[4] = DllStructGetData($tDevice, "ID")
    Return $aDevice
EndFunc   ;==>_WinAPI_EnumDisplayDevices

Share this post


Link to post
Share on other sites
PsaltyDS

What version are you looking at? The current version of AutoIt is 3.3.6.1, and the example script's loop in the help file exits like this:

While 1
    $aDevice = _WinAPI_EnumDisplayDevices("", $i)
    If Not $aDevice[0] Then ExitLoop
    
    ;...

WEnd

It's testing the return code in $aDevice[0], not @error.

:)

Edit: Oops, spoke too soon. I was looking at the example script, not the UDF function.

;)

The example script is still wrong. Since the function does not always return an array, the example should not assume $aDevice is an array, and $aDevice[0] is available to test.

;)

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

Share this post


Link to post
Share on other sites
trancexx

Changing it the way murmansk suggest would be wrong. It would be script braking change.

Solution could be (murmansk's choice of variable names):

;...
$retval = DllCall("user32.dll", "bool", "EnumDisplayDevicesW", "ptr", $pName, "dword", $iDevNum, "ptr", $pDevice, "dword", 1)
If @error Then Return SetError(@error, @extended, 0)
If $retval[0] Then $aDevice[0] = True
;...

This should be reported so that someday when devs decide they are done with fucking around and pissing contest they could fix it.

Edited by trancexx

♡♡♡

.

eMyvnE

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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.