EnumDisplayDevices函数对我不起作用
EnumDisplayDevices function not working for me
我正在尝试以编程方式获取监视器上的信息。循环的内容现在并不重要,它们只包含调试语句,这些语句将在满足循环条件时打印出来。现在,外循环代码执行三次,而内循环代码从未被访问,这意味着(内)循环的while条件从未为真,意味着调用失败。
我这里的问题是Windows API说,关于这个函数:
要获取显示监视器上的信息,请首先调用EnumDisplayDevices,并将lpDevice>设置为NULL。然后,在lpDevice设置为DISPLAY_DEVICE.DeviceName>的情况下,从对EnumDisplayDevices的第一次调用中调用EnumDisplayDevices,并将iDevNum设置为零。则>DISPLAY_DEVICE.DeviceString是监视器名称。
但即使按照它所说的做了,第二个EnumDisplayDevices调用也总是失败?有什么见解吗???
此外,我在windowsxp和windows7上作为一个服务级别的应用程序来做这件事,并得到了相同的结果。当我试图打印出dd.DeviceName时,它会给我一个地址(例如:0x12cfa4),但这一定是函数在第二次调用时所期望的,因为MSDN说,只需传入显示设备指针并将.DeviceName附加到它…
使用C++(使用Qt)、Windows API/MSDN调用。
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"传递到内部调用。我知道这没有道理,但我怀疑,由于dd是一个out参数,API正在向它写入,但随后查看输入参数的内容。如果他们在执行之前将输出parm记忆为0以保持理智,则可能会发生这种情况。
只要确保这不是发送一个非空的dd,我用完全相同的比特制作了第二个dd,事情仍然很好。这绝对是混叠记忆。
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "user32.lib")
void DumpDevice(const DISPLAY_DEVICE& dd, size_t nSpaceCount )
{
printf("%*sDevice Name: %sn", nSpaceCount, "", dd.DeviceName );
printf("%*sDevice String: %sn", nSpaceCount, "", dd.DeviceString );
printf("%*sState Flags: %xn", nSpaceCount, "", dd.StateFlags );
printf("%*sDeviceID: %sn", nSpaceCount, "", dd.DeviceID );
printf("%*sDeviceKey: ...%snn", 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;
}
我现在所在的盒子只有1个监视器,所以我无法验证内部循环,但我怀疑这很好,因为"newdd"从未在调用中被别名化。你还说你在服务环境中——我不确定winstation是否会限制你对显示器的看法——所以这也可能是一个问题;但我怀疑你至少还能看到物理设备。在我的机器上我得到:
Device Name: \.DISPLAY1
Device String: NVIDIA GeForce GTX 580
State Flags: 8000005
DeviceID: PCIVEN_10DE&DEV_1080&SUBSYS_15803842&REV_A1
DeviceKey: ...ControlVideo{B0CDD262-FCFB-4FD4-A03C-54621896C9CD} 000
Device Name: \.DISPLAY1Monitor0
Device String: Generic PnP Monitor
State Flags: 3
DeviceID: MONITORDEL4016{4d36e96e-e325-11ce-bfc1-08002be10318} 002
DeviceKey: ...ControlClass{4d36e96e-e325-11ce-bfc1-08002be10318} 002
Device Name: \.DISPLAY2
Device String: NVIDIA GeForce GTX 580
State Flags: 0
DeviceID: PCIVEN_10DE&DEV_1080&SUBSYS_15803842&REV_A1
DeviceKey: ...ControlVideo{B0CDD262-FCFB-4FD4-A03C-54621896C9CD} 001
Device Name: \.DISPLAYV1
Device String: RDPDD Chained DD
State Flags: 8
DeviceID:
DeviceKey: ...ControlVideo{DEB039CC-B704-4F53-B43E-9DD4432FA2E9} 000
Device Name: \.DISPLAYV2
Device String: RDP Encoder Mirror Driver
State Flags: 200008
DeviceID:
DeviceKey: ...ControlVideo{42cf9257-1d96-4c9d-87f3-0d8e74595f78} 000
Device Name: \.DISPLAYV3
Device String: RDP Reflector Display Driver
State Flags: 200008
DeviceID:
DeviceKey: ...ControlVideo{b043b95c-5670-4f10-b934-8ed0c8eb59a8} 000
如果您是专门为Win7及更高版本编写代码的,您可能需要了解QueryDisplayConfig和相关函数。
- C++为什么尽管我调用了void函数,它却不起作用
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 通过构造函数创建一些值并尝试添加到文档中使用 rapidjson 不起作用
- 为什么我的数组双精度函数不起作用?
- 使用 va_arg 传递给函数va_list不起作用
- Windows.h 输入在函数之外不起作用
- 类和构造函数中的函数根本不起作用,并且不返回任何错误
- 类中的虚拟布尔函数参数不起作用
- getline 函数似乎在 C++ 中不起作用
- 将新放置与 std::函数一起使用不起作用
- binary_search() 函数在我的函数体中不起作用
- 为什么读取函数在 sha1 c++ 实现中不起作用?
- 在函数中声明的 ifStream 对象在发布模式下不起作用
- 指针变量在 cout 函数中不起作用
- std::函数不起作用,但普通的旧函数指针可以 - 为什么?
- C++ 函数,用于查找数组中四个最小最大元素的总和不起作用
- 为什么必须使用'*p=a',而使用'p=&a'在构造函数中不起作用
- C++ Arduino - 随机函数不起作用
- QObject::连接不起作用 - 使用函数语法找不到信号
- 函数在类中不起作用-函数调用缺少参数列表