home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows 95 / Programming Windows 95.iso / code / CHAP15 / DEVCAPS2.C next >
Encoding:
C/C++ Source or Header  |  1996-01-01  |  17.2 KB  |  413 lines

  1. /*------------------------------------------------------------------
  2.    DEVCAPS2.C -- Displays Device Capability Information (Version 2)
  3.                  (c) Charles Petzold, 1996
  4.   ------------------------------------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include "devcaps2.h"
  10.  
  11. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  12. void DoBasicInfo    (HDC, HDC, int, int) ;
  13. void DoOtherInfo    (HDC, HDC, int, int) ;
  14. void DoBitCodedCaps (HDC, HDC, int, int, int) ;
  15.  
  16. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  17.                     PSTR szCmdLine, int iCmdShow)
  18.      {
  19.      static char szAppName[] = "DevCaps2" ;
  20.      HWND        hwnd ;
  21.      MSG         msg ;
  22.      WNDCLASSEX  wndclass ;
  23.  
  24.      wndclass.cbSize        = sizeof (wndclass) ;
  25.      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  26.      wndclass.lpfnWndProc   = WndProc ;
  27.      wndclass.cbClsExtra    = 0 ;
  28.      wndclass.cbWndExtra    = 0 ;
  29.      wndclass.hInstance     = hInstance ;
  30.      wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  31.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  32.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  33.      wndclass.lpszMenuName  = szAppName ;
  34.      wndclass.lpszClassName = szAppName ;
  35.      wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION) ;
  36.  
  37.      RegisterClassEx (&wndclass) ;
  38.  
  39.      hwnd = CreateWindow (szAppName, NULL,
  40.                           WS_OVERLAPPEDWINDOW,
  41.                           CW_USEDEFAULT, CW_USEDEFAULT,
  42.                           CW_USEDEFAULT, CW_USEDEFAULT,
  43.                           NULL, NULL, hInstance, NULL) ;
  44.  
  45.      ShowWindow (hwnd, iCmdShow) ;
  46.      UpdateWindow (hwnd) ;
  47.  
  48.      while (GetMessage (&msg, NULL, 0, 0))
  49.           {
  50.           TranslateMessage (&msg) ;
  51.           DispatchMessage (&msg) ;
  52.           }
  53.      return msg.wParam ;
  54.      }
  55.  
  56. LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  57.      {
  58.      static char   szDevice[32], szWindowText[64] ;
  59.      static int    n, cxChar, cyChar, 
  60.                    nCurrentDevice = IDM_SCREEN,
  61.                    nCurrentInfo   = IDM_BASIC ;
  62.      static DWORD  dwNeeded, dwReturned ;
  63.      static LPPRINTER_INFO_5 pinfo5 ;
  64.  
  65.      DWORD         i ;
  66.      HDC           hdc, hdcInfo ;
  67.      HMENU         hMenu ;
  68.      PAINTSTRUCT   ps ;
  69.      TEXTMETRIC    tm ;
  70.      HANDLE        hPrint ;
  71.  
  72.      switch (msg)
  73.           {
  74.           case WM_CREATE :
  75.                hdc = GetDC (hwnd) ;
  76.                SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
  77.                GetTextMetrics (hdc, &tm) ;
  78.                cxChar = tm.tmAveCharWidth ;
  79.                cyChar = tm.tmHeight + tm.tmExternalLeading ;
  80.                ReleaseDC (hwnd, hdc) ;
  81.  
  82.                lParam = 0 ;
  83.                                                   // fall through
  84.           case WM_WININICHANGE :
  85.                if (lParam != 0 && lstrcmp ((PSTR) lParam, "devices") != 0)
  86.                     return 0 ;
  87.  
  88.                hMenu = GetSubMenu (GetMenu (hwnd), 0) ;
  89.  
  90.                while (GetMenuItemCount (hMenu) > 1)
  91.                     DeleteMenu (hMenu, 1, MF_BYPOSITION) ;
  92.  
  93.                // Get a list of all local and remote printers
  94.                // 
  95.                // First, find out how large an array we need; this
  96.                //   call will fail, leaving the required size in dwNeeded
  97.                EnumPrinters (PRINTER_ENUM_LOCAL, 
  98.                              NULL, 5, (LPBYTE) "", 0, &dwNeeded, &dwReturned) ;
  99.  
  100.                // Next, allocate space for PRINTER_INFO_5 array
  101.                if (pinfo5)
  102.                     HeapFree (GetProcessHeap (), 0, pinfo5) ;
  103.                pinfo5 = (LPPRINTER_INFO_5) HeapAlloc (GetProcessHeap (), 
  104.                                               HEAP_NO_SERIALIZE, dwNeeded) ;
  105.  
  106.                // Last, fill allocated PRINTER_INFO_5 array
  107.                if (!pinfo5 || !EnumPrinters (PRINTER_ENUM_LOCAL, 
  108.                                     NULL, 5, (LPBYTE) pinfo5, dwNeeded, 
  109.                                     &dwNeeded, &dwReturned))
  110.                     {
  111.                     MessageBox (hwnd, "Could not enumerate printers!",
  112.                                                   NULL, MB_ICONSTOP) ;
  113.                     DestroyWindow (hwnd) ;
  114.                     return 0 ;
  115.                     }
  116.  
  117.                for (i = 0, n = IDM_SCREEN + 1 ; i < dwReturned ; i++, n++)
  118.                     {
  119.                     AppendMenu (hMenu, n % 16 ? 0 : MF_MENUBARBREAK, n, 
  120.                                                   pinfo5->pPrinterName) ;
  121.                     pinfo5++ ;
  122.                     }
  123.  
  124.                AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ;
  125.                AppendMenu (hMenu, 0, IDM_DEVMODE, "Properties") ;
  126.  
  127.                wParam = IDM_SCREEN ;
  128.                                                   // fall through
  129.           case WM_COMMAND :
  130.                hMenu = GetMenu (hwnd) ;
  131.  
  132.                if (wParam < IDM_DEVMODE)          // IDM_SCREEN & Printers
  133.                     {
  134.                     CheckMenuItem (hMenu, nCurrentDevice, MF_UNCHECKED) ;
  135.                     nCurrentDevice = wParam ;
  136.                     CheckMenuItem (hMenu, nCurrentDevice, MF_CHECKED) ;
  137.                     }
  138.                else if (wParam == IDM_DEVMODE)    // "Properties" selection
  139.                     {
  140.                     GetMenuString (hMenu, nCurrentDevice, szDevice,
  141.                                    sizeof (szDevice), MF_BYCOMMAND) ;
  142.  
  143.                     if (OpenPrinter (szDevice, &hPrint, NULL))
  144.                          {
  145.                          PrinterProperties (hwnd, hPrint) ;
  146.                          ClosePrinter (hPrint) ;
  147.                          }
  148.                     }
  149.                else                               // info menu items
  150.                     {
  151.                     CheckMenuItem (hMenu, nCurrentInfo, MF_UNCHECKED) ;
  152.                     nCurrentInfo = wParam ;
  153.                     CheckMenuItem (hMenu, nCurrentInfo, MF_CHECKED) ;
  154.                     }
  155.                InvalidateRect (hwnd, NULL, TRUE) ;
  156.                return 0 ;
  157.  
  158.           case WM_INITMENUPOPUP :
  159.                if (lParam == 0)
  160.                     EnableMenuItem (GetMenu (hwnd), IDM_DEVMODE,
  161.                          nCurrentDevice == IDM_SCREEN ?
  162.                               MF_GRAYED : MF_ENABLED) ;
  163.                return 0 ;
  164.  
  165.           case WM_PAINT :
  166.                strcpy (szWindowText, "Device Capabilities: ") ;
  167.           
  168.                if (nCurrentDevice == IDM_SCREEN)
  169.                     {
  170.                     strcpy (szDevice, "DISPLAY") ;
  171.                     hdcInfo = CreateIC (szDevice, NULL, NULL, NULL) ;
  172.                     }
  173.                else
  174.                     {
  175.                     hMenu = GetMenu (hwnd) ;
  176.                     GetMenuString (hMenu, nCurrentDevice, szDevice,
  177.                                    sizeof (szDevice), MF_BYCOMMAND) ;
  178.                     hdcInfo = CreateIC (NULL, szDevice, NULL, NULL) ;
  179.                     }
  180.  
  181.                strcat (szWindowText, szDevice) ;
  182.                SetWindowText (hwnd, szWindowText) ;
  183.  
  184.                hdc = BeginPaint (hwnd, &ps) ;
  185.                SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
  186.  
  187.                if (hdcInfo)
  188.                     {
  189.                     switch (nCurrentInfo)
  190.                          {
  191.                          case IDM_BASIC :
  192.                               DoBasicInfo (hdc, hdcInfo, cxChar, cyChar) ;
  193.                               break ;
  194.  
  195.                          case IDM_OTHER :
  196.                               DoOtherInfo (hdc, hdcInfo, cxChar, cyChar) ;
  197.                               break ;
  198.  
  199.                          case IDM_CURVE :
  200.                          case IDM_LINE :
  201.                          case IDM_POLY :
  202.                          case IDM_TEXT :
  203.                               DoBitCodedCaps (hdc, hdcInfo, cxChar, cyChar,
  204.                                    nCurrentInfo - IDM_CURVE) ;
  205.                               break ;
  206.                          }
  207.                     DeleteDC (hdcInfo) ;
  208.                     }
  209.  
  210.                EndPaint (hwnd, &ps) ;
  211.                return 0 ;
  212.  
  213.           case WM_DESTROY :
  214.                if (pinfo5)
  215.                     HeapFree (GetProcessHeap (), 0, pinfo5) ;
  216.  
  217.                PostQuitMessage (0) ;
  218.                return 0 ;
  219.           }
  220.      return DefWindowProc (hwnd, msg, wParam, lParam) ;
  221.      }
  222.  
  223. void DoBasicInfo (HDC hdc, HDC hdcInfo, int cxChar, int cyChar)
  224.      {
  225.      static struct
  226.           {
  227.           int   nIndex ;
  228.           char *szDesc ;
  229.           }
  230.           info[] =
  231.           {
  232.           HORZSIZE,      "HORZSIZE     Width in millimeters:",
  233.           VERTSIZE,      "VERTSIZE     Height in millimeters:",
  234.           HORZRES,       "HORZRES      Width in pixels:",
  235.           VERTRES,       "VERTRES      Height in raster lines:",
  236.           BITSPIXEL,     "BITSPIXEL    Color bits per pixel:",
  237.           PLANES,        "PLANES       Number of color planes:",
  238.           NUMBRUSHES,    "NUMBRUSHES   Number of device brushes:",
  239.           NUMPENS,       "NUMPENS      Number of device pens:",
  240.           NUMMARKERS,    "NUMMARKERS   Number of device markers:",
  241.           NUMFONTS,      "NUMFONTS     Number of device fonts:",
  242.           NUMCOLORS,     "NUMCOLORS    Number of device colors:",
  243.           PDEVICESIZE,   "PDEVICESIZE  Size of device structure:",
  244.           ASPECTX,       "ASPECTX      Relative width of pixel:",
  245.           ASPECTY,       "ASPECTY      Relative height of pixel:",
  246.           ASPECTXY,      "ASPECTXY     Relative diagonal of pixel:",
  247.           LOGPIXELSX,    "LOGPIXELSX   Horizontal dots per inch:",
  248.           LOGPIXELSY,    "LOGPIXELSY   Vertical dots per inch:",
  249.           SIZEPALETTE,   "SIZEPALETTE  Number of palette entries:",
  250.           NUMRESERVED,   "NUMRESERVED  Reserved palette entries:",
  251.           COLORRES,      "COLORRES     Actual color resolution:"
  252.           } ;
  253.      char   szBuffer[80] ;
  254.      int    i ;
  255.  
  256.      for (i = 0 ; i < sizeof (info) / sizeof (info[0]) ; i++)
  257.           TextOut (hdc, cxChar, (i + 1) * cyChar, szBuffer,
  258.                sprintf (szBuffer, "%-40s%8d", info[i].szDesc,
  259.                     GetDeviceCaps (hdcInfo, info[i].nIndex))) ;
  260.      }
  261.  
  262. void DoOtherInfo (HDC hdc, HDC hdcInfo, int cxChar, int cyChar)
  263.      {
  264.      static BITS clip[] =
  265.           {
  266.           CP_RECTANGLE,  "CP_RECTANGLE",     "Can Clip To Rectangle:"
  267.           } ; 
  268.  
  269.      static BITS raster[] =
  270.           {
  271.           RC_BITBLT,       "RC_BITBLT",       "Capable of simple BitBlt:",
  272.           RC_BANDING,      "RC_BANDING",      "Requires banding support:",
  273.           RC_SCALING,      "RC_SCALING",      "Requires scaling support:",
  274.           RC_BITMAP64,     "RC_BITMAP64",     "Supports bitmaps >64K:",
  275.           RC_GDI20_OUTPUT, "RC_GDI20_OUTPUT", "Has 2.0 output calls:",
  276.           RC_DI_BITMAP,    "RC_DI_BITMAP",    "Supports DIB to memory:",
  277.           RC_PALETTE,      "RC_PALETTE",      "Supports a palette:",
  278.           RC_DIBTODEV,     "RC_DIBTODEV",     "Supports bitmap conversion:",
  279.           RC_BIGFONT,      "RC_BIGFONT",      "Supports fonts >64K:",
  280.           RC_STRETCHBLT,   "RC_STRETCHBLT",   "Supports StretchBlt:",
  281.           RC_FLOODFILL,    "RC_FLOODFILL",    "Supports FloodFill:",
  282.           RC_STRETCHDIB,   "RC_STRETCHDIB",   "Supports StretchDIBits:"
  283.           } ;
  284.  
  285.      static char *szTech[] = { "DT_PLOTTER (Vector plotter)",
  286.                                "DT_RASDISPLAY (Raster display)",
  287.                                "DT_RASPRINTER (Raster printer)",
  288.                                "DT_RASCAMERA (Raster camera)",
  289.                                "DT_CHARSTREAM (Character-stream, PLP)",
  290.                                "DT_METAFILE (Metafile, VDM)",
  291.                                "DT_DISPFILE (Display-file)" } ;
  292.      char        szBuffer[80] ;
  293.      int         i ;
  294.  
  295.      TextOut (hdc, cxChar, cyChar, szBuffer,
  296.           sprintf (szBuffer, "%-24s%04XH",
  297.                "DRIVERVERSION:", GetDeviceCaps (hdcInfo, DRIVERVERSION))) ;
  298.  
  299.      TextOut (hdc, cxChar, 2 * cyChar, szBuffer,
  300.           sprintf (szBuffer, "%-24s%-40s", "TECHNOLOGY:", 
  301.                    szTech[GetDeviceCaps (hdcInfo, TECHNOLOGY)])) ;
  302.  
  303.      TextOut (hdc, cxChar, 4 * cyChar, szBuffer,
  304.           sprintf (szBuffer, "CLIPCAPS (Clipping capabilities)")) ;
  305.  
  306.      for (i = 0 ; i < sizeof (clip) / sizeof (clip[0]) ; i++)
  307.           TextOut (hdc, 9 * cxChar, (i + 6) * cyChar, szBuffer,
  308.                sprintf (szBuffer, "%-16s%-28s %3s",
  309.                     clip[i].szMask, clip[i].szDesc,
  310.                     GetDeviceCaps (hdcInfo, CLIPCAPS) & clip[i].nMask ?
  311.                          "Yes" : "No")) ;
  312.  
  313.      TextOut (hdc, cxChar, 8 * cyChar, szBuffer,
  314.           sprintf (szBuffer, "RASTERCAPS (Raster capabilities)")) ;
  315.  
  316.      for (i = 0 ; i < sizeof (raster) / sizeof (raster[0]) ; i++)
  317.           TextOut (hdc, 9 * cxChar, (i + 10) * cyChar, szBuffer,
  318.                sprintf (szBuffer, "%-16s%-28s %3s",
  319.                     raster[i].szMask, raster[i].szDesc,
  320.                     GetDeviceCaps (hdcInfo, RASTERCAPS) & raster[i].nMask ?
  321.                          "Yes" : "No")) ;
  322.      }
  323.  
  324. void DoBitCodedCaps (HDC hdc, HDC hdcInfo, int cxChar, int cyChar, int nType)
  325.      {
  326.      static BITS curves[] =
  327.           {
  328.           CC_CIRCLES,    "CC_CIRCLES",    "circles:",
  329.           CC_PIE,        "CC_PIE",        "pie wedges:",
  330.           CC_CHORD,      "CC_CHORD",      "chord arcs:",
  331.           CC_ELLIPSES,   "CC_ELLIPSES",   "ellipses:",
  332.           CC_WIDE,       "CC_WIDE",       "wide borders:",
  333.           CC_STYLED,     "CC_STYLED",     "styled borders:",
  334.           CC_WIDESTYLED, "CC_WIDESTYLED", "wide and styled borders:",
  335.           CC_INTERIORS,  "CC_INTERIORS",  "interiors:"
  336.           } ; 
  337.  
  338.      static BITS lines[] =
  339.           {
  340.           LC_POLYLINE,   "LC_POLYLINE",   "polyline:",
  341.           LC_MARKER,     "LC_MARKER",     "markers:",
  342.           LC_POLYMARKER, "LC_POLYMARKER", "polymarkers",
  343.           LC_WIDE,       "LC_WIDE",       "wide lines:",
  344.           LC_STYLED,     "LC_STYLED",     "styled lines:",
  345.           LC_WIDESTYLED, "LC_WIDESTYLED", "wide and styled lines:",
  346.           LC_INTERIORS,  "LC_INTERIORS",  "interiors:"
  347.           } ;
  348.  
  349.      static BITS poly[] =
  350.           {
  351.           PC_POLYGON,    "PC_POLYGON",    "alternate fill polygon:",
  352.           PC_RECTANGLE,  "PC_RECTANGLE",  "rectangle:",
  353.           PC_WINDPOLYGON,"PC_WINDPOLYGON","winding number fill polygon:",
  354.           PC_SCANLINE,   "PC_SCANLINE",   "scanlines:",
  355.           PC_WIDE,       "PC_WIDE",       "wide borders:",
  356.           PC_STYLED,     "PC_STYLED",     "styled borders:",
  357.           PC_WIDESTYLED, "PC_WIDESTYLED", "wide and styled borders:",
  358.           PC_INTERIORS,  "PC_INTERIORS",  "interiors:"
  359.           } ;
  360.  
  361.      static BITS text[] =
  362.           {
  363.           TC_OP_CHARACTER, "TC_OP_CHARACTER", "character output precision:",
  364.           TC_OP_STROKE,    "TC_OP_STROKE",    "stroke output precision:",
  365.           TC_CP_STROKE,    "TC_CP_STROKE",    "stroke clip precision:",
  366.           TC_CR_90,        "TC_CP_90",        "90 degree character rotation:",
  367.           TC_CR_ANY,       "TC_CR_ANY",       "any character rotation:",
  368.           TC_SF_X_YINDEP,  "TC_SF_X_YINDEP",  "scaling independent of X and Y:",
  369.           TC_SA_DOUBLE,    "TC_SA_DOUBLE",    "doubled character for scaling:",
  370.           TC_SA_INTEGER,   "TC_SA_INTEGER",   "integer multiples for scaling:",
  371.           TC_SA_CONTIN,    "TC_SA_CONTIN",    "any multiples for exact scaling:",
  372.           TC_EA_DOUBLE,    "TC_EA_DOUBLE",    "double weight characters:",
  373.           TC_IA_ABLE,      "TC_IA_ABLE",      "italicizing:",
  374.           TC_UA_ABLE,      "TC_UA_ABLE",      "underlining:",
  375.           TC_SO_ABLE,      "TC_SO_ABLE",      "strikeouts:",
  376.           TC_RA_ABLE,      "TC_RA_ABLE",      "raster fonts:",
  377.           TC_VA_ABLE,      "TC_VA_ABLE",      "vector fonts:"
  378.           } ;
  379.  
  380.      static struct
  381.           {
  382.           int   nIndex ;
  383.           char  *szTitle ;
  384.           BITS  (*pbits)[] ;
  385.           short nSize ;
  386.           }
  387.           bitinfo[] =
  388.           {
  389.           CURVECAPS,  "CURVCAPS (Curve Capabilities)",
  390.                       (BITS (*)[]) curves, sizeof (curves) / sizeof (curves[0]),
  391.           LINECAPS,   "LINECAPS (Line Capabilities)",
  392.                       (BITS (*)[]) lines, sizeof (lines) / sizeof (lines[0]),
  393.           POLYGONALCAPS, "POLYGONALCAPS (Polygonal Capabilities)",
  394.                       (BITS (*)[]) poly, sizeof (poly) / sizeof (poly[0]),
  395.           TEXTCAPS,   "TEXTCAPS (Text Capabilities)",
  396.                       (BITS (*)[]) text, sizeof (text) / sizeof (text[0])
  397.           } ;
  398.  
  399.      static char szBuffer[80] ;
  400.      BITS        (*pbits)[] = bitinfo[nType].pbits ;
  401.      int         nDevCaps = GetDeviceCaps (hdcInfo, bitinfo[nType].nIndex) ;
  402.      int         i ;
  403.  
  404.      TextOut (hdc, cxChar, cyChar, bitinfo[nType].szTitle,
  405.                     strlen (bitinfo[nType].szTitle)) ;
  406.  
  407.      for (i = 0 ; i < bitinfo[nType].nSize ; i++)
  408.           TextOut (hdc, cxChar, (i + 3) * cyChar, szBuffer,
  409.                sprintf (szBuffer, "%-16s %s %-32s %3s",
  410.                     (*pbits)[i].szMask, "Can do", (*pbits)[i].szDesc,
  411.                     nDevCaps & (*pbits)[i].nMask ? "Yes" : "No")) ;
  412.      }
  413.