MultiMonitor.cpp
上传用户:maidou0901
上传日期:2008-10-19
资源大小:68k
文件大小:5k
源码类别:

多显示器编程

开发平台:

Visual C++

  1. // Monitor.cpp : implementation file
  2. //
  3. //////////////////////////////////////////////////
  4. // CMonitor - wrapper to Win32 multi-monitor API
  5. //
  6. // Author: Donald Kackman
  7. // Email:  don@itsEngineering.com
  8. // Copyright 2002, Donald Kackman
  9. //
  10. // You may freely use or modify this code provided this
  11. // Copyright is included in all derived versions.
  12. //
  13. ///////////////////////////////////////////////////
  14. #include "stdafx.h"
  15. #include "MultiMonitor.h"
  16. #include "Monitors.h"
  17. // CMonitor
  18. // constucts a monitor class not attached to any handle
  19. CMonitor::CMonitor() : m_hMonitor( NULL )
  20. {
  21. }
  22. // copy constructor
  23. CMonitor::CMonitor( const CMonitor& monitor  )
  24. {
  25. m_hMonitor = (HMONITOR)monitor;
  26. }
  27. CMonitor::~CMonitor()
  28. {
  29. }
  30. void CMonitor::Attach( const HMONITOR hMonitor )
  31. {
  32. ASSERT( CMonitors::IsMonitor( hMonitor ) );
  33. m_hMonitor = hMonitor;
  34. }
  35. HMONITOR CMonitor::Detach() 
  36. {
  37. HMONITOR hMonitor = m_hMonitor;
  38. m_hMonitor = NULL;
  39. return hMonitor;
  40. }
  41. // creates an HDC for the monitor
  42. // it is up to the client to call DeleteDC
  43. //
  44. // for normal multimonitor drawing it is not necessary to get a
  45. // dc for each monitor. Windows takes care of drawing correctly
  46. // on all monitors
  47. //
  48. // Only very exacting applications would need a DC for each monitor
  49. HDC CMonitor::CreateDC() const
  50. {
  51. ASSERT( IsMonitor() );
  52. CString name;
  53. GetName( name );
  54. //create a dc for this display
  55. HDC hdc = ::CreateDC( name, name, NULL, NULL );
  56. ASSERT( hdc != NULL );
  57. //set the viewport based on the monitor rect's relation to the primary monitor
  58. CRect rect;
  59. GetMonitorRect( &rect );
  60. ::SetViewportOrgEx( hdc, -rect.left, -rect.top, NULL );
  61. ::SetViewportExtEx( hdc, rect.Width(), rect.Height(), NULL );
  62. return hdc;
  63. }
  64. int CMonitor::GetBitsPerPixel() const
  65. {
  66. HDC hdc = CreateDC();
  67. int ret = ::GetDeviceCaps( hdc, BITSPIXEL ) * ::GetDeviceCaps( hdc, PLANES );
  68. VERIFY( ::DeleteDC( hdc ) );
  69. return ret;
  70. }
  71. void CMonitor::GetName( CString& string ) const
  72. {
  73. ASSERT( IsMonitor() );
  74. MONITORINFOEX mi;
  75. mi.cbSize = sizeof( mi );
  76. ::GetMonitorInfo( m_hMonitor, &mi );
  77. string = mi.szDevice;
  78. }
  79. //
  80. // these methods return true if any part of the item intersects the monitor rect
  81. BOOL CMonitor::IsOnMonitor( const POINT pt ) const
  82. {
  83. CRect rect;
  84. GetMonitorRect( rect );
  85. return rect.PtInRect( pt );
  86. }
  87. BOOL CMonitor::IsOnMonitor( const CWnd* pWnd ) const
  88. {
  89. CRect rect;
  90. GetMonitorRect( rect );
  91. ASSERT( ::IsWindow( pWnd->GetSafeHwnd() ) );
  92. CRect wndRect;
  93. pWnd->GetWindowRect( &wndRect );
  94. return rect.IntersectRect( rect, wndRect );
  95. }
  96. BOOL CMonitor::IsOnMonitor( const LPRECT lprc ) const
  97. {
  98. CRect rect;
  99. GetMonitorRect( rect );
  100. return rect.IntersectRect( rect, lprc );
  101. }
  102. void CMonitor::GetMonitorRect( LPRECT lprc ) const
  103. {
  104. ASSERT( IsMonitor() );
  105. MONITORINFO mi;
  106.     RECT        rc;
  107. mi.cbSize = sizeof( mi );
  108. ::GetMonitorInfo( m_hMonitor, &mi );
  109. rc = mi.rcMonitor;
  110. ::SetRect( lprc, rc.left, rc.top, rc.right, rc.bottom );
  111. }
  112. //
  113. // the work area does not include the start bar
  114. void CMonitor::GetWorkAreaRect( LPRECT lprc ) const
  115. {
  116. ASSERT( IsMonitor() );
  117. MONITORINFO mi;
  118.     RECT        rc;
  119. mi.cbSize = sizeof( mi );
  120. ::GetMonitorInfo( m_hMonitor, &mi );
  121. rc = mi.rcWork;
  122. ::SetRect( lprc, rc.left, rc.top, rc.right, rc.bottom );
  123. }
  124. //these two center methods are adapted from David Campbell's
  125. //MSJ article (see comment at the top of the header file)
  126. void CMonitor::CenterRectToMonitor( LPRECT lprc, const BOOL UseWorkAreaRect ) const
  127. {
  128.     int  w = lprc->right - lprc->left;
  129.     int  h = lprc->bottom - lprc->top;
  130.     CRect rect;
  131.     if ( UseWorkAreaRect )
  132.         GetWorkAreaRect( &rect );
  133.     else
  134.         GetMonitorRect( &rect );
  135.     lprc->left = rect.left + ( rect.Width() - w ) / 2;
  136.     lprc->top = rect.top + ( rect.Height() - h ) / 2;
  137.     lprc->right = lprc->left + w;
  138.     lprc->bottom = lprc->top + h;
  139. }
  140. void CMonitor::CenterWindowToMonitor( CWnd* const pWnd, const BOOL UseWorkAreaRect ) const
  141. {
  142. ASSERT( IsMonitor() );
  143. ASSERT( pWnd );
  144. ASSERT( ::IsWindow( pWnd->m_hWnd ) );
  145. CRect rect;
  146.     pWnd->GetWindowRect( &rect );
  147.     CenterRectToMonitor( &rect, UseWorkAreaRect );
  148.     pWnd->SetWindowPos( NULL, rect.left, rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
  149. }
  150. void CMonitor::ClipRectToMonitor( LPRECT lprc, const BOOL UseWorkAreaRect ) const
  151. {
  152.     int w = lprc->right - lprc->left;
  153.     int h = lprc->bottom - lprc->top;
  154.     CRect rect;
  155.     if ( UseWorkAreaRect )
  156.         GetWorkAreaRect( &rect );
  157.     else
  158.         GetMonitorRect( &rect );
  159.     lprc->left = max( rect.left, min( rect.right - w, lprc->left ) );
  160.     lprc->top = max( rect.top, min( rect.bottom - h, lprc->top ) );
  161.     lprc->right = lprc->left + w;
  162.     lprc->bottom = lprc->top  + h;
  163. }
  164. //
  165. // is the instance the primary monitor
  166. BOOL CMonitor::IsPrimaryMonitor() const
  167. {
  168. ASSERT( IsMonitor() );
  169. MONITORINFO mi;
  170. mi.cbSize = sizeof( mi );
  171. ::GetMonitorInfo( m_hMonitor, &mi );
  172. return mi.dwFlags == MONITORINFOF_PRIMARY;
  173. }
  174. //
  175. // is the instance currently attached to a valid monitor handle
  176. BOOL CMonitor::IsMonitor() const 
  177. {
  178. return CMonitors::IsMonitor( m_hMonitor );
  179. }