home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / stretch3 / ddmm.cpp next >
C/C++ Source or Header  |  1997-07-14  |  5KB  |  207 lines

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