home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows (5th Edition) / Programming Windows, 5th ed. - Companion CD (097-0002183)(1999).iso / Chap13 / DevCaps2 / DevCaps2.c next >
Encoding:
C/C++ Source or Header  |  1998-10-09  |  18.4 KB  |  440 lines

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