|
// Monitor.h : implementation of the CMonitor class
//
/////////////////////////////////////////////////////////////////////////////
// David Campbell's article "How to Exploit Multiple Monitor Support in Memphis and Windows NT 5.0"
// is very helpful for multimonitor api calls
// http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0697/monitor/monitor.htm&nav=/msj/0697/newnav.htm
// Author: Donald Kackman
// Email: don@itsEngineering.com
// Copyright 2002, Donald Kackman
// You may freely use or modify this code provided this copyright is included in all derived versions.
//
// Ported to WTL by Igor Vigdorchik
#include "stdafx.h"
#include "Monitor.h"
#include "Monitors.h"
CMonitor::CMonitor() : m_hMonitor(NULL) {}
CMonitor::CMonitor(const CMonitor& monitor)
{
m_hMonitor = (HMONITOR)monitor;
}
void CMonitor::Attach(const HMONITOR hMonitor)
{
ATLASSERT(CMonitors::IsMonitor(hMonitor));
m_hMonitor = hMonitor;
}
HMONITOR CMonitor::Detach()
{
HMONITOR hMonitor = m_hMonitor;
m_hMonitor = NULL;
return hMonitor;
}
// Creates an HDC for the monitor, it is up to the client to call DeleteDC.
// For normal multimonitor drawing it is not necessary to get a dc for each monitor.
// Windows takes care of drawing correctly on all monitors, only very exacting applications would need a DC for each monitor
HDC CMonitor::CreateDC() const
{
ATLASSERT(IsMonitor());
CString name;
GetName(name);
// Create a dc for this display
HDC hdc = ::CreateDC(name, name, NULL, NULL);
ATLASSERT(hdc != NULL);
// Set the viewport based on the monitor rect's relation to the primary monitor
CRect rect;
GetMonitorRect(&rect);
::SetViewportOrgEx(hdc, -rect.left, -rect.top, NULL);
::SetViewportExtEx(hdc, rect.Width(), rect.Height(), NULL);
return hdc;
}
void CMonitor::ClipRectToMonitor(LPRECT lprc, const BOOL bUseWorkAreaRect) const
{
// The work area is the monitor rect minus the start bar
int w = lprc->right - lprc->left;
int h = lprc->bottom - lprc->top;
CRect rect;
if (bUseWorkAreaRect)
GetWorkAreaRect(&rect);
else
GetMonitorRect(&rect);
lprc->left = max(rect.left, min(rect.right - w, lprc->left));
lprc->top = max(rect.top, min(rect.bottom - h, lprc->top));
lprc->right = lprc->left + w;
lprc->bottom = lprc->top + h;
}
// These two center methods are adapted from David Campbell's MSJ article (see comment at the top of the header file)
void CMonitor::CenterRectToMonitor(LPRECT lprc, const BOOL bUseWorkAreaRect) const
{
// The work area is the monitor rect minus the start bar
int w = lprc->right - lprc->left;
int h = lprc->bottom - lprc->top;
CRect rect;
if (bUseWorkAreaRect)
GetWorkAreaRect(&rect);
else
GetMonitorRect(&rect);
lprc->left = rect.left + (rect.Width() - w ) / 2;
lprc->top = rect.top + (rect.Height() - h ) / 2;
lprc->right = lprc->left + w;
lprc->bottom = lprc->top + h;
}
void CMonitor::CenterWindowToMonitor(CWindow* const pWnd, const BOOL bUseWorkAreaRect) const
{
// The work area is the monitor rect minus the start bar
ATLASSERT(IsMonitor());
ATLASSERT(pWnd);
ATLASSERT(::IsWindow(pWnd->m_hWnd));
CRect rect;
pWnd->GetWindowRect(&rect);
CenterRectToMonitor(&rect, bUseWorkAreaRect);
pWnd->SetWindowPos(NULL, rect.left, rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}
void CMonitor::GetMonitorRect(LPRECT lprc) const
{
ATLASSERT(IsMonitor());
MONITORINFO mi;
RECT rc;
mi.cbSize = sizeof(mi);
::GetMonitorInfo(m_hMonitor, &mi);
rc = mi.rcMonitor;
::SetRect(lprc, rc.left, rc.top, rc.right, rc.bottom);
}
void CMonitor::GetWorkAreaRect(LPRECT lprc) const
{
ATLASSERT(IsMonitor());
MONITORINFO mi;
RECT rc;
mi.cbSize = sizeof(mi);
::GetMonitorInfo(m_hMonitor, &mi);
rc = mi.rcWork;
::SetRect(lprc, rc.left, rc.top, rc.right, rc.bottom);
}
void CMonitor::GetName(CString& string) const
{
ATLASSERT(IsMonitor());
MONITORINFOEX mi;
mi.cbSize = sizeof(mi);
::GetMonitorInfo(m_hMonitor, &mi);
string = mi.szDevice;
}
int CMonitor::GetBitsPerPixel() const
{
HDC hdc = CreateDC();
int ret = ::GetDeviceCaps(hdc, BITSPIXEL) * ::GetDeviceCaps(hdc, PLANES);
::DeleteDC(hdc);
return ret;
}
// Determines if the specified item on the monitor, these methods return true
// if any part of the item intersects the monitor rect
BOOL CMonitor::IsOnMonitor(const POINT pt) const
{
CRect rect;
GetMonitorRect(rect);
return rect.PtInRect(pt);
}
BOOL CMonitor::IsOnMonitor(const CWindow* pWnd) const
{
CRect rect;
GetMonitorRect(rect);
ATLASSERT(::IsWindow(pWnd->m_hWnd));
CRect wndRect;
pWnd->GetWindowRect(&wndRect);
return rect.IntersectRect(rect, wndRect);
}
BOOL CMonitor::IsOnMonitor(const LPRECT lprc) const
{
CRect rect;
GetMonitorRect(rect);
return rect.IntersectRect(rect, lprc);
}
// Is the instance the primary monitor
BOOL CMonitor::IsPrimaryMonitor() const
{
ATLASSERT(IsMonitor());
MONITORINFO mi;
mi.cbSize = sizeof(mi);
::GetMonitorInfo(m_hMonitor, &mi);
return mi.dwFlags == MONITORINFOF_PRIMARY;
}
// Is the instance currently attached to a valid monitor handle
BOOL CMonitor::IsMonitor() const
{
return CMonitors::IsMonitor(m_hMonitor);
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.