EnumDisplayDevices函数不为我工作 [英] EnumDisplayDevices function not working for me

查看:583
本文介绍了EnumDisplayDevices函数不为我工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图以编程方式在我的显示器上获取信息。循环的内容现在不重要,它们只包含当循环条件满足时打印的调试语句。现在,外部循环代码执行三次,内部循环代码从不被访问,意味着(内部)循环的while条件永远不为真,意味着调用失败。

I'm trying to get info on my monitors programmatically. The content of the loops is not important right now, they just contain debug statements that will be printed when the loop condition is satisfied. Right now, the outer loop code executes three times and the inner loop code is never accessed, meaning the while condition of the (inner) loop is never true, meaning that call fails.

我的问题在这里是Windows API说,关于此功能:

My problem here is that the Windows API says, regarding this function:


要获得显示监视器上的信息,首先调用EnumDisplayDevices与lpDevice>设置为NULL。然后调用EnumDisplayDevices与lpDevice设置为DISPLAY_DEVICE.DeviceName>从第一次调用EnumDisplayDevices和iDevNum设置为零。然后> DISPLAY_DEVICE.DeviceString是监视器名称。

To obtain information on a display monitor, first call EnumDisplayDevices with lpDevice >set to NULL. Then call EnumDisplayDevices with lpDevice set to DISPLAY_DEVICE.DeviceName >from the first call to EnumDisplayDevices and with iDevNum set to zero. Then >DISPLAY_DEVICE.DeviceString is the monitor name.

...但即使完成它的说明后,第二个EnumDisplayDevices调用总是失败?任何洞察力

...but even after doing exactly what it says, the second EnumDisplayDevices call always fails? Any insight???

同时我做这个服务级别的应用程序在Windows XP和Windows 7,并得到相同的结果。当我尝试打印出dd.DeviceName,它给我一个地址(例如:0x12cfa4),但这必须是函数期待在第二次调用,因为MSDN说只是传入你的显示设备指针,并追加.DeviceName it ...

Also I'm doing this as a service level application on both windows xp and windows 7 and getting the same results. When I try to print out dd.DeviceName, it gives me an address (for example: 0x12cfa4), but this must be what the function is expecting on the second call as MSDN says just pass in your display device pointer and append .DeviceName to it...

C ++(使用Qt),使用Windows API / MSDN调用。

C++ (using Qt), Windows API/MSDN calls are used.

    DISPLAY_DEVICE dd;

    dd.cb = sizeof(DISPLAY_DEVICE);

    DWORD deviceNum = 0;
    while( EnumDisplayDevices(NULL, deviceNum, &dd, 0) ){
        qWarning() << "We've entered the outer loop.";

        while( EnumDisplayDevices(dd.DeviceName, 0, &dd, 0)){
            qWarning() << "We've entered the inner loop.";
        }

        deviceNum++;
    }


推荐答案

'进入内部调用,同时使用'dd'成员作为输入字符串。我知道这没有意义,但我怀疑,因为dd是一个out参数,API正在写入它,但随后查看输入参数的内容,它已经在它上面写了。这可能发生,如果他们做的事情输出parm为0执行之前的理智。

The problem is passing 'dd' into the inner call while using a member of 'dd' as the input string. I know this doesn't make sense, but I suspect that since dd is an out parameter the API is writing to it, but then looking that the contents of the input parameter after it has scribbled on it. This could happen if they did something like memset'ing the output parm to 0 before execution for sanity.

只要确保它不是关于发送在非空dd,我做了第二个dd与完全相同的位,它仍然工作正常。这绝对是别名记忆。

Just make sure it wasn't something about sending in a non-empty dd, I made a second dd with the exact same bits in it and things still work fine. It's definitely the aliased memory.

#include <windows.h>
#include <stdio.h>

#pragma comment(lib, "user32.lib")

void DumpDevice(const DISPLAY_DEVICE& dd, size_t nSpaceCount )
{
    printf("%*sDevice Name: %s\n", nSpaceCount, "", dd.DeviceName );
    printf("%*sDevice String: %s\n", nSpaceCount, "", dd.DeviceString );
    printf("%*sState Flags: %x\n", nSpaceCount, "", dd.StateFlags );
    printf("%*sDeviceID: %s\n", nSpaceCount, "", dd.DeviceID );
    printf("%*sDeviceKey: ...%s\n\n", nSpaceCount, "", dd.DeviceKey+42 );
}

int main()
{
    DISPLAY_DEVICE dd;

    dd.cb = sizeof(DISPLAY_DEVICE);

    DWORD deviceNum = 0;
    while( EnumDisplayDevices(NULL, deviceNum, &dd, 0) ){
        DumpDevice( dd, 0 );
        DISPLAY_DEVICE newdd = {0};
        newdd.cb = sizeof(DISPLAY_DEVICE);
        DWORD monitorNum = 0;
        while ( EnumDisplayDevices(dd.DeviceName, monitorNum, &newdd, 0))
        {
            DumpDevice( newdd, 4 );
            monitorNum++;
        }
        puts("");
        deviceNum++;
    }

    return 0;
}

我现在所在的方块现在只有一个显示器, '验证内部循环,但我怀疑它很好,因为'newdd'从来没有被别名进入调用。你也说你在一个服务上下文 - 我不知道那个winstation会限制你看到的显示器,所以这也可能是一个问题;但我怀疑你应该仍然能够至少看到物理设备。在我的机器上,我得到:

The box I'm on right now only has 1 monitor, so I can't verify the inner loop, but I suspect it's fine since 'newdd' never gets aliased into the call. You also say you are in a service context - I'm not sure if that winstation will restrict what you see about the displays - so that could also be a problem; but I suspect you should still be able to at least see the physical device. On my machine I get:

Device Name: \\.\DISPLAY1
Device String: NVIDIA GeForce GTX 580
State Flags: 8000005
DeviceID: PCI\VEN_10DE&DEV_1080&SUBSYS_15803842&REV_A1
DeviceKey: ...\Control\Video\{B0CDD262-FCFB-4FD4-A03C-54621896C9CD}\0000

   Device Name: \\.\DISPLAY1\Monitor0
   Device String: Generic PnP Monitor
   State Flags: 3
   DeviceID: MONITOR\DEL4016\{4d36e96e-e325-11ce-bfc1-08002be10318}\0002
   DeviceKey: ...\Control\Class\{4d36e96e-e325-11ce-bfc1-08002be10318}\0002

Device Name: \\.\DISPLAY2
Device String: NVIDIA GeForce GTX 580
State Flags: 0
DeviceID: PCI\VEN_10DE&DEV_1080&SUBSYS_15803842&REV_A1
DeviceKey: ...\Control\Video\{B0CDD262-FCFB-4FD4-A03C-54621896C9CD}\0001

Device Name: \\.\DISPLAYV1
Device String: RDPDD Chained DD
State Flags: 8
DeviceID:
DeviceKey: ...\Control\Video\{DEB039CC-B704-4F53-B43E-9DD4432FA2E9}\0000

Device Name: \\.\DISPLAYV2
Device String: RDP Encoder Mirror Driver
State Flags: 200008
DeviceID:
DeviceKey: ...\Control\Video\{42cf9257-1d96-4c9d-87f3-0d8e74595f78}\0000

Device Name: \\.\DISPLAYV3
Device String: RDP Reflector Display Driver
State Flags: 200008
DeviceID:
DeviceKey: ...\Control\Video\{b043b95c-5670-4f10-b934-8ed0c8eb59a8}\0000

这篇关于EnumDisplayDevices函数不为我工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆