home *** CD-ROM | disk | FTP | other *** search
/ Microsoft DirectX SDK 6.1 / Dx6_1_Gold.iso / dxf / samples / multimedia / ddraw / src / stretch3 / ddmm.cpp next >
Encoding:
C/C++ Source or Header  |  1998-06-30  |  5.7 KB  |  247 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. #ifndef WIN32_LEAN_AND_MEAN
  11. #define WIN32_LEAN_AND_MEAN
  12. #endif
  13.  
  14. #include <windows.h>
  15. #include <windowsx.h>
  16. #define COMPILE_MULTIMON_STUBS
  17. #include "multimon.h"
  18. #include <ddraw.h>
  19. #include "ddmm.h"
  20.  
  21.  
  22. /*
  23.  *  OneMonitorCallback
  24.  */
  25. BOOL CALLBACK OneMonitorCallback(HMONITOR hMonitor, HDC hdc, LPRECT prc, LPARAM lParam)
  26. {
  27.     HMONITOR *phMonitorFound = (HMONITOR *)lParam;
  28.  
  29.     if (*phMonitorFound == 0)
  30.     *phMonitorFound = hMonitor;
  31.     else
  32.     *phMonitorFound = (HMONITOR)INVALID_HANDLE_VALUE;
  33.  
  34.     return TRUE;
  35. }
  36.  
  37. /*
  38.  *  OneMonitorFromWindow
  39.  *
  40.  *  similar to the Win32 function MonitorFromWindow, except
  41.  *  only returns a HMONITOR if a window is on a single monitor.
  42.  *
  43.  *  if the window handle is NULL, the primary monitor is returned
  44.  *  if the window is not visible returns NULL
  45.  *  if the window is on a single monitor returns its HMONITOR
  46.  *  if the window is on more than on monitor returns INVALID_HANDLE_VALUE
  47.  */
  48. HMONITOR OneMonitorFromWindow(HWND hwnd)
  49. {
  50.     HMONITOR hMonitor = NULL;
  51.     RECT rc;
  52.  
  53.     if (hwnd)
  54.     {
  55.     GetClientRect(hwnd, &rc);
  56.     ClientToScreen(hwnd, (LPPOINT)&rc);
  57.     ClientToScreen(hwnd, (LPPOINT)&rc+1);
  58.     }
  59.     else
  60.     {
  61.     //SetRect(&rc,0,0,1,1);
  62.     SetRectEmpty(&rc);
  63.     }
  64.  
  65.     EnumDisplayMonitors(NULL, &rc, OneMonitorCallback, (LPARAM)&hMonitor);
  66.     return hMonitor;
  67. }
  68.  
  69. /*
  70.  * FindDeviceCallback
  71.  */
  72. typedef struct {
  73.     LPSTR    szDevice;
  74.     GUID*    lpGUID;
  75.     GUID     GUID;
  76.     BOOL     fFound;
  77.     HMONITOR hMon;
  78. }   FindDeviceData;
  79.  
  80. // This is the callback routine to use with DirectDrawEnumerateEx():
  81. BOOL CALLBACK FindDeviceCallbackEx(GUID* lpGUID, LPSTR szName,
  82.                    LPSTR szDevice, LPVOID lParam, HMONITOR hMonitor)
  83. {
  84.     FindDeviceData *p = (FindDeviceData*)lParam;
  85.  
  86.     if (lstrcmpi(p->szDevice, szDevice) == 0)
  87.     {
  88.     if (lpGUID)
  89.     {
  90.         p->GUID = *lpGUID;
  91.         p->lpGUID = &p->GUID;
  92.     }
  93.     else
  94.     {
  95.         p->lpGUID = NULL;
  96.     }
  97.     p->fFound = TRUE;
  98.     p->hMon = hMonitor;
  99.     return FALSE;
  100.     }
  101.     return TRUE;
  102. }
  103.  
  104. // This is the callback routine to use with DirectDrawEnumerate():
  105. BOOL CALLBACK FindDeviceCallback(GUID* lpGUID, LPSTR szName, LPSTR szDevice, LPVOID lParam)
  106. {
  107.     return FindDeviceCallbackEx(lpGUID, szName, szDevice, lParam, (HMONITOR)0);
  108. }
  109.  
  110. /*
  111.  * DirectDrawCreateFromDevice
  112.  *
  113.  * create a DirectDraw object for a particular device
  114.  */
  115. LPDIRECTDRAW DirectDrawCreateFromDevice(LPSTR szDevice)
  116. {
  117.     HRESULT hres;
  118.     HMODULE hModule;
  119.     FindDeviceData find;
  120.     LPDIRECTDRAWENUMERATEEX pfnEnum;
  121.  
  122.     find.szDevice = szDevice;
  123.     find.fFound   = FALSE;
  124.     find.hMon     = 0;
  125.  
  126.     hModule = GetModuleHandle("ddraw.dll");
  127.     pfnEnum = (LPDIRECTDRAWENUMERATEEX)GetProcAddress(hModule, "DirectDrawEnumerateExA");
  128.  
  129.     if (pfnEnum != NULL)
  130.     {
  131.     /*
  132.      * Make the call to DirectDrawEnumerateEx().
  133.      */
  134.     hres = (*pfnEnum)(FindDeviceCallbackEx,
  135.               (LPVOID)&find, DDENUM_ATTACHEDSECONDARYDEVICES);
  136.     }
  137.     else
  138.     {
  139.     /*
  140.      * The release of DirectDraw we're running on is earlier than DX6, so
  141.      * we must call DirectDrawEnumerate instead of DirectDrawEnumerateEx.
  142.      * Now, of course, we won't be able to handle a multimonitor desktop.
  143.      */
  144.     hres = DirectDrawEnumerate(FindDeviceCallback, (LPVOID)&find);
  145.     }
  146.  
  147.     if (hres == DD_OK && find.fFound)
  148.     {
  149.     LPDIRECTDRAW pdd = NULL;
  150.  
  151.         hres = DirectDrawCreate(find.lpGUID, &pdd, NULL);
  152.     if (hres == DD_OK)
  153.     {
  154.             return pdd;
  155.     }
  156.     }
  157.     return NULL;
  158. }
  159.  
  160. /*
  161.  * DirectDrawDeviceFromWindow
  162.  *
  163.  * find the direct draw device that should be used for a given window
  164.  *
  165.  * the return code is a "unique id" for the device, it should be used
  166.  * to determine when your window moves from one device to another.
  167.  *
  168.  *      case WM_MOVE:
  169.  *          if (MyDevice != DirectDrawDeviceFromWindow(hwnd,NULL,NULL))
  170.  *          {
  171.  *              // handle moving to a new device.
  172.  *          }
  173.  *
  174.  */
  175. int DirectDrawDeviceFromWindow(HWND hwnd, LPSTR szDevice, RECT *prc)
  176. {
  177.     HMONITOR hMonitor;
  178.  
  179.     if (GetSystemMetrics(SM_CMONITORS) <= 1)
  180.     {
  181.     if (prc) SetRect(prc,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
  182.     if (szDevice) lstrcpy(szDevice, "DISPLAY");
  183.     return -1;
  184.     }
  185.  
  186.     hMonitor = OneMonitorFromWindow(hwnd);
  187.  
  188.     if (hMonitor == NULL || hMonitor == INVALID_HANDLE_VALUE)
  189.     {
  190.     if (prc) SetRectEmpty(prc);
  191.     if (szDevice) *szDevice=0;
  192.     return 0;
  193.     }
  194.     else
  195.     {
  196.     if (prc != NULL || szDevice != NULL)
  197.     {
  198.         MONITORINFOEX mi;
  199.         mi.cbSize = sizeof(mi);
  200.         GetMonitorInfo(hMonitor, &mi);
  201.         if (prc) *prc = mi.rcMonitor;
  202.         if (szDevice) lstrcpy(szDevice, mi.szDevice);
  203.     }
  204.     return (int)hMonitor;
  205.     }
  206. }
  207.  
  208. /*
  209.  * DirectDrawCreateFromWindow
  210.  */
  211. IDirectDraw * DirectDrawCreateFromWindow(HWND hwnd)
  212. {
  213.     IDirectDraw *pdd;
  214.     char szDevice[80];
  215.  
  216.     //
  217.     // if there is only one monitor, just create a DD object!
  218.     //
  219.     if (GetSystemMetrics(SM_CMONITORS) <= 1)
  220.     {
  221.     DirectDrawCreate(NULL, &pdd, NULL);
  222.     return pdd;
  223.     }
  224.  
  225.     //
  226.     // find the direct draw device that the window is on
  227.     //
  228.     if (DirectDrawDeviceFromWindow(hwnd, szDevice, NULL))
  229.     {
  230.     //
  231.     // the window is only on one device,
  232.     // do a create for only that device
  233.     //
  234.     return DirectDrawCreateFromDevice(szDevice);
  235.     }
  236.     else
  237.     {
  238.     //
  239.     // the window is off the screen or spans two
  240.     // monitors, do a DirectDrawCreate(NULL)
  241.     //
  242.     DirectDrawCreate(NULL, &pdd, NULL);
  243.     return pdd;
  244.     }
  245. }
  246.  
  247.