testmm.c
上传用户:wqn_0827
上传日期:2007-01-04
资源大小:10k
文件大小:16k
源码类别:

多显示器编程

开发平台:

Visual C++

  1. /*----------------------------------------------------------------------------*
  2. |   TestMM.c : A test sample that calls new Multi monitor APIs and             |
  3. |              displays the results in a simple window.                        |
  4. |                                                                              |
  5. *----------------------------------------------------------------------------*/
  6. #include <windows.h>
  7. #include <windowsx.h>
  8. #include "multimon.h"
  9. #include "mmhelp.h"
  10. #include "testmm.rc"
  11. //
  12. // normally you just include "multimon.h" (like above)
  13. // but one C file needs to define COMPILE_MULTIMON_STUBS
  14. // so the compatibility stubs will be defined
  15. //
  16. #define COMPILE_MULTIMON_STUBS
  17. #include "multimon.h"
  18. /*----------------------------------------------------------------------------*
  19. *----------------------------------------------------------------------------*/
  20. static  char    szAppName[]="TestMM";
  21. static  HINSTANCE hInstApp;
  22. static  HWND      hwndApp;
  23. /*----------------------------------------------------------------------------*
  24. *----------------------------------------------------------------------------*/
  25. LONG CALLBACK AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  26. int  ErrMsg (LPSTR sz,...);
  27. void AppSetText(LPSTR sz,...);
  28. void AppPrint(LPSTR sz,...);
  29. void GetOptimalDIBFormat(HDC hdc, BITMAPINFOHEADER *pbi);
  30. /*----------------------------------------------------------------------------*
  31. *----------------------------------------------------------------------------*/
  32. void TestEnumDisplayDevices()
  33. {
  34.     DWORD i;
  35.     DISPLAY_DEVICE dd;
  36.     DEVMODE dm;
  37.     AppPrint("");
  38.     AppPrint("EnumDisplayDevices:");
  39.     ZeroMemory(&dd, sizeof(dd));
  40.     dd.cb = sizeof(dd);
  41.     __try
  42.     {
  43.         for(i=0; EnumDisplayDevices(NULL, i, &dd, 0); i++)
  44.         {
  45.             AppPrint("Device %d:", i);
  46.             AppPrint("    DeviceName:   '%s'", dd.DeviceName);
  47.             AppPrint("    DeviceString: '%s'", dd.DeviceString);
  48.             AppPrint("    StateFlags:   %s%s%s%s",
  49.                 ((dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) ? "desktop " : ""),
  50.                 ((dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE     ) ? "primary " : ""),
  51.                 ((dd.StateFlags & DISPLAY_DEVICE_VGA                ) ? "vga "     : ""),
  52.                 ((dd.StateFlags & DISPLAY_DEVICE_MULTI_DRIVER       ) ? "multi "   : ""),
  53.                 ((dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER   ) ? "mirror "  : "") );
  54.             ZeroMemory(&dm, sizeof(dm));
  55.             dm.dmSize = sizeof(dm);
  56.             EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm);
  57.             AppPrint("    Current Settings %dx%dx%d",dm.dmPelsWidth,dm.dmPelsHeight,dm.dmBitsPerPel);
  58.             EnumDisplaySettings(dd.DeviceName, ENUM_REGISTRY_SETTINGS, &dm);
  59.             AppPrint("    Registry Settings %dx%dx%d",dm.dmPelsWidth,dm.dmPelsHeight,dm.dmBitsPerPel);
  60.         }
  61.     }
  62.     __except(1)
  63.     {
  64.         AppPrint("EnumDisplayDevices faulted!");
  65.     }
  66. }
  67. /*----------------------------------------------------------------------------*
  68. *----------------------------------------------------------------------------*/
  69. BOOL CALLBACK CallbackNull(HMONITOR hMonitor,HDC hdc, LPRECT prc, LPARAM lParam)
  70. {
  71.     return TRUE;
  72. }
  73. BOOL CALLBACK CallbackWindow(HMONITOR hMonitor,HDC hdc, LPRECT prc, LPARAM lParam)
  74. {
  75.     return TRUE;
  76. }
  77. BOOL CALLBACK CallbackRect(HMONITOR hMonitor,HDC hdc, LPRECT prc, LPARAM lParam)
  78. {
  79.     return TRUE;
  80. }
  81. BOOL CALLBACK CallbackScreen(HMONITOR hMonitor,HDC hdc,LPRECT prc,LPARAM lParam)
  82. {
  83.     MONITORINFOEX mix;
  84.     MONITORINFO mi;
  85.     mi.cbSize = sizeof(mi);
  86.     GetMonitorInfo(hMonitor, &mi);
  87.     mix.cbSize = sizeof(mix);
  88.     GetMonitorInfo(hMonitor, (MONITORINFO*)&mix);
  89.     AppPrint("Monitor %08X", hMonitor);
  90.     AppPrint("      szDevice  = '%s'", (LPSTR)mix.szDevice);
  91.     AppPrint("      rcMonitor = [%d,%d,%d,%d]", mi.rcMonitor);
  92.     AppPrint("      rcWork    = [%d,%d,%d,%d]", mi.rcWork);
  93.     AppPrint("      dwFlags   = %08X", mi.dwFlags);
  94.     if (hdc)
  95.     {
  96.         struct {
  97.             BITMAPINFOHEADER bi;
  98.             DWORD            ct[256];
  99.         }   dib;
  100.         GetOptimalDIBFormat(hdc, &dib.bi);
  101.         AppPrint("      VREFRESH        = %d", GetDeviceCaps(hdc, VREFRESH       ));
  102.         AppPrint("      DESKTOPVERTRES  = %d", GetDeviceCaps(hdc, DESKTOPVERTRES ));
  103.         AppPrint("      DESKTOPHORZRES  = %d", GetDeviceCaps(hdc, DESKTOPHORZRES ));
  104.         AppPrint("      BLTALIGNMENT    = %d", GetDeviceCaps(hdc, BLTALIGNMENT   ));
  105.         AppPrint("      HORZRES         = %d", GetDeviceCaps(hdc, HORZRES   ));
  106.         AppPrint("      VERTRES         = %d", GetDeviceCaps(hdc, VERTRES   ));
  107.         AppPrint("      PALETTE         = %s", (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) ? "Yes" : "No");
  108.         AppPrint("      BITSPIXEL       = %d", GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES));
  109.         if (dib.bi.biCompression == BI_BITFIELDS)
  110.         {
  111.             if (dib.ct[0] == 0xF800 &&
  112.                 dib.ct[1] == 0x07E0 &&
  113.                 dib.ct[2] == 0x001F )
  114.             {
  115.                 AppPrint("      FORMAT          = 565");
  116.             }
  117.             if (dib.ct[0] == 0x7C00 &&
  118.                 dib.ct[1] == 0x03E0 &&
  119.                 dib.ct[2] == 0x001F )
  120.             {
  121.                 AppPrint("      FORMAT          = 555");
  122.             }
  123.             if (dib.ct[0] == 0xFF0000 &&
  124.                 dib.ct[1] == 0x00FF00 &&
  125.                 dib.ct[2] == 0x0000FF )
  126.             {
  127.                 AppPrint("      FORMAT          = BGR");
  128.             }
  129.             if (dib.ct[0] == 0x0000FF &&
  130.                 dib.ct[1] == 0x00FF00 &&
  131.                 dib.ct[2] == 0xFF0000 )
  132.             {
  133.                 AppPrint("      FORMAT          = RGB");
  134.             }
  135.         }
  136.     }
  137.     return TRUE;
  138. }
  139. /*----------------------------------------------------------------------------*
  140. *----------------------------------------------------------------------------*/
  141. void TestEnumDisplayMonitors()
  142. {
  143.     HDC hdc;
  144.     RECT rc;
  145.     AppPrint("");
  146.     AppPrint("EnumDisplayMonitors");
  147.     EnumDisplayMonitors(NULL, NULL, CallbackNull, 42);
  148.     hdc = GetDC(NULL);
  149.     EnumDisplayMonitors(hdc, NULL, CallbackScreen, 42);
  150.     ReleaseDC(NULL,hdc);
  151.     hdc = GetDC(hwndApp);
  152.     EnumDisplayMonitors(hdc, NULL, CallbackWindow, 42);
  153.     ReleaseDC(hwndApp,hdc);
  154.     GetWindowRect(hwndApp, &rc);
  155.     EnumDisplayMonitors(NULL, &rc, CallbackRect, 42);
  156. }
  157. /*----------------------------------------------------------------------------*
  158. *----------------------------------------------------------------------------*/
  159. void DoTestMM(HWND hwnd, LPARAM lParam)
  160. {
  161.     HDC hdc;
  162.     RECT rc;
  163.     static HMONITOR hMonitorMe;
  164.     HMONITOR hMonitor;
  165.     hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
  166.     if (hMonitorMe == hMonitor && lParam)
  167.         return;
  168.     hMonitorMe = hMonitor;
  169.     AppPrint(NULL);
  170.     if (hMonitor)
  171.     {
  172.         MONITORINFOEX mi;
  173.         mi.cbSize = sizeof(mi);
  174.         GetMonitorInfo(hMonitor, (MONITORINFO*)&mi);
  175.         AppSetText(mi.szDevice);
  176.         AppPrint("My Window is on hMonitor %08X",hMonitor);
  177.     }
  178.     else
  179.     {
  180.         AppSetText(NULL);
  181.         AppPrint("My Window is not visible");
  182.     }
  183.     AppPrint("");
  184.     AppPrint("SM_CMONITORS         is %d", GetSystemMetrics(SM_CMONITORS));
  185.     AppPrint("SM_SAMEDISPLAYFORMAT is %d", GetSystemMetrics(SM_SAMEDISPLAYFORMAT));
  186.     AppPrint("SM_XVIRTUALSCREEN    is %d", GetSystemMetrics(SM_XVIRTUALSCREEN));
  187.     AppPrint("SM_YVIRTUALSCREEN    is %d", GetSystemMetrics(SM_YVIRTUALSCREEN));
  188.     AppPrint("SM_CXVIRTUALSCREEN   is %d", GetSystemMetrics(SM_CXVIRTUALSCREEN));
  189.     AppPrint("SM_CYVIRTUALSCREEN   is %d", GetSystemMetrics(SM_CYVIRTUALSCREEN));
  190.     hdc = GetDC(NULL);
  191.     GetClipBox(hdc, &rc);
  192.     AppPrint("GetClipBox of GetDC(NULL)    = [%d,%d,%d,%d]", rc);
  193.     ReleaseDC(NULL, hdc);
  194.     hdc = GetDC(GetDesktopWindow());
  195.     GetClipBox(hdc, &rc);
  196.     AppPrint("GetClipBox of GetDC(desktop) = [%d,%d,%d,%d]", rc);
  197.     ReleaseDC(GetDesktopWindow(), hdc);
  198.     GetWindowRect(GetDesktopWindow(), &rc);
  199.     AppPrint("GetWindowRect of desktop     = [%d,%d,%d,%d]", rc);
  200.     TestEnumDisplayMonitors();
  201.     TestEnumDisplayDevices();
  202. }
  203. /*----------------------------------------------------------------------------*
  204. |   AppInit( hInst, hPrev)                                                     |
  205. *----------------------------------------------------------------------------*/
  206. BOOL AppInit(HINSTANCE hInst,HINSTANCE hPrev,int sw,LPSTR szCmdLine)
  207. {
  208.     WNDCLASS cls;
  209.     int      dx,dy;
  210.     /* Save instance handle for DialogBoxs */
  211.     hInstApp = hInst;
  212.     if (!hPrev)
  213.     {
  214.         /*
  215.          *  Register a class for the main application window
  216.          */
  217.         cls.hCursor        = LoadCursor(NULL,IDC_ARROW);
  218.         cls.hIcon          = LoadIcon(hInst,"AppIcon");
  219.         cls.lpszMenuName   = "AppMenu";
  220.         cls.lpszClassName  = szAppName;
  221.         cls.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  222.         cls.hInstance      = hInst;
  223.         cls.style          = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  224.         cls.lpfnWndProc    = (WNDPROC)AppWndProc;
  225.         cls.cbWndExtra     = 0;
  226.         cls.cbClsExtra     = 0;
  227.         if (!RegisterClass(&cls))
  228.             return FALSE;
  229.     }
  230.     dx = GetSystemMetrics (SM_CXSCREEN) / 2;
  231.     dy = GetSystemMetrics (SM_CYSCREEN) / 2;
  232.     hwndApp = CreateWindow (szAppName,    // Class name
  233.                             szAppName,              // Caption
  234.                             WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  235.                             CW_USEDEFAULT, 0,
  236.     dx,dy,     // Size
  237.                             (HWND)NULL,             // Parent window (no parent)
  238.                             (HMENU)NULL,            // use class menu
  239.                             hInst,                  // handle to window instance
  240.                             (LPSTR)NULL             // no params to pass on
  241.                            );
  242.      
  243.     ShowWindow(hwndApp,sw);
  244.     return TRUE;
  245. }
  246. /*----------------------------------------------------------------------------*
  247. |   AppWndProc( hwnd, uiMessage, wParam, lParam )                              |
  248. |                                                                              |
  249. |   Description:                                                               |
  250. |       The window proc for the app's main (tiled) window.  This processes all |
  251. |       of the parent window's messages.                                       |
  252. |                                                                              |
  253. *----------------------------------------------------------------------------*/
  254. LONG FAR PASCAL AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  255. {
  256.     HWND hwndC;
  257.     switch (msg)
  258.     {
  259.         case WM_COMMAND:
  260.             switch (LOWORD(wParam))
  261.             {
  262.                 case ID_TEST_CENTERTOMONITOR:   
  263.     CenterWindowToMonitor(hwnd, hwnd, FALSE); 
  264.     break;
  265.                 case ID_TEST_CENTERTOWORKAREA:  
  266.     CenterWindowToMonitor(hwnd, hwnd, TRUE); 
  267.     break;
  268.                 case ID_TEST_CLIPTOMONITOR:     
  269.     ClipWindowToMonitor(hwnd, hwnd, FALSE); 
  270.     break;
  271.                 case ID_TEST_CLIPTOWORKAREA:    
  272.     ClipWindowToMonitor(hwnd, hwnd, TRUE); 
  273.     break;
  274.                 case ID_TEST_RUNNOTEPAD:
  275.     ShellExecute(hwnd, "open", "notepad.exe", NULL, NULL, SW_SHOWNORMAL );
  276.     break;
  277.             }
  278.             break;
  279.         case WM_KEYUP:
  280.             if (wParam == VK_F5)
  281.                 DoTestMM(hwnd, 0);
  282.             break;
  283.         case WM_WINDOWPOSCHANGED:
  284.             DoTestMM(hwnd, 1);
  285.             break;
  286.         case WM_SETTINGCHANGE:
  287.         case WM_DISPLAYCHANGE:
  288.             DoTestMM(hwnd, 0);
  289.             break;
  290. case WM_SIZE:
  291.     if (hwndC = GetWindow(hwnd, GW_CHILD))
  292.                 MoveWindow(hwndC, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
  293.     break;
  294. case WM_DESTROY:
  295.             PostQuitMessage(0);
  296.     break;
  297.     }
  298.     return DefWindowProc(hwnd,msg,wParam,lParam);
  299. }
  300. /*----------------------------------------------------------------------------*
  301. |   ErrMsg - Opens a Message box with a error message in it.  The user can     |
  302. |            select the OK button to continue                                  |
  303. *----------------------------------------------------------------------------*/
  304. int ErrMsg (LPSTR sz,...)
  305. {
  306.     char ach[128];
  307.     wvsprintf (ach,sz,(LPSTR)(&sz+1));   /* Format the string */
  308.     MessageBox(hwndApp,ach,szAppName,MB_OK|MB_ICONEXCLAMATION|MB_TASKMODAL);
  309.     return FALSE;
  310. }
  311. /*----------------------------------------------------------------------------*
  312. *----------------------------------------------------------------------------*/
  313. void AppSetText(LPSTR sz,...)
  314. {
  315.     char ach[128];
  316.     lstrcpy(ach, szAppName);
  317.     if (sz != NULL && *sz != 0)
  318.     {
  319.         lstrcat(ach, " - ");
  320.         wvsprintf (ach+lstrlen(ach),sz,(LPSTR)(&sz+1));   /* Format the string */
  321.     }
  322.     SetWindowText(hwndApp, ach);
  323. }
  324. /*----------------------------------------------------------------------------*
  325. *----------------------------------------------------------------------------*/
  326. void AppPrint(LPSTR sz,...)
  327. {
  328.     HWND hwndE = GetWindow(hwndApp, GW_CHILD);
  329.     char ach[128];
  330.     if (hwndE == NULL) 
  331.     {
  332.      RECT rc;
  333.         GetClientRect(hwndApp, &rc);
  334.         hwndE = CreateWindow ("Edit", "", 
  335.             WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_READONLY | WS_VSCROLL | ES_AUTOVSCROLL,
  336.             0, 0, rc.right, rc.bottom,
  337.             hwndApp, (HMENU)-1, hInstApp, NULL);
  338.         SetWindowFont(hwndE, GetStockObject(ANSI_FIXED_FONT), TRUE);
  339.     }
  340.     if (sz == NULL)
  341.     {
  342.      Edit_SetSel(hwndE, 0, (UINT)-1);
  343.      Edit_ReplaceSel(hwndE, "");
  344.     }
  345.     else
  346.     {
  347.      wvsprintf (ach,sz,(LPSTR)(&sz+1));   /* Format the string */
  348.      lstrcat(ach, "rn");
  349.      Edit_SetSel(hwndE, (UINT)-1, (UINT)-1);
  350.      Edit_ReplaceSel(hwndE, ach);
  351.     }
  352. }
  353. /*----------------------------------------------------------------------------*
  354. |   WinMain( hInst, hPrev, lpszCmdLine, cmdShow )                              |
  355. *----------------------------------------------------------------------------*/
  356. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
  357. {
  358.     MSG     msg;
  359.     DWORD   dw=0;
  360.     /* Call initialization procedure */
  361.     if (!AppInit(hInst,hPrev,sw,szCmdLine))
  362.         return FALSE;
  363.     /*
  364.      * Polling messages from event queue
  365.      */
  366.     for (;;)
  367.     {
  368.         if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
  369.         {
  370.             if (msg.message == WM_QUIT)
  371.                 break;
  372.             TranslateMessage(&msg);
  373.             DispatchMessage(&msg);
  374.         }
  375.         else
  376. {
  377.             WaitMessage();
  378.         }
  379.     }
  380.     return msg.wParam;
  381. }
  382. //
  383. //  GetOptimalDIBFormat
  384. //
  385. //   get the optimal DIB format for a display device.
  386. //   the optimal DIB format is the format that exactly
  387. //   matches the format of the device, this is very important
  388. //   when dealing with 16bpp modes, you need to know
  389. //   what bitfields to use (555 or 565 for example)
  390. //
  391. //   you normaly use this function to get the best
  392. //   format to pass to CreateDIBSection()
  393. //
  394. //  Input
  395. //   hdc device to get the optimal format for.
  396. //   pbi pointer to a bitmapinfo + color table
  397. //       (room for 256 colors are assumed)
  398. //
  399. //  Output
  400. //   pbi contains optimal DIB format, in the <= 8bpp case
  401. //       the color table will contain the system palette
  402. //       in the >=16bpp case the "color table" will contain
  403. //       the correct bit fields (see BI_BITFIELDS for more info)
  404. //
  405. //  Notes
  406. //   if you are going to use this function on a 8bpp device
  407. //   you should make sure the colortable contains a indentity
  408. //   palette for optimal blt'ing
  409. //
  410. void GetOptimalDIBFormat(HDC hdc, BITMAPINFOHEADER *pbi)
  411. {
  412.     HBITMAP hbm;
  413.     hbm = CreateCompatibleBitmap(hdc, 1, 1);
  414.     ZeroMemory(pbi, sizeof(BITMAPINFOHEADER));
  415.     pbi->biSize = sizeof(BITMAPINFOHEADER);
  416.     pbi->biBitCount = 0;
  417.     // first call will fill in the optimal biBitCount
  418.     GetDIBits(hdc, hbm, 0, 1, NULL, (BITMAPINFO*)pbi, DIB_RGB_COLORS);
  419.     // second call will get the optimal color table, or the optimal bitfields
  420.     GetDIBits(hdc, hbm, 0, 1, NULL, (BITMAPINFO*)pbi, DIB_RGB_COLORS);
  421.     DeleteObject(hbm);
  422. }