3

_WinAPI_EnumDisplayDevices() reports 3 additional virtual monitors I don't need. So I've created an If statement where if specific flags come about (such as 1, 2, 3, 35, or 33), it only returns those monitors. However, it bugs me how long my conditional statement is:

$_enum = _WinAPI_EnumDisplayDevices("", $x)
If $_enum[3] = 1 OR $_enum[3] = 2 OR $_enum[3] = 3 OR $_enum[3] = 33 OR $_enum[3] = 35 Then

How to get same results with less code?

user4157124
  • 2,809
  • 13
  • 27
  • 42
Anthony Miller
  • 15,101
  • 28
  • 69
  • 98

2 Answers2

1

You should take note of what the flags mean. Check out the example under _WinAPI_EnumDisplayDevices.

In essence when you are checking for flags 1, 2, 3, 33 or 35. You're only really checking for flags 1, 2 and 32. Where "3 = 2 + 1" and "35 = 32 + 2 + 1" and "33 = 32 + 1". With the BitAnd function you can more easily check for these.

Your conditional will become:

If BitAND($_enum[3], 1) Or BitAND($_enum[3], 2) Or BitAND($_enum[3], 32) Then

That's a bit shorter, but if someone else is reading the application he still won't make much sense of it. You can solve this with a comment or by moving the conditional to a new function. Here's an example with a function:

$_enum = _WinAPI_EnumDisplayDevices("", $x)
If isValidMonitor($enum[3]) Then
    ; Do things
EndIf

Func isValidMonitor($i)
    Return BitAND($i, 1) Or BitAND($i, 2) Or BitAND($i, 32)
EndFunc

I chose the isValidMonitor name because I'm not really sure what your code is meant to do. Maybe a better name is "isPrimaryDesktop()" but then I'd remove the check for flag 32. You can see, though, that your code is instantly more readable.

Jos van Egmond
  • 2,370
  • 15
  • 19
  • 1
    You should revise your original post and see what it actually means. Hint: It's not what you posted as answer. Don't go the _ArraySearch route, but use BitAND like the function is actually designed for. – Jos van Egmond Feb 13 '12 at 15:17
-1

Discovered _ArraySearch() allows to search a value in an array, and returns different flags based on what it finds or doesn't. So I can create an array with all values, then perform an _ArraySearch() for $_enum[3] against the array.

I ended up with:

Dim $x = 0, $y = 0, $_enum, $_PhysMon[15] = [1,2,8,32,3,9,33,10,34,40,11,35,36,42,51], $_DefMon[8] = [2,3,10,34,11,35,42,43]
Do
    $_enum = _WinAPI_EnumDisplayDevices("", $x)
    $_physCheck = _ArraySearch($_PhysMon, $_enum[3])
    $_defCheck = _ArraySearch($_DefMon, $_enum[3])
    $x+=1
    msgbox(0,"","Phys Check:  " & $_physCheck & @LF & "Def Check:   " & $_defCheck)
    If $_physCheck <> -1 AND %_defCheck <> -1 Then
        msgbox(0,"","Monitor " & $x & " IS THE PHYSICAL DEFAULT MONITOR")
    ElseIf $_physCheck <> -1 Then
        msgbox(0,"","Monitor " & $x & " IS A PHYSICAL MONITOR")
    Else
        msgbox(0,"","Monitor " & $x & " IS A VIRTUAL MONITOR")
    EndIf
Until NOT $_enum[3]

I've set all possible combinations of flags, successfully parsed what monitors are real (physical) vs not real (virtual) and even defined the machine's default display as well.

user4157124
  • 2,809
  • 13
  • 27
  • 42
Anthony Miller
  • 15,101
  • 28
  • 69
  • 98