DevCaps2.mod: Translation to Stony Brook Modula-2

Last updated: 15. 2.1998, 18: 8

<*/NOWARN:F*>
MODULE DevCaps2;
(*------------------------------------------------------------------
   DEVCAPS2.C      --- Displays Device Capability Information (Version 2)
                   (c) Charles Petzold, 1996
   DevCaps2.mod    --- Translation to Stony Brook Modula-2
                   (c) Peter Stadler,   1997
  ------------------------------------------------------------------*)
%IF WIN32 %THEN
    <*/Resource:DEVCAPS2.RES*>
%ELSE
%END
IMPORT WINUSER;
IMPORT WIN32;
IMPORT WINGDI;
IMPORT WINX;
IMPORT COMMDLG;
IMPORT SYSTEM;
IMPORT WINSPOOL;
IMPORT h2d_devcaps2;
IMPORT Str;

CONST
  szAppName = "DevCaps2";
VAR
  hwnd            :  WIN32.HWND;
  msg             :  WINUSER.MSG;
  wc              :  WINUSER.WNDCLASSEX;
VAR (* static in WndProc *)
  szDevice        :  ARRAY[0..31] OF CHAR;
  szWindowText    :  ARRAY[0..63] OF CHAR;
  n               :  INTEGER;
  cxChar          :  INTEGER;
  cyChar          :  INTEGER;
  nCurrentDevice  :  INTEGER = h2d_devcaps2.IDM_SCREEN;
  nCurrentInfo    :  INTEGER = h2d_devcaps2.IDM_BASIC;
  dwNeeded        :  WIN32.DWORD;
  dwReturned      :  WIN32.DWORD;
  pinfo5          :  WINSPOOL.LPPRINTER_INFO_5;

    (* static in DoBasicInfo *)
TYPE
  Info   =  RECORD
              nIndex   : INTEGER;
              szDesc   : WIN32.LPSTR;
            END;
  InfoArr=  ARRAY[0..19] OF Info;
VAR
  info   :   InfoArr;

    (* static in DoOtherInfo *)
VAR
  clip       : h2d_devcaps2.BITS;

TYPE
  Raster     = ARRAY[0..11] OF h2d_devcaps2.BITS;
VAR
  raster     : Raster;
TYPE
  SzTech     =  ARRAY[0..6] OF WIN32.LPSTR;
VAR
  szTech     :  SzTech;

    (* static in DoBitCodedCaps *)
TYPE
  Curves    =   ARRAY[0..7] OF h2d_devcaps2.BITS;
VAR
  curves    :   Curves;
TYPE
  Lines     =   ARRAY[0..6] OF h2d_devcaps2.BITS;
VAR
  lines     :   Lines;
TYPE
  Poly      =   ARRAY[0..7] OF h2d_devcaps2.BITS;
VAR
  poly      :   Poly;
TYPE
  Text      =   ARRAY[0..14] OF h2d_devcaps2.BITS;
VAR
  text      :   Text;

TYPE
  BITSARRAY = ARRAY[0..14] OF h2d_devcaps2.BITS;
  BitInfo = RECORD
              nIndex   : INTEGER;
              szTitle  : WIN32.LPSTR;
              pbits    : POINTER TO BITSARRAY;
              nSize    : INTEGER (*WIN32.SHORT*);
            END;
  BitInfoArr=  ARRAY[0..3] OF BitInfo;
VAR
  bitinfo       : BitInfoArr;

<*/PUSH*>
%IF WIN32 %THEN
    <*/CALLS:WIN32SYSTEM*>
%ELSE
    <*/CALLS:WINSYSTEM*>
%END
(*++++*****************************************************************)
PROCEDURE WndProc (hwnd        : WIN32.HWND;
                   iMsg        : WIN32.UINT;
                   wParam      : WIN32.WPARAM;
                   lParam      : WIN32.LPARAM) : WIN32.LRESULT [EXPORT];
(**********************************************************************)

VAR
  i           :  WIN32.DWORD;
  hdc         :  WIN32.HDC;
  hdcInfo     :  WIN32.HDC;
  hMenu       :  WIN32.HMENU;
  ps          :  WINUSER.PAINTSTRUCT;
  tm          :  WINGDI.TEXTMETRIC;
  hPrint      :  WIN32.HANDLE;
  pStr        :  WIN32.LPSTR;
BEGIN
     CASE (iMsg) OF
          | WINUSER.WM_CREATE :
               hdc := WINUSER.GetDC (hwnd);
               WINGDI.SelectObject (hdc, WINGDI.GetStockObject (WINGDI.SYSTEM_FIXED_FONT));
               WINGDI.GetTextMetrics (hdc, tm);
               cxChar := tm.tmAveCharWidth;
               cyChar := tm.tmHeight + tm.tmExternalLeading;
               WINUSER.ReleaseDC (hwnd, hdc);

               lParam := 0;
                                                  (* fall through              *)
          | WINUSER.WM_WININICHANGE :
               pStr := SYSTEM.CAST(WIN32.LPSTR,lParam);
               IF(Str.Compare(pStr^,"devices")#0) AND(lParam#0) THEN
                 RETURN 0;
               END;
               hMenu := WINUSER.GetSubMenu (WINUSER.GetMenu (hwnd), 0);

               WHILE (WINUSER.GetMenuItemCount (hMenu) > 1) DO
                    WINUSER.DeleteMenu (hMenu, 1, WINUSER.MF_BYPOSITION);
               END;
               (* Get a list of all local and remote printers                  *)
               (*                                                              *)
               (* First, find out how large an array we need; this             *)
               (*   call will fail, leaving the required size in dwNeeded      *)
               WINSPOOL.EnumPrinters (WINSPOOL.PRINTER_ENUM_LOCAL,
                             WINX.NIL_ASTR, 5, SYSTEM.CAST(WIN32.LPBYTE,SYSTEM.ADR("")), 0, dwNeeded, dwReturned);

               (* Next, allocate space for PRINTER_INFO_5 array          *)
               IF (pinfo5#NIL) THEN
                    WIN32.HeapFree (WIN32.GetProcessHeap (), 0, pinfo5);
               END;
               pinfo5 := SYSTEM.CAST(WINSPOOL.LPPRINTER_INFO_5,WIN32.HeapAlloc (WIN32.GetProcessHeap (),
                                              WIN32.HEAP_NO_SERIALIZE, dwNeeded));

               (* Last, fill allocated PRINTER_INFO_5 array                    *)
               IF (pinfo5=NIL) OR (WINSPOOL.EnumPrinters (WINSPOOL.PRINTER_ENUM_LOCAL,
                                    WINX.NIL_ASTR, 5, SYSTEM.CAST(WIN32.LPBYTE,pinfo5), dwNeeded,
                                    dwNeeded, dwReturned)=TRUE) THEN
                    WINUSER.MessageBox (hwnd, "Could not enumerate printers!",
                                                  "", WINUSER.MB_ICONSTOP);
                    WINUSER.DestroyWindow (hwnd);
                    RETURN 0;
               END;
               n := h2d_devcaps2.IDM_SCREEN+1;
               FOR i := 0 TO dwReturned-1 DO
                    IF(n REM 16#0) THEN
                       WINUSER.AppendMenu (hMenu,  0, n, pinfo5^.pPrinterName^);
                    ELSE
                       WINUSER.AppendMenu (hMenu, WINUSER.MF_MENUBARBREAK, n,pinfo5^.pPrinterName^);
                    END;
                    pinfo5 := SYSTEM.ADDADR(pinfo5,1);
                    INC(n);
               END;

               WINUSER.AppendMenu (hMenu, WINUSER.MF_SEPARATOR, 0, WINX.NIL_ASTR);
               WINUSER.AppendMenu (hMenu, 0, h2d_devcaps2.IDM_DEVMODE, "Properties");

               wParam := h2d_devcaps2.IDM_SCREEN;
                                                  (* fall through              *)
          | WINUSER.WM_COMMAND :
               hMenu := WINUSER.GetMenu (hwnd);

               IF (wParam < h2d_devcaps2.IDM_DEVMODE) THEN          (* IDM_SCREEN BAND Printers     *)
                    WINUSER.CheckMenuItem (hMenu, nCurrentDevice, WINUSER.MF_UNCHECKED);
                    nCurrentDevice := wParam;
                    WINUSER.CheckMenuItem (hMenu, nCurrentDevice, WINUSER.MF_CHECKED);
               ELSIF (wParam = h2d_devcaps2.IDM_DEVMODE) THEN    (* "Properties" selection    *)
                    WINUSER.GetMenuString (hMenu, nCurrentDevice, szDevice,
                                   SIZE (szDevice), WINUSER.MF_BYCOMMAND);
                    IF (WINSPOOL.OpenPrinter (szDevice, hPrint, NIL)) THEN
                         WINSPOOL.PrinterProperties (hwnd, hPrint);
                         WINSPOOL.ClosePrinter (hPrint);
                    END;
               ELSE                               (* info menu items           *)
                    WINUSER.CheckMenuItem (hMenu, nCurrentInfo, WINUSER.MF_UNCHECKED);
                    nCurrentInfo := wParam;
                    WINUSER.CheckMenuItem (hMenu, nCurrentInfo, WINUSER.MF_CHECKED);
               END;
               WINUSER.InvalidateRect (hwnd, WINX.NIL_RECT, TRUE);
               RETURN 0;

          | WINUSER.WM_INITMENUPOPUP :
               IF (lParam = 0) THEN
                    IF(nCurrentDevice = h2d_devcaps2.IDM_SCREEN) THEN
                      WINUSER.EnableMenuItem (WINUSER.GetMenu (hwnd), h2d_devcaps2.IDM_DEVMODE,WINUSER.MF_GRAYED);
                    ELSE
                      WINUSER.EnableMenuItem (WINUSER.GetMenu (hwnd), h2d_devcaps2.IDM_DEVMODE,WINUSER.MF_ENABLED);
                    END;
               END;
               RETURN 0;

          | WINUSER.WM_PAINT :
               Str.Copy(szWindowText,"Device Capabilities: ");

               IF (nCurrentDevice = h2d_devcaps2.IDM_SCREEN) THEN
                    Str.Copy(szDevice, "DISPLAY");
                    hdcInfo := WINGDI.CreateIC (szDevice, WINX.NIL_ASTR, WINX.NIL_ASTR, WINX.NIL_DEVMODEA);
               ELSE
                    hMenu := WINUSER.GetMenu (hwnd);
                    WINUSER.GetMenuString (hMenu, nCurrentDevice, szDevice,
                                   SIZE (szDevice), WINUSER.MF_BYCOMMAND);
                    hdcInfo := WINGDI.CreateIC (WINX.NIL_ASTR, szDevice, WINX.NIL_ASTR, WINX.NIL_DEVMODEA);
               END;

               Str.Append(szWindowText, szDevice);
               WINUSER.SetWindowText (hwnd, szWindowText);

               hdc := WINUSER.BeginPaint (hwnd, ps);
               WINGDI.SelectObject (hdc, WINGDI.GetStockObject (WINGDI.SYSTEM_FIXED_FONT));

               IF (hdcInfo#NIL) THEN
                    CASE (nCurrentInfo) OF
                         | h2d_devcaps2.IDM_BASIC :
                              DoBasicInfo (hdc, hdcInfo, cxChar, cyChar);
                              RETURN 0;

                         | h2d_devcaps2.IDM_OTHER :
                              DoOtherInfo (hdc, hdcInfo, cxChar, cyChar);
                              RETURN 0;

                         | h2d_devcaps2.IDM_CURVE :
                              DoBitCodedCaps (hdc, hdcInfo, cxChar, cyChar,
                                   nCurrentInfo - h2d_devcaps2.IDM_CURVE);
                         | h2d_devcaps2.IDM_LINE :
                              DoBitCodedCaps (hdc, hdcInfo, cxChar, cyChar,
                                   nCurrentInfo - h2d_devcaps2.IDM_CURVE);
                         | h2d_devcaps2.IDM_POLY :
                              DoBitCodedCaps (hdc, hdcInfo, cxChar, cyChar,
                                   nCurrentInfo - h2d_devcaps2.IDM_CURVE);
                         | h2d_devcaps2.IDM_TEXT :
                              DoBitCodedCaps (hdc, hdcInfo, cxChar, cyChar,
                                   nCurrentInfo - h2d_devcaps2.IDM_CURVE);
                    ELSE
                      WINGDI.DeleteDC (hdcInfo);
                    END;
               END;

               WINUSER.EndPaint (hwnd, ps);
               RETURN 0;

          | WINUSER.WM_DESTROY :
               IF (pinfo5#NIL) THEN
                    WIN32.HeapFree (WIN32.GetProcessHeap (), 0, pinfo5);
               END;

               WINUSER.PostQuitMessage (0);
               RETURN 0;
     ELSE
        RETURN WINUSER.DefWindowProc (hwnd, iMsg, wParam, lParam);
     END;
END WndProc;
<*/POP*>

(*++++*****************************************************************)
PROCEDURE DoBasicInfo (hdc      :  WIN32.HDC;
                       hdcInfo  :  WIN32.HDC;
                       cxChar   :  INTEGER;
                       cyChar   :  INTEGER);
(**********************************************************************)
VAR
  szBuffer  :  ARRAY[0..79] OF CHAR;
  i         :  INTEGER;
BEGIN
     FOR i := 0 TO (SIZE (info) DIV SIZE (info[0]))-1 DO
          WINGDI.TextOut (hdc, cxChar, (i + 1) * cyChar, szBuffer,
               WINUSER.wsprintf (szBuffer, "%-40s%8d", info[i].szDesc,
                    WINGDI.GetDeviceCaps (hdcInfo, info[i].nIndex)));
     END;

END DoBasicInfo;

(*++++*****************************************************************)
PROCEDURE DoOtherInfo (hdc      :  WIN32.HDC;
                       hdcInfo  :  WIN32.HDC;
                       cxChar   :  INTEGER;
                       cyChar   :  INTEGER);
(**********************************************************************)
VAR
  szBuffer     :  ARRAY[0..79] OF CHAR;
  i            :  INTEGER;
BEGIN
     WINGDI.TextOut (hdc, cxChar, cyChar, szBuffer,
          WINUSER.wsprintf (szBuffer, "%-24s%04XH",
               "DRIVERVERSION:", WINGDI.GetDeviceCaps (hdcInfo, WINGDI.DRIVERVERSION)));

     WINGDI.TextOut (hdc, cxChar, 2 * cyChar, szBuffer,
          WINUSER.wsprintf (szBuffer, "%-24s%-40s", "TECHNOLOGY:",
                           szTech[WINGDI.GetDeviceCaps (hdcInfo, WINGDI.TECHNOLOGY)]));

     WINGDI.TextOut (hdc, cxChar, 4 * cyChar, szBuffer,
          WINUSER.wsprintf (szBuffer, "CLIPCAPS (Clipping capabilities)"));

     FOR i := 0 TO (SIZE (clip) DIV SIZE (clip.nMask))-1 DO
          IF( (WINGDI.GetDeviceCaps (hdcInfo, WINGDI.CLIPCAPS) BAND VAL(INTEGER,clip.nMask))=1) THEN
              WINGDI.TextOut (hdc, 9 * cxChar, (i + 6) * cyChar, szBuffer,
               WINUSER.wsprintf (szBuffer, "%-16s%-28s %3s",
                    clip.szMask, clip.szDesc,"Yes"));
          ELSE
              WINGDI.TextOut (hdc, 9 * cxChar, (i + 6) * cyChar, szBuffer,
               WINUSER.wsprintf (szBuffer, "%-16s%-28s %3s",
                    clip.szMask, clip.szDesc,"No"));
          END;

     END;
     WINGDI.TextOut (hdc, cxChar, 8 * cyChar, szBuffer,
          WINUSER.wsprintf (szBuffer, "RASTERCAPS (Raster capabilities)"));

     FOR i := 0 TO (SIZE (raster) DIV SIZE (raster[0]))-1 DO
          IF(WINGDI.GetDeviceCaps (hdcInfo, WINGDI.RASTERCAPS) BAND VAL(INTEGER,raster[i].nMask)=1) THEN
               WINGDI.TextOut (hdc, 9 * cxChar, (i + 10) * cyChar, szBuffer,
               WINUSER.wsprintf (szBuffer, "%-16s%-28s %3s",
                    raster[i].szMask, raster[i].szDesc,"Yes"))
          ELSE
           WINGDI.TextOut (hdc, 9 * cxChar, (i + 10) * cyChar, szBuffer,
               WINUSER.wsprintf (szBuffer, "%-16s%-28s %3s",
                    raster[i].szMask, raster[i].szDesc,"No"));
          END;
     END;
END DoOtherInfo;

(*++++*****************************************************************)
PROCEDURE DoBitCodedCaps (hdc      :  WIN32.HDC;
                          hdcInfo  :  WIN32.HDC;
                          cxChar   :  INTEGER;
                          cyChar   :  INTEGER;
                          nType    :  INTEGER);
(**********************************************************************)
TYPE
  PBITSARRAY =  POINTER TO BITSARRAY;
VAR
  szBuffer   :  ARRAY[0..79] OF CHAR;
  pbits      :  PBITSARRAY;
  (*
  pbits      :  ARRAY[0..14] OF POINTER TO h2d_devcaps2.BITS;
  *)
  nDevCaps   :  INTEGER;
  i          :  INTEGER(*16*);
BEGIN
     pbits := SYSTEM.CAST(PBITSARRAY,bitinfo[nType].pbits);
     nDevCaps := WINGDI.GetDeviceCaps (hdcInfo, bitinfo[nType].nIndex);

     WINGDI.TextOut (hdc, cxChar, cyChar, bitinfo[nType].szTitle^,
                    LENGTH(bitinfo[nType].szTitle^));

     FOR i := 0 TO bitinfo[nType].nSize-1 DO
          IF(nDevCaps BAND VAL(INTEGER,pbits^[i].nMask)=1) THEN
               WINGDI.TextOut (hdc, cxChar, (i + 3) * cyChar, szBuffer,
               WINUSER.wsprintf (szBuffer, "%-16s %s %-32s %3s",
                    pbits^[i].szMask, "Can do", pbits^[i].szDesc,
                    "Yes"));
          ELSE
               WINGDI.TextOut (hdc, cxChar, (i + 3) * cyChar, szBuffer,
               WINUSER.wsprintf (szBuffer, "%-16s %s %-32s %3s",
                    pbits^[i].szMask, "Can do", pbits^[i].szDesc,
                    "No"));
          END;
     END;
END DoBitCodedCaps;
(*++++*****************************************************************)
PROCEDURE InitApplication () : BOOLEAN;
(**********************************************************************)
VAR
  rc   :  CARDINAL;
BEGIN
  wc.cbSize        := SIZE(wc);
  wc.style         := WINUSER.CS_HREDRAW BOR WINUSER.CS_VREDRAW;
  wc.lpfnWndProc   := WndProc;
  wc.cbClsExtra    := 0;
  wc.cbWndExtra    := 0;
  wc.hInstance     := WINX.Instance;
  wc.hIcon         := WINUSER.LoadIcon (NIL, WINUSER.IDI_APPLICATION^);
  wc.hCursor       := WINUSER.LoadCursor (NIL, WINUSER.IDC_ARROW^);
  wc.hbrBackground := SYSTEM.CAST(WIN32.HBRUSH, WINGDI.GetStockObject (WINGDI.WHITE_BRUSH));
  wc.lpszMenuName  := SYSTEM.ADR(szAppName);
  wc.lpszClassName := SYSTEM.ADR(szAppName);
  wc.hIconSm       := WINUSER.LoadIcon (NIL, WINUSER.IDI_APPLICATION^);

  rc := WINUSER.RegisterClassEx(wc);
  RETURN rc#0;
END InitApplication;

(*++++*****************************************************************)
PROCEDURE InitMainWindow () : BOOLEAN;
(**********************************************************************)
BEGIN
  hwnd := WINUSER.CreateWindow (
                       szAppName,                      (* window class name            *)
                       "",                             (* window caption               *)
                       WINUSER.WS_OVERLAPPEDWINDOW,    (* window style                 *)
                       WINUSER.CW_USEDEFAULT,          (* initial x position           *)
                       WINUSER.CW_USEDEFAULT,          (* initial y position           *)
                       WINUSER.CW_USEDEFAULT,          (* initial x size               *)
                       WINUSER.CW_USEDEFAULT,          (* initial y size               *)
                       NIL,                            (* parent window handle         *)
                       NIL,                            (* window menu handle           *)
                       WINX.Instance,                  (* program instance handle      *)
                       NIL);                           (* creation parameters          *)

  IF hwnd = NIL THEN
    RETURN FALSE;
  END;
  WINUSER.ShowWindow (hwnd, WINUSER.SW_SHOWDEFAULT);
  WINUSER.UpdateWindow (hwnd);
  RETURN TRUE;
END InitMainWindow;
(*++++*****************************************************************)
BEGIN
  info       := InfoArr
       {
         {WINGDI.HORZSIZE,      SYSTEM.ADR("HORZSIZE     Width in millimeters:")},
         {WINGDI.VERTSIZE,      SYSTEM.ADR("VERTSIZE     Height in millimeters:")},
         {WINGDI.HORZRES,       SYSTEM.ADR("HORZRES      Width in pixels:")},
         {WINGDI.VERTRES,       SYSTEM.ADR("VERTRES      Height in raster lines:")},
         {WINGDI.BITSPIXEL,     SYSTEM.ADR("BITSPIXEL    Color bits per pixel:")},
         {WINGDI.PLANES,        SYSTEM.ADR("PLANES       Number of color planes:")},
         {WINGDI.NUMBRUSHES,    SYSTEM.ADR("NUMBRUSHES   Number of device brushes:")},
         {WINGDI.NUMPENS,       SYSTEM.ADR("NUMPENS      Number of device pens:")},
         {WINGDI.NUMMARKERS,    SYSTEM.ADR("NUMMARKERS   Number of device markers:")},
         {WINGDI.NUMFONTS,      SYSTEM.ADR("NUMFONTS     Number of device fonts:")},
         {WINGDI.NUMCOLORS,     SYSTEM.ADR("NUMCOLORS    Number of device colors:")},
         {WINGDI.PDEVICESIZE,   SYSTEM.ADR("PDEVICESIZE  Size of device structure:")},
         {WINGDI.ASPECTX,       SYSTEM.ADR("ASPECTX      Relative width of pixel:")},
         {WINGDI.ASPECTY,       SYSTEM.ADR("ASPECTY      Relative height of pixel:")},
         {WINGDI.ASPECTXY,      SYSTEM.ADR("ASPECTXY     Relative diagonal of pixel:")},
         {WINGDI.LOGPIXELSX,    SYSTEM.ADR("LOGPIXELSX   Horizontal dots per inch:")},
         {WINGDI.LOGPIXELSY,    SYSTEM.ADR("LOGPIXELSY   Vertical dots per inch:")},
         {WINGDI.SIZEPALETTE,   SYSTEM.ADR("SIZEPALETTE  Number of palette entries:")},
         {WINGDI.NUMRESERVED,   SYSTEM.ADR("NUMRESERVED  Reserved palette entries:")},
         {WINGDI.COLORRES,      SYSTEM.ADR("COLORRES     Actual color resolution:")}
       };
  clip       := h2d_devcaps2.BITS
          {
            WINGDI.CP_RECTANGLE,  SYSTEM.ADR("CP_RECTANGLE"),     SYSTEM.ADR("Can Clip To Rectangle:")
          };

  raster     := Raster
      {
         {WINGDI.RC_BITBLT,       SYSTEM.ADR("RC_BITBLT"),      SYSTEM.ADR("Capable of simple BitBlt:")},
         {WINGDI.RC_BANDING,      SYSTEM.ADR("RC_BANDING"),     SYSTEM.ADR("Requires banding support:")},
         {WINGDI.RC_SCALING,      SYSTEM.ADR("RC_SCALING"),     SYSTEM.ADR("Requires scaling support:")},
         {WINGDI.RC_BITMAP64,     SYSTEM.ADR("RC_BITMAP64"),    SYSTEM.ADR("Supports bitmaps >64K:")},
         {WINGDI.RC_GDI20_OUTPUT, SYSTEM.ADR("RC_GDI20_OUTPUT"),SYSTEM.ADR("Has 2.0 output calls:")},
         {WINGDI.RC_DI_BITMAP,    SYSTEM.ADR("RC_DI_BITMAP"),   SYSTEM.ADR("Supports DIB to memory:")},
         {WINGDI.RC_PALETTE,      SYSTEM.ADR("RC_PALETTE"),     SYSTEM.ADR("Supports a palette:")},
         {WINGDI.RC_DIBTODEV,     SYSTEM.ADR("RC_DIBTODEV"),    SYSTEM.ADR("Supports bitmap conversion:")},
         {WINGDI.RC_BIGFONT,      SYSTEM.ADR("RC_BIGFONT"),     SYSTEM.ADR("Supports fonts >64K:")},
         {WINGDI.RC_STRETCHBLT,   SYSTEM.ADR("RC_STRETCHBLT"),  SYSTEM.ADR("Supports StretchBlt:")},
         {WINGDI.RC_FLOODFILL,    SYSTEM.ADR("RC_FLOODFILL"),   SYSTEM.ADR("Supports FloodFill:")},
         {WINGDI.RC_STRETCHDIB,   SYSTEM.ADR("RC_STRETCHDIB"),  SYSTEM.ADR("Supports StretchDIBits:")}
      };

  szTech     := SzTech
                              {SYSTEM.ADR("DT_PLOTTER (Vector plotter)"),
                               SYSTEM.ADR("DT_RASDISPLAY (Raster display)"),
                               SYSTEM.ADR("DT_RASPRINTER (Raster printer)"),
                               SYSTEM.ADR("DT_RASCAMERA (Raster camera)"),
                               SYSTEM.ADR("DT_CHARSTREAM (Character-stream, PLP)"),
                               SYSTEM.ADR("DT_METAFILE (Metafile, VDM)"),
                               SYSTEM.ADR("DT_DISPFILE (Display-file)")
                              };


  curves     :=  Curves
      {
         {WINGDI.CC_CIRCLES,    SYSTEM.ADR("CC_CIRCLES"),   SYSTEM.ADR("circles:")},
         {WINGDI.CC_PIE,        SYSTEM.ADR("CC_PIE"),       SYSTEM.ADR("pie wedges:")},
         {WINGDI.CC_CHORD,      SYSTEM.ADR("CC_CHORD"),     SYSTEM.ADR("chord arcs:")},
         {WINGDI.CC_ELLIPSES,   SYSTEM.ADR("CC_ELLIPSES"),  SYSTEM.ADR("ellipses:")},
         {WINGDI.CC_WIDE,       SYSTEM.ADR("CC_WIDE"),      SYSTEM.ADR("wide borders:")},
         {WINGDI.CC_STYLED,     SYSTEM.ADR("CC_STYLED"),    SYSTEM.ADR("styled borders:")},
         {WINGDI.CC_WIDESTYLED, SYSTEM.ADR("CC_WIDESTYLED"),SYSTEM.ADR("wide and styled borders:")},
         {WINGDI.CC_INTERIORS,  SYSTEM.ADR("CC_INTERIORS"), SYSTEM.ADR("interiors:")}
       };
  lines     :=   Lines
       {
         {WINGDI.LC_POLYLINE,   SYSTEM.ADR("LC_POLYLINE"),  SYSTEM.ADR("polyline:")},
         {WINGDI.LC_MARKER,     SYSTEM.ADR("LC_MARKER"),    SYSTEM.ADR("markers:")},
         {WINGDI.LC_POLYMARKER, SYSTEM.ADR("LC_POLYMARKER"),SYSTEM.ADR("polymarkers")},
         {WINGDI.LC_WIDE,       SYSTEM.ADR("LC_WIDE"),      SYSTEM.ADR("wide lines:")},
         {WINGDI.LC_STYLED,     SYSTEM.ADR("LC_STYLED"),    SYSTEM.ADR("styled lines:")},
         {WINGDI.LC_WIDESTYLED, SYSTEM.ADR("LC_WIDESTYLED"),SYSTEM.ADR("wide and styled lines:")},
         {WINGDI.LC_INTERIORS,  SYSTEM.ADR("LC_INTERIORS"), SYSTEM.ADR("interiors:")}
       };
  poly      :=   Poly
       {
         {WINGDI.PC_POLYGON,    SYSTEM.ADR("PC_POLYGON"),    SYSTEM.ADR("alternate fill polygon:")},
         {WINGDI.PC_RECTANGLE,  SYSTEM.ADR("PC_RECTANGLE"),  SYSTEM.ADR("rectangle:")},
         {WINGDI.PC_WINDPOLYGON,SYSTEM.ADR("PC_WINDPOLYGON"),SYSTEM.ADR("winding number fill polygon:")},
         {WINGDI.PC_SCANLINE,   SYSTEM.ADR("PC_SCANLINE"),   SYSTEM.ADR("scanlines:")},
         {WINGDI.PC_WIDE,       SYSTEM.ADR("PC_WIDE"),       SYSTEM.ADR("wide borders:")},
         {WINGDI.PC_STYLED,     SYSTEM.ADR("PC_STYLED"),     SYSTEM.ADR("styled borders:")},
         {WINGDI.PC_WIDESTYLED, SYSTEM.ADR("PC_WIDESTYLED"), SYSTEM.ADR("wide and styled borders:")},
         {WINGDI.PC_INTERIORS,  SYSTEM.ADR("PC_INTERIORS"),  SYSTEM.ADR("interiors:")}
       };

  text      :=  Text
       {
         {WINGDI.TC_OP_CHARACTER, SYSTEM.ADR("TC_OP_CHARACTER"), SYSTEM.ADR("character output precision:")},
         {WINGDI.TC_OP_STROKE,    SYSTEM.ADR("TC_OP_STROKE"),    SYSTEM.ADR("stroke output precision:")},
         {WINGDI.TC_CP_STROKE,    SYSTEM.ADR("TC_CP_STROKE"),    SYSTEM.ADR("stroke clip precision:")},
         {WINGDI.TC_CR_90,        SYSTEM.ADR("TC_CP_90"),        SYSTEM.ADR("90 degree character rotation:")},
         {WINGDI.TC_CR_ANY,       SYSTEM.ADR("TC_CR_ANY"),       SYSTEM.ADR("any character rotation:")},
         {WINGDI.TC_SF_X_YINDEP,  SYSTEM.ADR("TC_SF_X_YINDEP"),  SYSTEM.ADR("scaling independent of X and Y:")},
         {WINGDI.TC_SA_DOUBLE,    SYSTEM.ADR("TC_SA_DOUBLE"),    SYSTEM.ADR("doubled character for scaling:")},
         {WINGDI.TC_SA_INTEGER,   SYSTEM.ADR("TC_SA_INTEGER"),   SYSTEM.ADR("integer multiples for scaling:")},
         {WINGDI.TC_SA_CONTIN,    SYSTEM.ADR("TC_SA_CONTIN"),    SYSTEM.ADR("any multiples for exact scaling:")},
         {WINGDI.TC_EA_DOUBLE,    SYSTEM.ADR("TC_EA_DOUBLE"),    SYSTEM.ADR("double weight characters:")},
         {WINGDI.TC_IA_ABLE,      SYSTEM.ADR("TC_IA_ABLE"),      SYSTEM.ADR("italicizing:")},
         {WINGDI.TC_UA_ABLE,      SYSTEM.ADR("TC_UA_ABLE"),      SYSTEM.ADR("underlining:")},
         {WINGDI.TC_SO_ABLE,      SYSTEM.ADR("TC_SO_ABLE"),      SYSTEM.ADR("strikeouts:")},
         {WINGDI.TC_RA_ABLE,      SYSTEM.ADR("TC_RA_ABLE"),      SYSTEM.ADR("raster fonts:")},
         {WINGDI.TC_VA_ABLE,      SYSTEM.ADR("TC_VA_ABLE"),      SYSTEM.ADR("vector fonts:")}
       };

  bitinfo       := BitInfoArr
       {
         {WINGDI.CURVECAPS,  SYSTEM.ADR("CURVCAPS (Curve Capabilities)"),
                      SYSTEM.ADR(curves), SIZE (curves) DIV SIZE (curves[0])},
         {WINGDI.LINECAPS,   SYSTEM.ADR("LINECAPS (Line Capabilities)"),
                      SYSTEM.ADR(lines), SIZE (lines) DIV SIZE (lines[0])},
         {WINGDI.POLYGONALCAPS, SYSTEM.ADR("POLYGONALCAPS (Polygonal Capabilities)"),
                      SYSTEM.ADR(poly), SIZE (poly) DIV SIZE (poly[0])},
         {WINGDI.TEXTCAPS,   SYSTEM.ADR("TEXTCAPS (Text Capabilities)"),
                      SYSTEM.ADR(text), SIZE (text) DIV SIZE (text[0])}
       };








  IF InitApplication()  AND  InitMainWindow() THEN
    WHILE (WINUSER.GetMessage(msg,NIL,0,0)) DO
          WINUSER.TranslateMessage(msg);
          WINUSER.DispatchMessage(msg);
    END;
  END;
END DevCaps2.