针对_WinAPI_EnumDisplayDevices()的条件语句:有更好的方法吗?

时间:2012-02-09 15:00:59

标签: coding-style conditional autoit

我正在执行_WinAPI_EnumDisplayDevices()函数。但是,我的机器报告了3个额外的虚拟监视器,我不需要输出。所以我创建了一个If语句,如果出现特定标志(例如1,2,3,35或33作为标志返回),它只返回那些监视器。但是,它让我觉得我的条件陈述有多长:

$_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

有没有更好的方法可以用更少的工作来获得相同的结果?

2 个答案:

答案 0 :(得分:1)

你应该注意标志的含义。查看_WinAPI_EnumDisplayDevices下的示例。

本质上,当你检查标志1,2,3,33或35.你只是真正检查标志1,2和32.其中“3 = 2 + 1”和“35 = 32 + 2 + 1“和”33 = 32 + 1“。使用BitAnd功能,您可以更轻松地检查这些。

您的条件将成为:

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

这有点短,但如果其他人正在阅读该应用程序,他仍然不会对它有太多的了解。您可以通过注释或将条件移动到新函数来解决此问题。这是一个带函数的例子:

$_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

我选择了isValidMonitor名称,因为我不确定你的代码是做什么的。也许一个更好的名字是“isPrimaryDesktop()”但是我会删除对标志32的检查。但是你可以看到你的代码立即更具可读性。

答案 1 :(得分:-2)

发现_ArraySearch()函数,它允许我搜索数组中的值,并根据它找到或找不到的内容返回不同的标志。所以我可以创建一个包含所有值的数组,然后针对数组对$ _enum [3]执行_ArraySearch()。

编辑:这就是我最终的结果:

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]

我已经设置了所有可能的标志组合,并成功解析了显示器是真实的(物理的)还是非真实的(虚拟的),我甚至也定义了机器的默认显示。