GetDeviceCaps

Procedure GetDeviceCaps allows you to find many device capabilities, like: how many colors can be displayed, can a font be scaled or rotated, is the device capable of drawing lines or circles.
The "Device" can be the display but the procedure is also important for measuring the capabilities of a printer device, because your print routine may have to use different logic for penplotters or laserprinters or matrixprinters. Of course Windows can not actually measure the device but has to rely on the the device driver written by the manufacturer of the device.
You will use this procedure often together with GetSystemMetrics (to find out the dimensions of scrollbars or other objects) and with DeviceCapabilities (for printers only, to find info about paper sizes, orientation, number of bins and more)

How many colors can be displayed on screen?

A TrueColor picture can not be displayed when the display is configured for only 16 colors. At least not nicely. Suppose you have different sets of pictures for different display settings and now you want your program to decide which ones to use. You can do this by calling GetDeviceCaps, asking for the value on the BITSPIXEL index.

  {windows.i}
  &GLOBAL-DEFINE BITSPIXEL 12
 
  DEFINE VARIABLE ncolors AS INTEGER NO-UNDO.
  DEFINE VARIABLE txt AS CHARACTER NO-UNDO.
 
  RUN GetDisplayCaps( INPUT {&BITSPIXEL}, OUTPUT ncolors). 
 
  CASE ncolors :
     WHEN  1 THEN txt = "16 colors".
     WHEN  8 THEN txt = "256 colors".
     WHEN 16 THEN txt = "High Color (16 bits per pixel)".
     WHEN 24 THEN txt = "True Color (24 bits per pixel)".
     WHEN 32 THEN txt = "True Color (32 bits per pixel)".
     OTHERWISE    txt = "an unusual color depth!".
  END CASE.
 
  MESSAGE "your display is configured for " txt
          VIEW-AS ALERT-BOX.

Procedure GetDisplayCaps is a wrapper for the GetDeviceCaps and only works for the Display device. That's because the HDC (handle to device context) is used for a window. Any window will do, because all windows are on the same screen... This procedure uses the Progress DEFAULT-WINDOW because it always exists. If you want to find capabilities of a printer, you don't use GetDC but CreateDC.

PROCEDURE GetDisplayCaps :
  /* Wrapper for GetDeviceCaps when Device=display   */
  DEFINE INPUT PARAMETER  cap-index  AS INTEGER NO-UNDO.
  DEFINE OUTPUT PARAMETER capability AS INTEGER NO-UNDO.
 
  DEFINE VARIABLE hdc AS INTEGER NO-UNDO.
  DEFINE VARIABLE OK  AS INTEGER NO-UNDO.
  RUN GetDC IN hpApi(INPUT DEFAULT-WINDOW:HWND, OUTPUT hdc).
  RUN GetDeviceCaps IN hpApi(INPUT hdc,INPUT cap-index, OUTPUT capability). 
  RUN ReleaseDC IN hpApi(INPUT DEFAULT-WINDOW:HWND, INPUT hdc, OUTPUT OK).
END PROCEDURE.