2012-03-01 2 views
4

프로그래밍 방식으로 내 모니터에 대한 정보를 얻으려고합니다. 루프의 내용은 현재 중요하지 않으며 루프 조건이 충족 될 때 인쇄되는 디버그 문만 포함합니다. 바로 지금, 외부 루프 코드는 세 번 실행되고 내부 루프 코드는 결코 액세스되지 않습니다. 즉, (내부) 루프의 while 조건이 참이 아니라는 의미입니다. 즉 호출이 실패합니다. 여기EnumDisplayDevices 함수가 작동하지 않습니다.

내 문제는 Windows API는이 기능에 대해 말한다이다 :

은 디스플레이 모니터에 NULL로 설정 lpDevice와 먼저 통화 EnumDisplayDevices을> 정보를 얻으려면. 그런 다음 첫 번째 호출에서 EnumDisplayDevices로, iDevNum을 0으로 설정하여 lpDevice를 DISPLAY_DEVICE.DeviceName>으로 설정하여 EnumDisplayDevices를 호출합니다. 그런 다음> DISPLAY_DEVICE.DeviceString은 모니터 이름입니다.

... 정확히 말한 후에도 두 번째 EnumDisplayDevices 호출은 항상 실패합니까? 어떤 통찰력 ???

또한 저는 Windows XP 및 Windows 7에서 서비스 수준 응용 프로그램으로이 작업을 수행하고 동일한 결과를 얻습니다. 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++; 
    } 

답변

9

입력 문자열에 'dd'멤버를 사용하는 중에 'dd'를 내부 호출에 전달하는 중입니다. 나는 이것이 의미가 없다는 것을 안다. 그러나 dd가 out 매개 변수이기 때문에 API가 그것에 쓰고 있다고 생각한다. 그러나 입력 매개 변수의 내용을 그 위에 적었을 때 그것을보고있다. 이것은 정상적으로 실행하기 전에 출력 parm을 0으로 memset하는 것과 같은 일을하는 경우에 발생할 수 있습니다.

그냥 비어 있지 않은 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: %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; 
} 

나는에있어 상자는 현재 단 1 개 모니터를 가지고, 그래서 나는 내부 루프를 확인할 수 없습니다,하지만 난 'newdd'는 전화로 별명이 결코 극복 이후 괜찮아요 생각한다. 또한 서비스 컨텍스트에 있다고 말하면 - 윈 스테이션 스테이션이 디스플레이에 대해 보는 것을 제한 할 것인지 확신 할 수 없기 때문에 문제가 될 수 있습니다. 하지만 적어도 당신은 적어도 물리적 장치를 볼 수 있어야한다고 생각합니다. 내 컴퓨터에 나는 얻을 : 특별히 Win7에 대한 나중에 코딩하는 경우

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 
+0

나는 방금 같은 것을 많이 끝냈다. 앨리어싱이 문제입니다. – arx

+0

코드를 게시 한 이후로 변경된 사항인지 잘 모르겠지만 MSVC2015에서 DeviceName, DeviceString 등이 WCHAR 배열이므로 % s 대신 % S를 사용해야한다는 것을 알았습니다./0 두 번째 문자마다 데이터. – scone

관련 문제