Here is what I have tried.
I can enumerate the display devices using
DISPLAY_DEVICE dd;
DISPLAY_DEVICE ddMon;
DWORD device = 0;
POINT pt;
while (EnumDisplayDevice(0, device, &dd, 0) )
{// Get each display device in turn
// Ignore Mirror drivers
if (!(dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
{ // Get each monitor attached to the display device in turn
while (EnumDisplayDevices(dd.DeviceName, devMon, &ddMon, 0))
{ // Only worry about the active monitor
if (ddMon.StateFlags & DISPLAY_DEVICE_ACTIVE)
break;
devMon++;
}
if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
{ //These monitors are part of the desktop
pt = dm.dmPosition.x, dm.dmPosition.y };
hm = MonitorFromPoint (pt,MONITOR_DEVAULTTONULL);
} // I can use MonitorFromXXX as above to get an hdc to draw on
// any part of the desktop
else
{ // how do I get the hm or hdc of the Monitors that are not
// part of the desktop?
// I tried the following four combinations but hdc comes back
// NULL.
hdc = CreateDC(ddMon.DeviceName, NULL, NULL, NULL );
hdc = CreateDC(ddMon.DeviceName, NULL, NULL, &dm );
hdc = CreateDC(dd.DeviceName, NULL, NULL, NULL );
hdc = CreateDC(dd.DeviceName, NULL, NULL, &dm );
When I try GetLastError, the translation is usually "Invalid Printer Name".
What am I doing wrong?
Thanks in advance,
Marc Reinig
UCO Lick, LAO
do {
DISPLAY_DEVICE disp;
disp.cb = sizeof( DISPLAY_DEVICE );
bRet = EnumDisplayDevices(NULL,dwNum,&disp,0);
if( bRet)
dispVec.push_back(disp);
dwNum++;
} while(bRet);
vector<DISPLAY_DEVICE>::iterator it = dispVec.begin();
vector<DISPLAY_DEVICE>::iterator it_end = dispVec.end();
cout<<endl<<"* * * * * * Enumerate Monitor Devices * * * * * *"<<endl;
for ( ; it != it_end ; it++ )
{
cout<<"*********************************************************************
****"<<endl;
cout<<"DeviceName:\t" <<(*it).DeviceName << endl;
cout<< "DeviceString:\t"<<(*it).DeviceString << endl;
cout<<"StateFlag:\t"<<hex<<(*it).StateFlags<<endl;
cout<<"DeviceID:\t" <<(*it).DeviceID<<endl;
// code to obtain the monitor name
DISPLAY_DEVICE monInfo;
monInfo.cb = sizeof( DISPLAY_DEVICE );
if (EnumDisplayDevices(dispVec[0].DeviceName,0,&monInfo,0))
{
cout<< "Monitor name is :"<< monInfo.DeviceString <<endl;
}
cout<<"*********************************************************************
****"<<endl;
}
//.......Cleanup ...
}
//--------------------------------------------------------------------------
-------
Best regards,
Rhett Gong [MSFT]
Microsoft Online Partner Support
This posting is provided "AS IS" with no warranties, and confers no rights.
Please reply to newsgroups only. Thanks.
Thanks for responding.
The output from your program is at the end.
I would like to draw or display images on \\.DISPLAY2 or \\.DISPLAY3.
Currently, \\.DISPLAY2 does not have a monitor attached, but that is easily
fixed.
Neither \\.DISPLAY2 nor \\.DISPLAY3 are part of my desktop. I just want to
use them as independent output devices. I don't want the mouse there, or
any desktop items.
Thanks in advance,
Marc Reinig
UCO/Lick
Laboratory for Adaptive Optics
* * * * * * Enumerate Monitor Devices * * * * * *
********************************************************************
DeviceName: \\.\DISPLAY1
DeviceString: NVIDIA Quadro NVS with AGP8X (Microsoft Corporation)
StateFlag: 8000005
DeviceID: PCI\VEN_10DE&DEV_018A&SUBSYS_019010DE&REV_C1
Monitor name is :Default Monitor
********************************************************************
********************************************************************
DeviceName: \\.\DISPLAY2
DeviceString: Matrox Millennium G400 - English
StateFlag: 0
DeviceID: PCI\VEN_102B&DEV_0525&SUBSYS_41E0102B&REV_05
Monitor name is :Default Monitor
********************************************************************
********************************************************************
DeviceName: \\.\DISPLAY3
DeviceString: NVIDIA Quadro NVS with AGP8X (Microsoft Corporation)
StateFlag: 8000001
DeviceID: PCI\VEN_10DE&DEV_018A&SUBSYS_019010DE&REV_C1
Monitor name is :Default Monitor
********************************************************************
********************************************************************
DeviceName: \\.\DISPLAYV1
DeviceString: NetMeeting driver
StateFlag: 8
DeviceID:
Monitor name is :Default Monitor
********************************************************************
********************************************************************
DeviceName: \\.\DISPLAYV2
DeviceString: RDPDD Chained DD
StateFlag: 8
DeviceID:
Monitor name is :Default Monitor
********************************************************************
Since it will take some time for me to get a second display device for a
test, I suggest you try followings line to see if the dc could be properly
created.
hDC = CreateDC("DISPLAY", ddMon.DeviceName/*or dd.DeviceName*/, NULL, NULL);
Please let me know what you get when applying this line on Display2 and
Display3.
Thanks,
using your original code, I add
if (EnumDisplayDevices(dispVec[0].DeviceName,0,&monInfo,0))
{
cout<< "Monitor name is :"<< monInfo.DeviceString <<endl;
// Now try and get an hDC
hDC_mon = CreateDC("DISPLAY", monInfo.DeviceString, NULL, NULL);
if ( hDC_mon != 0 )
{ // Got it
printf ( "hDC_mon = %X\n", hDC_mon );
// draws box in the upper left corner
bool result = Rectangle(hDC_mon,10,10,100,100);
if (result)
printf ( "Success!\n" );
else
printf ( "Failure!\n" );
}
else // Argh!
printf ( "hDC_dev = NULL\n" );
}
and I get an hDC for each monitor, Yea!.
What I see is that Rectangle() draws a small box in the upper left corner of
my desktop for that hDC so I know I am getting a correct hDC (at least for
that monitor). However, my monitors for the independent displays are still
not enabled so I can't see if I am drawing on them.
So, now that I can get an hDC for the independent monitors (I hope), how do
I enable them (i.e. have the video cards send them video), so I can see if I
can draw on them?
Note: If I go to the "Display Properties / Settings Tab", and make them
part of the desktop, they work fine, but when I remove them from the desktop
they go black.
So there must be some sequence to enable them I am missing.
Best regards,
I need do some tests on my thought. I will update you later. Thanks.
Best regards,
This produces the output below. It draws a white box in the upper left of
any of the monitors that are part of the desk top. in this case only
Display1 was on the desktop.
But, if a monitor is not on the desktop, it still doesn't draw on it and it
is still suspended, i.e. power is applied, but the indicator lights indicate
they are not receiving any video and the screen is black.
Thanks,
Marco
* * * * * * Enumerating Monitor Devices * * * * * *
****************************************************
DeviceName: \\.\DISPLAY1
DeviceString: NVIDIA Quadro NVS with AGP8X (Microsoft Corporation)
StateFlag: 8000005
DeviceID: PCI\VEN_10DE&DEV_018A&SUBSYS_019010DE&REV_C1
Using current Graphics modes
Resolution and refresh rate:
1280 x 1024 @ 0, 0 - 32-bit - 60 Hz
Monitor name is :Default Monitor
hDC_mon = 4E010E51
Rect Success!
****************************************************
****************************************************
DeviceName: \\.\DISPLAY2
DeviceString: Matrox Millennium G400 - English
StateFlag: 0
DeviceID: PCI\VEN_102B&DEV_0525&SUBSYS_41E0102B&REV_05
There are no current Graphics modes
Using Graphics modes in the registry
Resolution and refresh rate:
0 x 0 @ 0, 0 - 0-bit - 0 Hz
Monitor name is :Default Monitor
hDC_mon = 700108A3
Rect Success!
****************************************************
****************************************************
DeviceName: \\.\DISPLAY3
DeviceString: NVIDIA Quadro NVS with AGP8X (Microsoft Corporation)
StateFlag: 8000000
DeviceID: PCI\VEN_10DE&DEV_018A&SUBSYS_019010DE&REV_C1
There are no current Graphics modes
Using Graphics modes in the registry
Resolution and refresh rate:
1280 x 1024 @ 1280, 0 - 32-bit - 75 Hz
Monitor name is :Default Monitor
hDC_mon = 39010362
Rect Success!
****************************************************
****************************************************
DeviceName: \\.\DISPLAYV1
DeviceString: NetMeeting driver
StateFlag: 8
DeviceID:
There are no current Graphics modes
Using Graphics modes in the registry
Resolution and refresh rate:
800 x 600 @ 0, 0 - 16-bit - 75 Hz
****************************************************
****************************************************
DeviceName: \\.\DISPLAYV2
DeviceString: RDPDD Chained DD
StateFlag: 8
DeviceID:
There are no current Graphics modes
Using Graphics modes in the registry
Resolution and refresh rate:
800 x 600 @ 0, 0 - 16-bit - 75 Hz
****************************************************
Below is the current state of my code:
// MS_TEST.cpp
#include "stdafx.h"
#include <windows.h>
#include <vector>
using namespace std;
int
_tmain(int argc, _TCHAR* argv[])
{
DISPLAY_DEVICE disp;
DEVMODE dm;
BOOL result;
BOOL bRet = FALSE;
DWORD dwNum =0;
vector< DISPLAY_DEVICE> dispVec;
HDC hDC_dev = NULL;
HDC hDC_mon = NULL;
do
{ // find all the display devices and add them to a vector
disp.cb = sizeof( DISPLAY_DEVICE );
bRet = EnumDisplayDevices(NULL,dwNum,&disp,0);
if( bRet)
dispVec.push_back(disp); // add another element to the vector
dwNum++;
} while(bRet);
vector<DISPLAY_DEVICE>::iterator it = dispVec.begin();
vector<DISPLAY_DEVICE>::iterator it_end = dispVec.end();
cout<<endl<<"* * * * * * Enumerating Monitor Devices * * * * * *\n"<<endl;
for ( ; it != it_end ; it++ )
{
cout<<"****************************************************"<<endl;
cout<<"DeviceName:\t" <<(*it).DeviceName << endl;
cout<<" DeviceString:\t"<<(*it).DeviceString << endl;
cout<<" StateFlag:\t"<<hex<<(*it).StateFlags<<endl;
cout<<" DeviceID:\t" <<(*it).DeviceID<<endl;
// get information about the display's position and the current display
mode
ZeroMemory ( &dm, sizeof(dm) );
dm.dmSize = sizeof(dm);
if ( EnumDisplaySettingsEx ( (*it).DeviceName, ENUM_CURRENT_SETTINGS, &dm,
0 ) == FALSE )
{
printf ( " There are no current Graphics modes\n" );
if ( EnumDisplaySettingsEx ( (*it).DeviceName, ENUM_REGISTRY_SETTINGS,
&dm, 0 ) == FALSE )
printf ( " There are no Graphics modes in the registry\n" );
else
printf ( " Using Graphics modes in the registry\n" );
}
else
{
printf ( " Using current Graphics modes\n" );
}
printf ( " Resolution and refresh rate:\n %d x %d @ %d, %d - %d-bit -
%d Hz\r\n",
dm.dmPelsWidth, dm.dmPelsHeight,
dm.dmPosition.x, dm.dmPosition.y,
dm.dmBitsPerPel, dm.dmDisplayFrequency );
// Obtain the monitor name
DISPLAY_DEVICE monInfo;
monInfo.cb = sizeof( DISPLAY_DEVICE );
if (EnumDisplayDevices((*it).DeviceName,0,&monInfo,0))
{
cout<< " Monitor name is :"<< monInfo.DeviceString <<endl;
// Now try and get an hDC for the monitor
hDC_mon = CreateDC("DISPLAY", monInfo.DeviceString, NULL, NULL);
if ( hDC_mon != 0 )
{
printf ( " hDC_mon = %X\n", hDC_mon );
// Try to draw a box on the upper left corner of each monitor
result = Rectangle ( hDC_mon, dm.dmPosition.x + 10, dm.dmPosition.y +
10,
dm.dmPosition.x + 100, dm.dmPosition.y + 100 );
if (result)
printf ( " Rect Success!\n" );
else
printf ( " Rect Failure!\n" );
}
else
printf ( " hDC_dev = NULL\n" );
}
cout<<"****************************************************"<<endl;
}
printf ("\n");
//.......Cleanup ...
//------------------------------------------------------------------------
}
In addition, here is a function to attach a monitor to the desktop. Hope it
could help you in some way.
//----------------------------------------
BOOL AddUnattachedDisplayDeviceToDesktop()
{
DWORD DispNum = 0;
DISPLAY_DEVICE DisplayDevice;
DEVMODE defaultMode;
HDC hdc;
int nWidth;
BOOL bFoundSecondary = FALSE;
hdc = GetDC(0);
nWidth = GetDeviceCaps(hdc,HORZRES);
ReleaseDC(0,hdc);
// Initialize DisplayDevice.
ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
DisplayDevice.cb = sizeof(DisplayDevice);
// Get display devices.
while ((EnumDisplayDevices(NULL, DispNum, &DisplayDevice, 0)) &&
(bFoundSecondary == FALSE))
{
ZeroMemory(&defaultMode, sizeof(DEVMODE));
defaultMode.dmSize = sizeof(DEVMODE);
if (!EnumDisplaySettings((LPSTR)DisplayDevice.DeviceName,
ENUM_REGISTRY_SETTINGS, &defaultMode))
return FALSE; // Store default failed
if (!(DisplayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE))
{
//Found the first secondary device.
bFoundSecondary = TRUE;
defaultMode.dmPosition.x += nWidth;
defaultMode.dmFields = DM_POSITION;
ChangeDisplaySettingsEx((LPSTR)DisplayDevice.DeviceName,
&defaultMode, NULL, CDS_NORESET|CDS_UPDATEREGISTRY,
NULL);
}
// Reinitialize DisplayDevice.
ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
DisplayDevice.cb = sizeof(DisplayDevice);
DispNum++;
} // End while the display devices.
return TRUE;
}
//--------------------------------------------------------------------------
-
Have a nice day,
Graphics and Multimedia
Windows GDI
Multiple Display Monitors
About Multiple Display Monitors
Using Multiple Monitors as Independent Displays
It says, "The window manager knows nothing about the independent displays.
They are completely controlled by the application, and no window manager
functions are available to the application (all window manager calls
automatically go to the primary display). Each independent display has its
own origin and horizontal and vertical coordinates, and is accessed through
the GDI functions such as CreateDC or the DirectX functions such as
DirectDrawCreate."
OK, so I can't use hWind's on them, but it says I can still access them
through GDI functions, but how?
Thanks in advance,
Marco
"Rhett Gong [MSFT]" <v-ra...@online.microsoft.com> wrote in message
news:c6goP6jl...@cpmsftngxa10.phx.gbl...
Thanks,
Arnaud
MVP - VC
Best regards,
Too bad :-(
I can't think of any good reason to such a limitation. Is that somehow
linked to the Window station/desktop management?
Arnaud
MVP - VC