我需要从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"