CreateDC返回错误1801

时间:2016-08-17 09:27:50

标签: c++ winapi driver mirror

我需要从MS Mirror驱动程序接收屏幕截图,但我注意到, CreateDC()函数返回 NULL 并且 GetLastError 给了我错误#1801(“打印机名称无效”)

extern "C" __declspec(dllexport) HDC InitDC() {
    DWORD dwAttach = 0;
    DEVMODE devmode;

    // Make sure we have a display on this thread.
    BOOL change = EnumDisplaySettings(NULL,
        ENUM_CURRENT_SETTINGS,
        &devmode);
    LPCWSTR driverName = L"Microsoft Mirror Driver";

    devmode.dmFields = DM_BITSPERPEL |
        DM_PELSWIDTH | 
        DM_PELSHEIGHT |
        DM_POSITION ;
    devmode.dmSize = sizeof(DEVMODE);
    devmode.dmDriverExtra = 0;

    if (change) 
    {
        // query all display devices in the system until we hit a primary
        // display device. Using it get the width and height of the primary
        // so we can use that for the mirror driver. Also enumerate the
        // display devices installed on this machine untill we hit
        // our favourate mirrored driver, then extract the device name string
        // of the format '\\.\DISPLAY#'

        DISPLAY_DEVICE dispDevice;

        FillMemory(&dispDevice, sizeof(DISPLAY_DEVICE), 0);

        dispDevice.cb = sizeof(DISPLAY_DEVICE);

        LPCWSTR deviceName = NULL;

        devmode.dmDeviceName[0] = '\0';

        INT devNum = 0;
        BOOL result;
        DWORD cxPrimary = 0xFFFFFFFF;
        DWORD cyPrimary = 0xFFFFFFFF;

        // First enumerate for Primary display device:
        while ((result = EnumDisplayDevices(NULL,
            devNum,
            &dispDevice,
            0)) == TRUE)
        {
            wcout << "DriverName: " << dispDevice.DeviceString << endl;
            wcout << "DevName: " << dispDevice.DeviceName << endl;

            if (dispDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
            {
                // Primary device. Find out its dmPelsWidht and dmPelsHeight.
                EnumDisplaySettings(dispDevice.DeviceName,
                    ENUM_CURRENT_SETTINGS,
                    &devmode);      
                cxPrimary = devmode.dmPelsWidth;
                cyPrimary = devmode.dmPelsHeight;

                wcout << "Selected Primary DevName (width, height): " << dispDevice.DeviceName << " (" << cxPrimary << "," << cyPrimary << ")" << endl << endl;
                break;
            }
            devNum++;
        }

        // error check
        if (!result)
        {
            wcout << "No " << driverName << " found " << endl;
            exit(0);
        }

        if (cxPrimary == 0xffffffff || cyPrimary == 0xffffffff)
        {
            wcout << "cxPrimary or cyPrimary not valid" << endl;
            exit(0);
        }

        // Enumerate again for the mirror driver:
        devNum = 0;
        while ((result = EnumDisplayDevices(NULL,
            devNum,
            &dispDevice,
            0)) == TRUE)
        {
            LPCWSTR devString = dispDevice.DeviceString;

            wcout << " devString: "<< devString << endl; 

            if (wcscmp(devString, driverName ) == 0) {
                wcout << " Driver selected: "<< driverName << endl;             
                break;
            }

            devNum++;
        }

        // error check       
        if (!result)
        {
            wcout << "No " << driverName << " found " << endl;
            exit(0);
        }

        wcout << "DevNum " << devNum << endl <<
            "DeviceName: " << dispDevice.DeviceName << endl <<
            "DeviceString: " << dispDevice.DeviceString << endl <<
            "DeviceID: " << dispDevice.DeviceID << endl <<
            "DeviceKey: " << dispDevice.DeviceKey << endl;

        CHAR *deviceNum = new CHAR[MAX_PATH];
        LPSTR deviceSub;

        // Simply extract 'DEVICE#' from registry key.  This will depend
        // on how many mirrored devices your driver has and which ones
        // you intend to use.
        _wcsupr(&dispDevice.DeviceKey[0]);

        deviceSub = (LPSTR)(wcsstr(&dispDevice.DeviceKey[0],
                           L"\\DEVICE"));

        if (!deviceSub) {
            printf("deviceSub - yes \n"); 
            deviceNum[0] = (CHAR)(((string)("DEVICE0")).c_str());
        }
        else {
            printf("!deviceSub \n"); 
            deviceNum[0] = (CHAR)(((string)("DEVICE1")).c_str());
        }
        // Reset the devmode for mirror driver use:
        FillMemory(&devmode, sizeof(DEVMODE), 0);
        devmode.dmSize = sizeof(DEVMODE);
        devmode.dmDriverExtra = 0;

        devmode.dmFields = DM_BITSPERPEL |
                           DM_PELSWIDTH | 
                           DM_PELSHEIGHT |
                           DM_POSITION;

        //wcscpy( devmode.dmDeviceName, sizeof(devmode.dmDeviceName, L"mirror" );
        deviceName = dispDevice.DeviceName;
        StringCbCopy(devmode.dmDeviceName, sizeof(devmode.dmDeviceName), dispDevice.DeviceName);

        wcout << "dmDeviceName: " << devmode.dmDeviceName << endl;
        wcout << "deviceName: " << deviceName << endl;
        wcout << "driverName: " << driverName << endl;

        /* !!! THE PROBLEM IS HERE !!!*/
        HDC hdc = CreateDC(driverName, deviceName, NULL, &devmode );

        if ( hdc == NULL ) {
            wcout << "CreateDC error: " << GetLastError() << endl;
            return NULL;
        }

        return hdc;
    }

    return NULL;
}

感谢您的帮助!

UPD1:

deviceName = "\\.\DISPLAYV1"
driverName = "Microsoft Mirror Driver"
devmode.dmDeviceName = "\\.\DISPLAYV1"

0 个答案:

没有答案