DDMM.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:5k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File:       ddmm.cpp
  6.  *  Content:    Routines for using DirectDraw on a multimonitor system
  7.  *
  8.  ***************************************************************************/
  9. #define WIN32_LEAN_AND_MEAN
  10. #define WINVER 0x0400
  11. #define _WIN32_WINDOWS 0x0400
  12. #include <windows.h>
  13. #include <windowsx.h>
  14. #include <ddraw.h>
  15. #include "ddmm.h"
  16. #define COMPILE_MULTIMON_STUBS
  17. #include "multimon.h"
  18. /*
  19.  *  OneMonitorCallback
  20.  */
  21. BOOL CALLBACK OneMonitorCallback(HMONITOR hMonitor, HDC hdc, LPRECT prc, LPARAM lParam)
  22. {
  23.     HMONITOR *phMonitorFound = (HMONITOR *)lParam;
  24.     if (*phMonitorFound == 0)
  25.         *phMonitorFound = hMonitor;
  26.     else
  27.         *phMonitorFound = INVALID_HANDLE_VALUE;
  28.     return TRUE;
  29. }
  30. /*
  31.  *  OneMonitorFromWindow
  32.  *
  33.  *  similar to the Win32 function MonitorFromWindow, except
  34.  *  only returns a HMONITOR if a window is on a single monitor.
  35.  *
  36.  *  if the window handle is NULL, the primary monitor is returned
  37.  *  if the window is not visible returns NULL
  38.  *  if the window is on a single monitor returns its HMONITOR
  39.  *  if the window is on more than on monitor returns INVALID_HANDLE_VALUE
  40.  */
  41. HMONITOR OneMonitorFromWindow(HWND hwnd)
  42. {
  43.     HMONITOR hMonitor = NULL;
  44.     RECT rc;
  45.     if (hwnd)
  46.     {
  47.         GetClientRect(hwnd, &rc);
  48.         ClientToScreen(hwnd, (LPPOINT)&rc);
  49.         ClientToScreen(hwnd, (LPPOINT)&rc+1);
  50.     }
  51.     else
  52.     {
  53.         //SetRect(&rc,0,0,1,1);
  54.         SetRectEmpty(&rc);
  55.     }
  56.     EnumDisplayMonitors(NULL, &rc, OneMonitorCallback, (LPARAM)&hMonitor);
  57.     return hMonitor;
  58. }
  59. /*
  60.  * FindDeviceCallback
  61.  */
  62. typedef struct {
  63.     LPSTR   szDevice;
  64.     GUID*   lpGUID;
  65.     GUID    GUID;
  66.     BOOL    fFound;
  67. }   FindDeviceData;
  68. BOOL CALLBACK FindDeviceCallback(GUID* lpGUID, LPSTR szName, LPSTR szDevice, LPVOID lParam)
  69. {
  70.     FindDeviceData *p = (FindDeviceData*)lParam;
  71.     if (lstrcmpi(p->szDevice, szDevice) == 0)
  72.     {
  73. if (lpGUID)
  74. {
  75.     p->GUID = *lpGUID;
  76.     p->lpGUID = &p->GUID;
  77. }
  78. else
  79. {
  80.     p->lpGUID = NULL;
  81. }
  82. p->fFound = TRUE;
  83. return FALSE;
  84.     }
  85.     return TRUE;
  86. }
  87. /*
  88.  * DirectDrawCreateFromDevice
  89.  *
  90.  * create a DirectDraw object for a particular device
  91.  */
  92. IDirectDraw * DirectDrawCreateFromDevice(LPSTR szDevice)
  93. {
  94.     IDirectDraw*    pdd = NULL;
  95.     FindDeviceData  find;
  96.     find.szDevice = szDevice;
  97.     find.fFound   = FALSE;
  98.     DirectDrawEnumerate(FindDeviceCallback, (LPVOID)&find);
  99.     if (find.fFound)
  100.     {
  101.         DirectDrawCreate(find.lpGUID, &pdd, NULL);
  102.     }
  103.     return pdd;
  104. }
  105. /*
  106.  * DirectDrawDeviceFromWindow
  107.  *
  108.  * find the direct draw device that should be used for a given window
  109.  *
  110.  * the return code is a "unique id" for the device, it should be used
  111.  * to determine when your window moves from one device to another.
  112.  *
  113.  *      case WM_MOVE:
  114.  *          if (MyDevice != DirectDrawDeviceFromWindow(hwnd,NULL,NULL))
  115.  *          {
  116.  *              // handle moving to a new device.
  117.  *          }
  118.  *
  119.  */
  120. int DirectDrawDeviceFromWindow(HWND hwnd, LPSTR szDevice, RECT *prc)
  121. {
  122.     HMONITOR hMonitor;
  123.     if (GetSystemMetrics(SM_CMONITORS) <= 1)
  124.     {
  125.         if (prc) SetRect(prc,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
  126.         if (szDevice) lstrcpy(szDevice, "DISPLAY");
  127.         return -1;
  128.     }
  129.     hMonitor = OneMonitorFromWindow(hwnd);
  130.     if (hMonitor == NULL || hMonitor == INVALID_HANDLE_VALUE)
  131.     {
  132. if (prc) SetRectEmpty(prc);
  133. if (szDevice) *szDevice=0;
  134.         return 0;
  135.     }
  136.     else
  137.     {
  138. if (prc != NULL || szDevice != NULL)
  139. {
  140.     MONITORINFOEX mi;
  141.     mi.cbSize = sizeof(mi);
  142.     GetMonitorInfo(hMonitor, &mi);
  143.     if (prc) *prc = mi.rcMonitor;
  144.     if (szDevice) lstrcpy(szDevice, mi.szDevice);
  145. }
  146.         return (int)hMonitor;
  147.     }
  148. }
  149. /*
  150.  * DirectDrawCreateFromWindow
  151.  */
  152. IDirectDraw * DirectDrawCreateFromWindow(HWND hwnd)
  153. {
  154.     IDirectDraw *pdd;
  155.     char szDevice[80];
  156.     //
  157.     // if there is only one monitor, just create a DD object!
  158.     //
  159.     if (GetSystemMetrics(SM_CMONITORS) <= 1)
  160.     {
  161. DirectDrawCreate(NULL, &pdd, NULL);
  162.         return pdd;
  163.     }
  164.     //
  165.     // find the direct draw device that the window is on
  166.     //
  167.     if (DirectDrawDeviceFromWindow(hwnd, szDevice, NULL))
  168.     {
  169. //
  170. // the window is only on one device,
  171. // do a create for only that device
  172. //
  173.         return DirectDrawCreateFromDevice(szDevice);
  174.     }
  175.     else
  176.     {
  177. //
  178. // the window is off the screen or spans two
  179. // monitors, do a DirectDrawCreate(NULL)
  180.         //
  181.         DirectDrawCreate(NULL, &pdd, NULL);
  182. return pdd;
  183.     }
  184. }