Jump to content

Problem in _WinAPI_EnumDisplayDevices


Recommended Posts

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...