UltraMon™ multi-monitor components
Low-level multi-monitor programming can be difficult: API differences between Win9x and NT-based platforms, undocumented features. And the only available API is intended for C programmers, making it even more difficult for Visual Basic developers, and unusable for scripting.
That's where the UltraMon™ multi-monitor components come in: COM components compatible with most programming languages, providing a single multi-monitor API on all platforms.
In the following paragraphs I'll show you how you can use UltraMon components from VBScript, Visual Basic and C++. For more samples and complete documentation, download the UltraMon SDK. The source code for the samples below is also included in the SDK.
Requirements
UltraMon
VBScript
I love scripting, so let's begin with that. The following code displays information about each installed monitor.
Const REFRATE_DEFAULT = 0
Const REFRATE_OPTIMAL = -1
Set sys = CreateObject("UltraMon.System")
For Each mon In sys.Monitors
msg = msg & "Monitor " & mon.ID & ": " & mon.Name & vbNewline
msg = msg & "Video card: " & mon.AdapterName & vbNewline
If mon.Enabled = True Then
'refresh rate can be in Hz or one of the values from the REFRATE enumeration
Select Case mon.RefreshRate
Case REFRATE_DEFAULT
refRate = "default refresh rate"
Case REFRATE_OPTIMAL
refRate = "optimal refresh rate"
Case Else
refRate = mon.RefreshRate & " Hz"
End Select
msg = msg & "Display mode: " & mon.Width & "x" & mon.Height & " " & mon.Colordepth & "-bit " & refRate & vbNewline
msg = msg & "Position: " & mon.Left & "," & mon.Top & vbNewline & vbNewline
Else
msg = msg & "(disabled)" & vbNewline & vbNewline
End If
Next
MsgBox msg, vbOKOnly, "System information"
Visual Basic
You could use pretty much the same code as for VBScript, but you can take advantage of early binding for improved performance:
Dim sys As New UltraMonSystem
instead of
Dim sys
Set sys = CreateObject("UltraMon.System")
And of course you don't need to define the constants manually, simply referencing the UltraMon 2.0 type library is enough.
C++
Here is the same sample in C++. ComString is a BSTR wrapper, which makes handling the strings used by UltraMon a lot simpler. ComString is included in the SDK.
// initialize COM
CoInitializeEx(0, COINIT_APARTMENTTHREADED);
// create the UltraMon System object
IUltraMonSystem* pSys = 0;
CoCreateInstance(CLSID_UltraMonSystem, 0, CLSCTX_ALL, IID_IUltraMonSystem,
reinterpret_cast<void**>(&pSys));
// get a pointer to the monitor collection, and determine the number of installed monitors
IUltraMonMonitors* pMonitors = 0;
pSys->get_Monitors(&pMonitors);
long numMonitors = 0;
pMonitors->get_Count(&numMonitors);
// allocate a string buffer to hold the system information
// we assume that there will never be more than 1000 characters per monitor
TCHAR* buf = new TCHAR[numMonitors * 1000];
*buf = _T('\0');
// enumerate all monitors, and get information about each one
VARIANT vt;
vt.vt = VT_I4;
for (int i = 0; i < numMonitors; ++i)
{
// get a pointer to the monitor
IUltraMonMonitor* pMonitor = 0;
vt.lVal = i;
pMonitors->Item(vt, &pMonitor);
// format the information about this monitor
TCHAR monInfo[1000] = _T("");
// monitor name
ComString str;
pMonitor->get_Name(&str);
wsprintf(monInfo, _T("Monitor %d: %s\r\n"), i + 1, static_cast<TCHAR*>(str));
lstrcat(buf, monInfo);
// video card name
pMonitor->get_AdapterName(&str);
wsprintf(monInfo, _T("Video card: %s\r\n"), static_cast<TCHAR*>(str));
lstrcat(buf, monInfo);
// check if the monitor is enabled
VARIANT_BOOL enabled;
pMonitor->get_Enabled(&enabled);
if (enabled == VARIANT_TRUE)
{
// the monitor is enabled
// display mode
long width, height;
short colordepth;
pMonitor->get_Width(&width);
pMonitor->get_Height(&height);
pMonitor->get_Colordepth(&colordepth);
// refresh rate can be in Hz, or one of the values from the REFRATE enumeration
short refreshRate;
TCHAR refreshRateStr[50] = _T("");
pMonitor->get_RefreshRate(&refreshRate);
switch (refreshRate)
{
case REFRATE_DEFAULT:
lstrcpy(refreshRateStr, _T("default refresh rate"));
break;
case REFRATE_OPTIMAL:
lstrcpy(refreshRateStr, _T("optimal refresh rate"));
break;
default:
wsprintf(refreshRateStr, _T("%d Hz"), refreshRate);
}
wsprintf(monInfo, _T("Display mode: %dx%d %d-bit %s\r\n"), width, height, colordepth,
refreshRateStr);
lstrcat(buf, monInfo);
// position
long left, top;
pMonitor->get_Left(&left);
pMonitor->get_Top(&top);
wsprintf(monInfo, _T("Position: %d,%d\r\n\r\n"), left, top);
lstrcat(buf, monInfo);
}
else
{
// the monitor is disabled
lstrcat(buf, _T("(disabled)\r\n\r\n"));
}
pMonitor->Release();
}
// display message box
MessageBox(0, buf, _T("System information"), MB_OK);
// release resources
delete [] buf;
pMonitors->Release();
pSys->Release();
// uninitialize COM
CoUninitialize();
Other features
Besides getting information about a system's multi-monitor configuration, you can also
- change monitor settings like resolution, colordepth, refresh rate and position
- enable and disable monitors
- change the primary monitor (Windows 2000/XP only)
- save/restore position of windows, desktop icons and Active Desktop items
- get and set various window properties
- move windows to a different monitor
- maximize windows to the desktop
More information
For complete documentation and more samples, download the software development kit. If you have any questions about programming with UltraMon, post them to the UltraMon SDK forum.
|