// ----------------------------------------
// Определение возможностей устройств
// ----------------------------------------

#define STRICT
#include <windows.h>
#include <stdio.h>
#include <string.h>

// Прототипы функций
void PrintD(int, char *);
void PrintH(int, char *);
void PrintFlag(int, int, char *);


FILE *out;     // файл для вывода
HDC hdc;       // идентификатор контекста
char buf[80];  // рабочий буфер
int i;         // рабочая переменная

// ===========================================
// Функция WinMain
// ===========================================

#pragma argsused

int PASCAL
WinMain(HINSTANCE hInstance,
		HINSTANCE hPrevInstance,
		LPSTR     lpszCmdLine,
		int       nCmdShow)
{

  // Открываем выходной файл для вывода
  // текста потоком
  // Если открыть файл не удалось, выводим
  // сообщение об ошибке
  if ((out = fopen("devcap.txt", "wt")) == NULL)
  {
    MessageBox(NULL,
     "Не могу открыть файл sysmet.txt",
     "Ошибка", MB_OK | MB_ICONSTOP);
    return 1;
  }

  // Выводим заголовок файла
  fputs("* ============================ *\n", out);
  fputs("* DCAPS, (C) Frolov A.V., 1994 *\n", out);
  fputs("* ============================ *\n\n", out);

  // Создаем контекст устройства для дисплея
  hdc = CreateDC("DISPLAY", NULL, NULL, NULL);

  // Выводим основные характеристики устройства

  PrintH(DRIVERVERSION, "DRIVERVERSION");
  PrintD(ASPECTX,       "ASPECTX      ");
  PrintD(ASPECTXY,      "ASPECTXY     ");
  PrintD(ASPECTY,       "ASPECTY      ");
  PrintD(BITSPIXEL,     "BITSPIXEL    ");
  PrintD(COLORRES,      "COLORRES     ");
  PrintD(HORZRES,       "HORZRES      ");
  PrintD(HORZSIZE,      "HORZSIZE     ");
  PrintD(LOGPIXELSX,    "LOGPIXELSX   ");
  PrintD(LOGPIXELSY,    "LOGPIXELSY   ");
  PrintD(NUMBRUSHES,    "NUMBRUSHES   ");
  PrintD(NUMCOLORS,     "NUMCOLORS    ");
  PrintD(NUMFONTS,      "NUMFONTS     ");
  PrintD(NUMMARKERS,    "NUMMARKERS   ");
  PrintD(NUMPENS,       "NUMPENS      ");
  PrintD(NUMRESERVED,   "NUMRESERVED  ");
  PrintD(PDEVICESIZE,   "PDEVICESIZE  ");
  PrintD(PLANES,        "PLANES       ");
  PrintD(SIZEPALETTE,   "SIZEPALETTE  ");
  PrintD(VERTRES,       "VERTRES      ");
  PrintD(VERTSIZE,      "VERTSIZE     ");

  fputs("-------------------------------\n", out);
  PrintH(CLIPCAPS,  "CLIPCAPS   ");
  fputs("-------------------------------\n", out);
  PrintFlag(CLIPCAPS, CP_NONE,      "CP_NONE          ");
  PrintFlag(CLIPCAPS, CP_RECTANGLE, "CP_RECTANGLE     ");
  PrintFlag(CLIPCAPS, CP_REGION,    "CP_REGION        ");

  fputs("-------------------------------\n", out);
  PrintH(CURVECAPS, "CURVECAPS  ");
  fputs("-------------------------------\n", out);
  PrintFlag(CURVECAPS, CC_CIRCLES,   "CC_CIRCLES      ");
  PrintFlag(CURVECAPS, CC_CHORD,     "CC_CHORD     	");
  PrintFlag(CURVECAPS, CC_ELLIPSES,  "CC_ELLIPSES		");
  PrintFlag(CURVECAPS, CC_INTERIORS, "CC_INTERIORS    ");
  PrintFlag(CURVECAPS, CC_NONE,      "CC_NONE      	");
  PrintFlag(CURVECAPS, CC_PIE,       "CC_PIE       	");
  PrintFlag(CURVECAPS, CC_ROUNDRECT, "CC_ROUNDRECT 	");
  PrintFlag(CURVECAPS, CC_STYLED,    "CC_STYLED    	");
  PrintFlag(CURVECAPS, CC_WIDE,      "CC_WIDE      	");
  PrintFlag(CURVECAPS, CC_WIDESTYLED,"CC_WIDESTYLED	");

  fputs("-------------------------------\n", out);
  PrintH(LINECAPS,  "LINECAPS   ");
  fputs("-------------------------------\n", out);
  PrintFlag(LINECAPS, LC_INTERIORS, "LC_INTERIORS     ");
  PrintFlag(LINECAPS, LC_MARKER,    "LC_MARKER        ");
  PrintFlag(LINECAPS, LC_NONE,      "LC_NONE          ");
  PrintFlag(LINECAPS, LC_POLYLINE,  "LC_POLYLINE      ");
  PrintFlag(LINECAPS, LC_POLYMARKER,"LC_POLYMARKER    ");
  PrintFlag(LINECAPS, LC_STYLED,    "LC_STYLED        ");
  PrintFlag(LINECAPS, LC_WIDE,      "LC_WIDE          ");
  PrintFlag(LINECAPS, LC_WIDESTYLED,"LC_WIDESTYLED    ");

  fputs("-------------------------------\n", out);
  PrintH(POLYGONALCAPS,"POLYGONALCAPS   ");
  fputs("-------------------------------\n", out);
  PrintFlag(POLYGONALCAPS, PC_INTERIORS, "PC_INTERIORS     ");
  PrintFlag(POLYGONALCAPS, PC_NONE,      "PC_NONE          ");
  PrintFlag(POLYGONALCAPS, PC_POLYGON,   "PC_POLYGON       ");
  PrintFlag(POLYGONALCAPS, PC_RECTANGLE, "PC_RECTANGLE     ");
  PrintFlag(POLYGONALCAPS, PC_SCANLINE,  "PC_SCANLINE      ");
  PrintFlag(POLYGONALCAPS, PC_STYLED,    "PC_STYLED        ");
  PrintFlag(POLYGONALCAPS, PC_WIDE,      "PC_WIDE          ");
  PrintFlag(POLYGONALCAPS, PC_WIDESTYLED,"PC_WIDESTYLED    ");

  fputs("-------------------------------\n", out);
  PrintH(RASTERCAPS,"RASTERCAPS   ");
  fputs("-------------------------------\n", out);
  PrintFlag(RASTERCAPS, RC_BANDING,      "RC_BANDING       ");
  PrintFlag(RASTERCAPS, RC_BIGFONT,      "RC_BIGFONT       ");
  PrintFlag(RASTERCAPS, RC_BITBLT,       "RC_BITBLT        ");
  PrintFlag(RASTERCAPS, RC_BITMAP64,     "RC_BITMAP64      ");
  PrintFlag(RASTERCAPS, RC_DEVBITS,      "RC_DEVBITS       ");
  PrintFlag(RASTERCAPS, RC_DI_BITMAP,    "RC_DI_BITMAP     ");
  PrintFlag(RASTERCAPS, RC_DIBTODEV,     "RC_DIBTODEV      ");
  PrintFlag(RASTERCAPS, RC_FLOODFILL,    "RC_FLOODFILL     ");
  PrintFlag(RASTERCAPS, RC_GDI20_OUTPUT, "RC_GDI20_OUTPUT  ");
  PrintFlag(RASTERCAPS, RC_GDI20_STATE,  "RC_GDI20_STATE   ");
  PrintFlag(RASTERCAPS, 0 /*RC_NONE*/,   "RC_NONE          ");
  PrintFlag(RASTERCAPS, RC_OP_DX_OUTPUT, "RC_PO_DX_OUTPUT  ");
  PrintFlag(RASTERCAPS, RC_PALETTE,      "RC_PALETTE       ");
  PrintFlag(RASTERCAPS, RC_SAVEBITMAP,   "RC_SAVEBITMAP    ");
  PrintFlag(RASTERCAPS, RC_SCALING,      "RC_SCALING       ");
  PrintFlag(RASTERCAPS, RC_STRETCHBLT,   "RC_STRETCHBLT    ");
  PrintFlag(RASTERCAPS, RC_STRETCHDIB,   "RC_STRETCHDIB    ");

  fputs("-------------------------------\n", out);
  PrintH(TECHNOLOGY,"TECHNOLOGY");
  fputs("-------------------------------\n", out);

  strcpy(buf, "Технология: ");

  i = GetDeviceCaps(hdc, TECHNOLOGY);
  switch (i)
  {
  case DT_CHARSTREAM:
	 strcat(buf, "DT_CHARSTREAM");
	 break;
  case DT_DISPFILE:
	 strcat(buf, "DT_DISPFILE");
	 break;
  case DT_METAFILE:
	 strcat(buf, "DT_METAFILE");
	 break;
  case DT_PLOTTER:
	 strcat(buf, "DT_PLOTTER");
	 break;
  case DT_RASDISPLAY:
	 strcat(buf, "DT_RASDISPLAY");
	 break;
  case DT_RASPRINTER:
	 strcat(buf, "DT_RASPRINTER");
	 break;
  case DT_RASCAMERA:
	 strcat(buf, "DT_RASCAMERA");
	 break;
  default:
	 strcat(buf, "Неизвестная технология");
    break;
  }
  strcat(buf, "\n");
  fputs(buf, out);

  fputs("-------------------------------\n", out);
  PrintH(TEXTCAPS,"TEXTCAPS   ");
  fputs("-------------------------------\n", out);
  PrintFlag(TEXTCAPS, TC_OP_CHARACTER,  "TC_OP_CHARACTER  ");
  PrintFlag(TEXTCAPS, TC_OP_STROKE,     "TC_OP_STROKE     ");
  PrintFlag(TEXTCAPS, TC_CP_STROKE,     "TC_CP_STROKE     ");
  PrintFlag(TEXTCAPS, TC_CR_90,         "TC_CR_90         ");
  PrintFlag(TEXTCAPS, TC_CR_ANY,        "TC_CR_ANY        ");
  PrintFlag(TEXTCAPS, TC_SF_X_YINDEP,   "TC_SF_X_YINDEP   ");
  PrintFlag(TEXTCAPS, TC_SA_DOUBLE,     "TC_SA_DOUBLE     ");
  PrintFlag(TEXTCAPS, TC_SA_INTEGER,    "TC_SA_INTEGER    ");
  PrintFlag(TEXTCAPS, TC_SA_CONTIN,     "TC_SA_CONTIN     ");
  PrintFlag(TEXTCAPS, TC_EA_DOUBLE,     "TC_EA_DOUBLE     ");
  PrintFlag(TEXTCAPS, TC_IA_ABLE,       "TC_IA_ABLE       ");
  PrintFlag(TEXTCAPS, TC_UA_ABLE,       "TC_UA_ABLE       ");
  PrintFlag(TEXTCAPS, TC_SO_ABLE,       "TC_SO_ABLE       ");
  PrintFlag(TEXTCAPS, TC_RA_ABLE,       "TC_RA_ABLE       ");
  PrintFlag(TEXTCAPS, TC_VA_ABLE,       "TC_VA_ABLE       ");
  PrintFlag(TEXTCAPS, TC_RESERVED,      "TC_RESREVED      ");

  // Стираем созданный контекст устройства
  DeleteDC(hdc);

  // Закрываем файл
  fclose(out);

  MessageBox(NULL,
    "Сведения о возможностях устройства записаны "
	 "в файл devcap.txt", "DCAPS",
	 MB_OK | MB_ICONINFORMATION);

  return 0;
}

// ------------------------------------------
// Функция для вывода параметра с использованием
// десятичной системы счисления
// ------------------------------------------
void PrintD(int nIndex, char *str)
{
  sprintf(buf, "%s\t%d\n", str, GetDeviceCaps(hdc, nIndex));
  fputs(buf, out);
  return;
}

// ------------------------------------------
// Функция для вывода параметра с использованием
// шестнадцатеричной системы счисления
// ------------------------------------------
void PrintH(int nIndex, char *str)
{
  sprintf(buf, "%s\t0x%x\n", str, GetDeviceCaps(hdc, nIndex));
  fputs(buf, out);
  return;
}

// ------------------------------------------
// Функция для вывода значения отдельных
// битов параметра
// ------------------------------------------
void PrintFlag(int nIndex, int nFlag, char *str)
{
  if((GetDeviceCaps(hdc, nIndex) & nFlag) == 0)
	  sprintf(buf, "\t%s\t-\n", str);
  else
	  sprintf(buf, "\t%s\t+\n", str);

  fputs(buf, out);
  return;
}

