#ifndef                 WINPLUS_H_INCLUDED
#define                 WINPLUS_H_INCLUDED

#include                <windows.h>
// #include                <winuser.h>
#include                <stdlib.h>
#include                <string.h>

#ifdef                  BUILD_SHARED_DLL
#define                 WARPAPI __declspec(dllexport)
#else
#define                 WARPAPI
#endif

// =======================================================================
// Для работы с памятью используются функции класса 'MemOverride'
#define                 MEM_OVERRIDE
// =======================================================================
// Типы значений для DWORD CWindowBase::OverrideDefaults(int Default);
#define OD_TITLE        0       //  Заголовок окна
#define OD_STYLE        1       //  Стиль окна
#define OD_X            2       //  Кооpдинаты левого веpхнего угла
#define OD_Y            3
#define OD_WIDTH        4       //  Шиpина и высота
#define OD_HEIGHT       5
#define OD_HICON        6       //  Значок
#define OD_HACCEL       7       //  Таблица акселеpатоpов
#define OD_HBRUSH       8       //  Фоновая кисть
#define OD_HMENU        9       //  Меню
#define OD_HCURSOR      10      //  Куpсоp
#define OD_HPARENTWND   11      //  Родительское окно
#define OD_CLASSNAME    12      //  Имя базового класса
#define OD_LASTCWB      20
#define OD_DEFAULT      ((DWORD)0xFFFFFFFF)
// =======================================================================
//  Максимальное количество вpеменных меню в меню пеpвого уpовня
#define MAX_POPUP_ITEM  32
// =======================================================================
//  Атpибуты файловых классов
#define   FA_PREREAD    1
#define   FA_WRAP       2
//  Минимальный размер кэша - 4 Кб
#define         OBF_CASHESIZE           4096
//  Максимальный разумный размер кэша - 32 Мб
#define         OBF_MAXCASHESIZE        16*1024*1024
// =======================================================================
// Константы для функций преобразования графиков
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif
#ifndef RADinDEG
#define RADinDEG (2*M_PI/180)
#endif
#ifndef MAXDOUBLE
#define MAXDOUBLE       1.797693E+308
#endif
#ifndef MINDOUBLE
#define MINDOUBLE       2.225074E-308
#endif
// Битовые поля для CGraphicalSamples::BeginPath / DrawArrays
// Точки
#define GS_POINTS           1
// Несвязанные между собой линии
#define GS_LINES            2
// Серия линий
#define GS_LINESTRIP        3
// Отдельные столбики
#define GS_BARS             5
// Столбики с общими сторонами
#define GS_BARSTRIP         6
// Вертикальные линии
#define GS_VLINES           7
// Флаги для CGraphicalSamples::fuDefinedArrays
#define GS_NONE             0
#define GS_COORD_ARRAY      (1<<0)
#define GS_COLOR_ARRAY      (1<<1)
#define GS_BOTH             (GS_COLOR_ARRAY|GS_COORD_ARRAY)
// Флаги для CGraphicalSamples::ScaleFromArrays и для
// CGraphicalSamples::TranstaleFromArrays
  // Коэффициенты масштабирования выбираются так, чтобы график целиком
  // лежал внутри ограничивающего прямоугольника
#define GS_AUTOSCALE        0
#define GS_AUTOTRANSLATE    0
  // Коэффициенты масштабирования должны быть одинаковы
#define GS_PROPORTIONAL     1
  // Не учитывать положение нулевой точки
#define GS_IGNOREZERO       2
// =======================================================================
#define MAX_LABEL_LENGTH      256
#define MAX_MARK_LENGTH       256
// =======================================================================
// ВНИМАНИЕ !
// Все влаги с '...COMMON...' не  управляют  отображением  соответствующих
// параметров, а лишь указывают на необходимость привязки этого  параметра
// к аналогичному параметру других  рядов.  Например,  установленный  флаг
// 'SF_COMMONGRIDX' не приводит к тому, что для данного ряда рисуется сет-
// ка, для этого необходимо установить флаг SF_GRIDX.
// Если сетка по указанной оси не рисуется, будет нарисована шкала.
// =======================================================================
// Рисуется сетка по оси абсцисс
#define SF_GRIDX              (1<<0)
// Рисуется сетка по оси ординат
#define SF_GRIDY              (1<<1)
// Все ряды с таким флагом имеют общую сетку по оси абсцисс
#define SF_COMMONGRIDX        (1<<2)
// Все ряды с таким флагом имеют общую сетку по оси ординат
#define SF_COMMONGRIDY        (1<<3)
// Шаг сетки по оси абсцисс выбирается автоматически
#define SF_AUTOGRIDX          (1<<4)
// Шаг сетки по оси ординат выбирается автоматически
#define SF_AUTOGRIDY          (1<<5)
// Ставится текстовая метка у оси абсцисс
#define SF_LABELX             (1<<6)
// Ставится текстовая метка у оси ординат
#define SF_LABELY             (1<<7)
// Все ряды с таким флагом имеют общую метку на оси абсцисс
#define SF_COMMONLABELX       (1<<8)
// Все ряды с таким флагом имеют общую метку на оси ординат
#define SF_COMMONLABELY       (1<<9)
// Ставятся метки значений у оси абсцисс
#define SF_MARKX              (1<<10)
// Ставятся метки значений у оси ординат
#define SF_MARKY              (1<<11)
// Все ряды с таким флагом имеют общие метки значений на оси абсцисс
#define SF_COMMONMARKX        (1<<12)
// Все ряды с таким флагом имеют общие метки значений на оси ординат
#define SF_COMMONMARKY        (1<<13)
// Рисуется ос абсцисс
#define SF_AXISX              (1<<14)
// Рисуется ос ординат
#define SF_AXISY              (1<<15)
// Пропорциональный шрифт
#define SF_AUTOSCALEFONT      (1<<16)
// =======================================================================
//  Базовый класс для служебных сообщений
class WARPAPI           CFormattedMessage
{
private:
  char                  lpBuffer[512];
public:
  char                  szAppTitle[128];
  HWND                  hWnd;
  void                  Report(const char *fmt, ...);
  // Метод 'DisplayString' может быть переопределен в производном классе,
  // например так, чтобы сообжение выводилось на консоль
  virtual void          DisplayString(char *lpszString,DWORD dwButtons)
  {
    ::MessageBox(hWnd,lpszString,szAppTitle,dwButtons);
  }
};
// =======================================================================
//  Базовый класс для информационных сообщений
class WARPAPI           CInfoReport : public CFormattedMessage
{
  public:
  void DisplayString(char *lpszStr, DWORD dwButtons)
  {
    CFormattedMessage::DisplayString(lpszStr,MB_OK|MB_ICONINFORMATION);
  }
};
// =======================================================================
//  Базовый класс для предупреждающих сообщений
class WARPAPI           CWarnReport : public CFormattedMessage
{
  public:
  void DisplayString(char *lpszStr, DWORD dwButtons)
  {
    CFormattedMessage::DisplayString(lpszStr,MB_OK|MB_ICONEXCLAMATION);
  }
};
// =======================================================================
//  Базовый класс для сообщений об ошибках
class WARPAPI           CErrorReport : public CFormattedMessage
{
  public:
  void DisplayString(char *lpszStr, DWORD dwButtons)
  {
    CFormattedMessage::DisplayString(lpszStr,MB_OK|MB_ICONHAND);
  }
};
// =======================================================================
//  Базовый класс для сообщений о критических ошибках
class WARPAPI           CFatalErrorReport : public CFormattedMessage
{
  public:
  void DisplayString(char *lpszStr, DWORD dwButtons);
};
// =======================================================================
// Класс 'MemOverride' переопределяет стандартные функции распределения
// памяти; например, можно отслеживать успешное распределение, и т.п.
class WARPAPI           MemOverride
{
public:
  LPVOID malloc(DWORD dwSize); // {return ::malloc(dwSize);}
  void   free(void *lpBlock); // {::free(lpBlock);}
};
// =======================================================================
//              Пpедставление окна
class WARPAPI   CWindowBase
#ifdef          MEM_OVERRIDE
  : public CFormattedMessage, public MemOverride
#else
  : public CFormattedMessage
#endif
{
protected:
  ATOM          ClassId;
  WNDCLASS      wc;
  char          ClassName[128];
  BOOL          bSuperclassed;
  //            Дескpиптоp pодительского окна
  HWND          parent;
  //            Заголовок окна
  char          *title;
  //            Стиль окна
  DWORD         style;
  //            Размеpы и положение окна
  int           x, y;
  int           width, height;
  HACCEL        haccel;
  HWND          hwnd;
  HINSTANCE     hinstance;
  BOOL          bInOnClose;
  WNDPROC       DefaultWindowProc;
  friend long FAR PASCAL GlobalWindowProc(HWND hWnd, 
    UINT message, WPARAM wParam, LPARAM lParam);
public:
  virtual void  DisplayString(char *lpszString,DWORD dwButtons)
  {
    CFormattedMessage::DisplayString(lpszString,MB_OK);
  }
  BOOL          bCreated;               //  Окно создано
  BOOL          bSuspend;               //  Окно не обpабатывает сообщения
  BOOL          InOnClose() {return bInOnClose;}
                CWindowBase();
  virtual       ~CWindowBase();
  HWND          GetWnd()                { return hwnd;                  }
  HWND          GetParent()             { return parent;                }
  HINSTANCE     GetInstance()           { return hinstance;             }
  //            Системные методы
  virtual DWORD OverrideDefaults(int Default) { return OD_DEFAULT;      }
  BOOL          Create(HINSTANCE hInstance, int nCmdShow);
  BOOL          CreateAndShow(HINSTANCE hInstance, int nCmdShow);
  int           MessageLoop();
  //            Полезные методы
  void          SetTitle(LPSTR lpszTitle);
  void          SetPos(RECT &rc);
  //            Форсирует обновление всей клиентской области окна
  void          Invalidate();
  //            Функции отклика на спецфические события
  // ВНИМАНИЕ !!! - OnCreate вызывается не в ответ на WM_CREATE, а непос-
  // редственно после вызова CreateWindow.
  virtual long  OnCreate(HWND hWnd)     { return 0L;                    }
  //
  virtual void  OnInitialUpdate()       {                               }
  virtual BOOL  OnClose()               { return TRUE;                  }
  virtual void  OnPaint(HDC dc, RECT &rcUpdate, BOOL bErase)    {       }
  virtual LPARAM OnCommand(WORD wId,WORD wNotifyCode,HWND hCtrl) 
  {      
    return 1;
  }
  //            if(res!=0 && res!=-1) - сообщение обpаботано
  virtual LPARAM OnEvent(UINT message, WPARAM wParam,LPARAM lParam)
  {
    return 1;
  }
  //
  LRESULT       Perform(UINT Msg,WPARAM wParam,LPARAM lParam);
  virtual void  OnIdle();
};
// =======================================================================
//              Работа с меню
class WARPAPI   CMenu
#ifdef          MEM_OVERRIDE
  : public      MemOverride
#endif
{
private:
  CWindowBase   *win;
  BOOL          bLoadedFromResource;
  int           iNextPopupPtr;
protected:
  HMENU         hmenupopup[MAX_POPUP_ITEM];
  HMENU         hmenumain;
public:
                CMenu();
                ~CMenu();
  void          Load(LPSTR lpResource);
  void          Load(int iResource);
  void          Destroy();
  void          Set(CWindowBase &cWnd);
  void          Create(int iPopups);
  void          NextPopup(LPSTR lpItemName);
  void          AppendTo(int iPopup, UINT fuFlags, UINT idNewItem,
                  LPCSTR lpNewItem);
  void          EnableItem(UINT idEnableItem, UINT uEnable);
  void          CheckItem(UINT idCheckItem, UINT uCheck);
};
// =======================================================================
//              Работа с окнами диалога
class WARPAPI   CDialog
#ifdef          MEM_OVERRIDE
  : public      MemOverride
#endif
{
protected:
  HINSTANCE     ParentInstance;
  HWND          ParentWnd;
  LPSTR         lpTemplate;
  CDialog       *PrevModalDialog;
public:
                CDialog(LPSTR lpTemplate, HWND hWnd=NULL);
                CDialog(int iTemplate, HWND hWnd=NULL);
                CDialog(LPSTR lpTemplate, CWindowBase &Parent);
                CDialog(int iTemplate, CWindowBase &Parent);
                CDialog(int iTemplate, HWND hWnd, HINSTANCE hInst);
  virtual       ~CDialog() {}
  BOOL          DoModal();
  virtual LRESULT OnInitDialog(HWND hDlg, HWND hFocus);
  virtual LRESULT OnCommand(HWND hDlg, WPARAM idControl);
};
// =======================================================================

#ifdef MoveTo
#undef MoveTo
#endif

// =======================================================================
// Классы, инкапсулирующие параметры перьев, кистей и шрифтов
// =======================================================================
class WARPAPI   CPen
{
protected:
  LOGPEN        PenParams;
public:
                CPen()
  {
    // По умолчанию устанавливается сплошное перо
    PenParams.lopnStyle=PS_SOLID;
    PenParams.lopnWidth.x=1;
    PenParams.lopnWidth.y=0;
    PenParams.lopnColor=RGB(255,255,255);
  }
  virtual       ~CPen() {}
  void          SetStyle(UINT uiStyle) {PenParams.lopnStyle=uiStyle;}
  void          SetWidth(LONG lWidth) {PenParams.lopnWidth.x=lWidth;}
  void          SetColor(COLORREF crColor) {PenParams.lopnColor=crColor;}
  LOGPEN        *GetLogPen() {return &PenParams;}
};
// =======================================================================
class WARPAPI   CBrush
{
protected:
  LOGBRUSH      BrushParams;
public:
                CBrush()
  {
    // По умолчанию устанавливается сплошная кисть
    BrushParams.lbStyle=BS_SOLID;
    BrushParams.lbColor=RGB(255,255,255);
    BrushParams.lbHatch=0;
  }
  virtual       ~CBrush() {}
  void          SetColor(COLORREF crColor) {BrushParams.lbColor=crColor;}
  void          SetHatch(LONG lbHatch)
  {
    BrushParams.lbStyle=BS_HATCHED;
    BrushParams.lbHatch=lbHatch;
  }
  void          SetDibPattern(HBITMAP hDib)
  {
    BrushParams.lbStyle=BS_DIBPATTERN;
    BrushParams.lbHatch=(LONG)hDib;
  }
  void          SetStyle(LONG lbStyle) {BrushParams.lbStyle=lbStyle;}
  LOGBRUSH      *GetLogBrush() {return &BrushParams;}
};
// =======================================================================
class WARPAPI   CFont
{
protected:
  LOGFONT       FontParams;
public:
                CFont()
  {
    FontParams.lfHeight=16;
    FontParams.lfWidth=0;
    FontParams.lfEscapement=0;
    FontParams.lfOrientation=0;
    FontParams.lfWeight=FW_DONTCARE;
    FontParams.lfItalic=FALSE;
    FontParams.lfUnderline=FALSE;
    FontParams.lfStrikeOut=FALSE;
    // В Windows NT 4.0 надо устанавливать lfCharSet в 'RUSSIAN_CHARSET'
    FontParams.lfCharSet=DEFAULT_CHARSET;
    FontParams.lfOutPrecision=OUT_DEFAULT_PRECIS;
    FontParams.lfClipPrecision=CLIP_DEFAULT_PRECIS;
    FontParams.lfQuality=DEFAULT_QUALITY;
    FontParams.lfPitchAndFamily=DEFAULT_PITCH;
    strcpy(FontParams.lfFaceName,"Arial");
  }
  virtual       ~CFont() {}
  void          SetHeight(LONG lfHeight)
  {
    FontParams.lfHeight=lfHeight;
  }
  void          SetWidth(LONG lfWidth)
  {
    FontParams.lfWidth=lfWidth;
  }
  void          SetOrientation(LONG lfOrientation)
  {
    FontParams.lfOrientation=FontParams.lfEscapement=lfOrientation;
  }
  void          SetWeight(LONG lfWeight)
  {
    FontParams.lfWeight=lfWeight;
  }
  void          SetItalic(BYTE lfItalic)
  {
    FontParams.lfItalic=lfItalic;
  }
  void          SetUnderline(BYTE lfUnderline)
  {
    FontParams.lfUnderline=lfUnderline;
  }
  void          SetStrikeOut(BYTE lfStrikeOut)
  {
    FontParams.lfStrikeOut=lfStrikeOut;
  }
  void          SetCharSet(BYTE lfCharSet)
  {
    FontParams.lfCharSet=lfCharSet;
  }
  void          SetOutPrecision(BYTE lfOutPrecision)
  {
    FontParams.lfOutPrecision=lfOutPrecision;
  }
  void          SetClipPrecision(BYTE lfClipPrecision)
  {
    FontParams.lfClipPrecision=lfClipPrecision;
  }
  void          SetQuality(BYTE lfQuality)
  {
    FontParams.lfQuality=lfQuality;
  }
  void          SetPitchAndFamily(BYTE lfPitchAndFamily)
  {
    FontParams.lfPitchAndFamily=lfPitchAndFamily;
  }
  void          SetFaceName(char *szFaceName)
  {
    strncpy(FontParams.lfFaceName,szFaceName,LF_FACESIZE);
  }
  LOGFONT       *GetLogFont()
  {
    return &FontParams;
  }
};
// =======================================================================
// Базовый класс для классов, оперирующих контекстами устройства.
// Методы, не являющиеся оболочками функций GDI, комментированы.
// =======================================================================
class WARPAPI   CDCObject : public CFormattedMessage
#ifdef          MEM_OVERRIDE
  , public MemOverride
#endif
{
protected:
  HWND                  HandleWND;
  HDC                   HandleDC;
  HGDIOBJ               hBrushOld,hBrush;
  HGDIOBJ               hFontOld,hFont;
  HGDIOBJ               hPenOld,hPen;
  RECT                  rcPaintArea;
  int                   nCurrentOrientation;
  void                  DeleteBrush();
  void                  DeleteFont();
  void                  DeletePen();
  void                  ResetAll();
  void                  ReleaseAll();
  BOOL                  bLastError;
public:
  BOOL                  LastError() {return bLastError;}
                        CDCObject(HDC hDC);
  virtual               ~CDCObject();
  HWND                  &GetWnd() {return HandleWND;}
  HDC                   &GetDC() {return HandleDC;}
  HGDIOBJ               &GetBrush() {return hBrush;}
  HGDIOBJ               &GetFont() {return hFont;}
  HGDIOBJ               &GetPen() {return hPen;}
// =======================================================================
// Создание объектов GDI
// =======================================================================
  void  CreatePen(int fnPenStyle,int nWidth,COLORREF crColor);
  void  CreatePenIndirect(CONST LOGPEN *lplgpn);
  void  CreateBrushIndirect(CONST LOGBRUSH *lplb);
  void  CreateDIBPatternBrush(HGLOBAL hglbDIBPacked,UINT fuColorSpec);
  void  CreateDIBPatternBrushPt(CONST VOID *lpPackedDIB,UINT iUsage);
  void  CreatePatternBrush(HBITMAP hbmp);
  void  CreateSolidBrush(COLORREF crColor);
  void  CreateFont(int nHeight,int nWidth,int nEscapement,
    int nOrientation,int fnWeight,DWORD fdwItalic,DWORD fdwUnderline,
    DWORD fdwStrikeOut,DWORD fdwCharSet,DWORD fdwOutputPrecision,
    DWORD fdwClipPrecision,DWORD fdwQuality,DWORD fdwPitchAndFamily,
    LPCTSTR lpszFace);
  void  CreateFontIndirect(CONST LOGFONT *lplf);
// Следующие три метода создают шрифт, устанавливая опущенные параметры:
//   nWidth - в ноль;
//   nEscapement и nOrientation - в ноль;
//   fnWeight - в FW_NORMAL;
//   fdwItalic и fdwUnderline - в FALSE;
//   fdwCharSet - в DEFAULT_CHARSET;
//   fdwStrikeOut - в FALSE;
//   fdwOutputPrecision - в OUT_DEFAULT_PRECIS;
//   fdwClipPrecision - в CLIP_DEFAULT_PRECIS;
//   fdwQuality - в NONANTIALIASED_QUALITY;
//   fdwPitchAndFamily - в DEFAULT_PITCH||FF_DONTCARE.
  void  CreateFont(int nSize,LPCTSTR lpszFace);
  void  CreateFont(int nHeight,int nWidth,int nOrientation,
    LPCTSTR lpszFace);
  void  CreateFont(int nHeight,int nWidth,int nOrientation,
    int fnWeight,DWORD fdwItalic,DWORD fdwUnderline,LPCTSTR lpszFace);
// Следующие три метода создают объекты GDI по параметрам классов
  void CreateFont(CFont *lpFont);
  void CreatePen(CPen *lpPen);
  void CreateBrush(CBrush *lpBrush);
// =======================================================================
// Рисование обьектами GDI
// =======================================================================
  void  SetPixel(int X, int Y, COLORREF Color)
  {
    ::SetPixel(HandleDC,X,Y,Color);
  }
  void  AngleArc(int X,int Y,DWORD dwRadius,FLOAT eStartAngle,
    FLOAT eSweepAngle);
  void  LineTo(int x,int y);
  void  Polyline(CONST POINT *lppt,int cPoints);
  void  Arc(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,
    int nXStartArc,int nYStartArc,int nXEndArc,int nYEndArc);
  void  MoveToEx(int X,int Y,LPPOINT lpPoint);
  void  PolylineTo(CONST POINT *lppt,DWORD cCount);
  void  ArcTo(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,
    int nXRadial1,int nYRadial1,int nXRadial2,int nYRadial2);
  void  Pie(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,
    int nXRadial1,int nYRadial1,int nXRadial2,int nYRadial2);
  void  PolyPolygon(CONST POINT *lpPoints,CONST INT *lpPolyCounts,
    int nCount);
  void  Chord(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,
    int nXRadial1,int nYRadial1,int nXRadial2,int nYRadial2);
  void  PolyBezier(CONST POINT *lppt,DWORD cPoints);
  void  PolyBezierTo(CONST POINT *lppt,DWORD cCount);
  void  Rectangle(int left,int top,int right,int bottom);
  void  Ellipse(int nLeftRect,int nTopRect,int nRightRect,
    int nBottomRect);
  void  PolyDraw(CONST POINT *lppt,CONST BYTE *lpbTypes,int cCount);
  void  RoundRect(int nLeftRect,int nTopRect,int nRightRect,
    int nBottomRect,int nWidth,int nHeight);
  void  ExtTextOut(int X,int Y,UINT fuOptions,CONST RECT *lprc,
    LPCTSTR lpString,UINT cbCount,CONST INT *lpDx);
  void  Polygon(CONST POINT *lpPoints,int nCount);
  void  TextOut(int x,int y,char *lpStr,int cbString);
  void  PolyPolyline(CONST POINT *lppt,CONST DWORD *lpdwPolyPoints,
    DWORD cCount);
  void  PatBlt(int nXLeft,int nYLeft,int nWidth,int nHeight,DWORD dwRop);
  void  Line(int x1,int y1,int x2,int y2);
// Рисует пустой прямоугольник (через 'Polyline')
  void  HollowRectangle(RECT *lpRc);
// Выводит всю строку (параметр cbString == strlen(lpStr))
  void  TextOut(int x,int y,char *lpStr);
// Для совместимости с Windows 3.X
  void  MoveTo(int X,int Y);
// Параметры от 'nXLeft' до 'nHeight' извлекаются из 'lprcArea'
  void  PatBlt(RECT *lprcArea,DWORD dwRop);
// =======================================================================
// Установка атрибутов контекста
// =======================================================================
  void  SetTextAlign(UINT fMode);
  void  SetTextCharacterExtra(int nCharExtra);
  void  SetTextColor(COLORREF crColor);
  void  SetBkColor(COLORREF crColor);
  void  SetMapMode(int fnMapMode);
  void  SetBkMode(int iBkMode);
  void  SetTextJustification(int nBreakExtra,int nBreakCount);
// =======================================================================
// Разное
// =======================================================================
  virtual void  GetTextExtentPoint(LPCTSTR lpString,int cbString,
    LPSIZE lpSize);
  void  GetTextExtentPoint(LPCTSTR lpString,LPSIZE lpSize);
// =======================================================================
// Метод записывает в массив точек координаты вершин прямоугольника,
// внутри которого содержится текстовая строка. Параметры:
// lpString - указатель на строку;
// lpOrigin - укзатель на точку, координаты которой будут передаваться
//   функции 'TextOut' при выводе текста;
// aVertices - массив, в который записываются координаты;
// bLooped - если этот флаг установлен, то пятая точка ломаной повторяет
//   первую. Полезно для 'Polyline'.
// =======================================================================
  void  GetTextRect(LPCTSTR lpString,POINT *lpOrigin,
    POINT *aVertices,
    BOOL bLooped=FALSE);
  // Метод в потомках возвращает размеры клиентской области
  virtual BOOL GetClientArea(RECT *lpRcClient) {return FALSE;}
};
// =======================================================================
// Потомок CDCObject, оперирующий с экранным контекстом
// =======================================================================
class WARPAPI   CClientDC : public CDCObject
{
public:
  CClientDC(HDC hDC) : CDCObject(hDC) {}
  CClientDC(CWindowBase *lpOutputFrame);
  BOOL GetClientArea(RECT *lpRcClient);
};
// =======================================================================
// 28.07.98
// Потомок CDCObject, оперирующий с контекстом размещаемого метафайла
// =======================================================================
class WARPAPI   CMetafileDC : public CDCObject
{
private:
  char              *szFileName;
  RECT              BoundsRect;
public:
  // Параметры конструктора:
  // szFileName - имя файла, в который будут записаны данные
  // lpRcInches1000 - размер области вывода (в тысячных долях дюйма)
  // если третий параметр равен NULL, то создается метафайл на лист A4
                    CMetafileDC(char *szFileName, RECT *lpRcInches1000);
  virtual           ~CMetafileDC();
  virtual void      GetTextExtentPoint(LPCTSTR lpString,int cbString,
    LPSIZE lpSize);
  BOOL              GetClientArea(RECT *lpRcClient);
};
// =======================================================================
//  Стандаpтные диалоги откpытия и закpытия файлов
// =======================================================================
class WARPAPI   COFNBase
#ifdef          MEM_OVERRIDE
  : public      MemOverride
#endif
{
protected:
  char          DirName[_MAX_DIR];
  char          File[3+_MAX_DIR+_MAX_FNAME+_MAX_EXT];
  char          FileTitle[_MAX_FNAME];
  OPENFILENAME  ofn;
  BOOL          bLastError;
public:
  void          SetTitle(char *title) {ofn.lpstrTitle = title;}
  BOOL          LastError() {return bLastError;}
};

class WARPAPI   CFileOpenDialog : public COFNBase
{
public:
                CFileOpenDialog(HWND hwnd, char *title = NULL,
    char *filter=NULL, char *dirname=NULL, char *filename=NULL);
  char          *GetName() { return File; }
  void          DoModal();
};

class WARPAPI   CFileSaveDialog : public COFNBase
{
public:
                CFileSaveDialog(HWND hwnd, char *title = NULL,
    char *filter=NULL, char *dirname=NULL, char *filename=NULL);
  char          *GetName() { return File; }
  void          DoModal();
};
// =======================================================================
//  Классы файлового ввода - вывода
// =======================================================================
class WARPAPI           CInputBinaryFile
#ifdef                  MEM_OVERRIDE
  : public MemOverride
#endif
{
protected:
  int                   iHandle;
  DWORD                 dwPos;
  DWORD                 dwSize;
  DWORD                 dwFlags;
  BOOL                  bLastError;
  void                  *lpFileBuffer;
public:
  BOOL                  LastError() {return bLastError;}
  char                  PathName[_MAX_PATH];
  char                  Drive[_MAX_DRIVE], Dir[_MAX_DIR],
                        Name[_MAX_FNAME],Ext[_MAX_EXT];
                        CInputBinaryFile(char *lpszPathName);
  virtual               ~CInputBinaryFile();
  void                  Preload(BOOL bUseSharedPool=FALSE);
  void                  *GetBuffer(void) {return lpFileBuffer;}
  void                  seek(long lOffeset, DWORD dwSeekType);
  DWORD                 tell(void);
  BOOL                  eof(void);
  DWORD                 filesize(void);
  DWORD                 read(void *lpBuffer, DWORD dwLength);
};
// =======================================================================
class                   CInputTextFile : public CInputBinaryFile
{
  public:
                        CInputTextFile(char *lpszPathName):
                        CInputBinaryFile(lpszPathName) {}
  void                  SetWrapMode(int iWMode);
  UCHAR                 getch();
  DWORD                 gets(char *lpszBuffer, DWORD dwLimit);
  DWORD                 scan(char *lpszBuffer, DWORD dwlimit);
};
// =======================================================================
//  Минимальный размер кэша - 4 Кб
#define         OBF_CASHESIZE           4096
//  Максимальный разумный размер кэша - 32 Мб
#define         OBF_MAXCASHESIZE        16*1024*1024
class WARPAPI   COutputBinaryFile : public CFormattedMessage
#ifdef                  MEM_OVERRIDE
  , public MemOverride
#endif
{
  BOOL          bLastError;
  BOOL          bAlreadyExists;
  BOOL          bOverWrite;
  char          *lpszFileName;      //  Имя выходного файла
  int           iHandle;            //  Дескриптор файла
  BYTE          *lpCache;           //  Указатель на кэш
  DWORD         dwCacheSize;        //  Размер кеша
  DWORD         dwCachePos;         //  Текущая позиция внутри кэша
  void          ResetAll();
  void          ReleaseAll();
public:
  BOOL          LastError() {return bLastError;}
  BOOL          IsExists() {return bAlreadyExists;}
  //  Аргументы конструктора - имя выходного файла и желаемый размер кэша
                COutputBinaryFile(char *lpszFileName,
    DWORD dwSizeCache=OBF_CASHESIZE);
  virtual       ~COutputBinaryFile();
  //  Метод выполняет сброс кэша на диск
  void          Commit();
  //  Метод выполняет запись в файл/кэш
  void          write(void *lpBuffer, DWORD dwBufferSize);
  //  Переопределенный метод выводит запрос на перезапись
  virtual void          DisplayString(char *lpszString,DWORD dwButtons);
};
// =======================================================================
class WARPAPI   COutputTextFile : public COutputBinaryFile
{
private:
  char          lpszBuffer[1024];
public:
  COutputTextFile(char *lpszFileName,DWORD dwSizeCache=OBF_CASHESIZE):
    COutputBinaryFile(lpszFileName,dwSizeCache) {}
  ~COutputTextFile() {}
  void          putch(char ch);
  void          puts(char *str);
  void          printf(const char *fmt, ...);
};
// =======================================================================
// Построение графиков. Код был создан в августе 1998 г., первое исполь-
// зование - в программе 'af15graph'. В сентябре 1998 г. перенесен в 
// библиотеку.
// =======================================================================
typedef struct tagTGraphVertex2d
{
  double x, y;
} TGraphVertex2d;
// Представление одного ряда данных
class WARPAPI   CGraphicsSamples : public MemOverride
{
private:
  // Количество вершин
  int           iVertexCount;
  // Предел и текущая вершина для функций в операторных скобках
  int           iMaxVertex;
  // Тип вершин для команд VertexXX
  int           iSamplesType;
  // Параметры рядов и флаг их допустимости
  double        MinX,MaxX,MinY,MaxY;
  double        CustomMinX,CustomMaxX,CustomMinY,CustomMaxY;
  BOOL          bMinMaxValid;
  BOOL          bUseCustomMinMaxX;
  BOOL          bUseCustomMinMaxY;
  // == TRUE если находимся в промежутке между операторными скобками
  BOOL          bInsidePath;
  // Флаги указывают, какие из двух массивов уже определены
  DWORD         fuDefinedArrays;
  // Массив координат вершин
  TGraphVertex2d *lpVertices;
  // Нулевая точка
  TGraphVertex2d vZeroPoint;
  // Масштабные множители
  TGraphVertex2d vZoom;
  // Угол поворота
  double        dAngle;
  // Массив цветов
  DWORD         *lpRGBTriples;
  // Признак ошибки
  BOOL          bLastError;
  // Объект, в который производится вывод
  CDCObject     *lpCDC;
  // Прямоугольник вывода
  RECT          rcOut;
  // Метод выделяет память под массивы
  void          AllocateArrays();
  // Метод освобождает память, занятую массивами координат и цветов
  void          ReleaseArrays();
  // Метод подсчитывает минимальное и максимальное значений координат ряда
  void          ResetMinMax();
public:
                CGraphicsSamples(CDCObject *lpCDC);
  virtual       ~CGraphicsSamples();
  // =====================================================================
  // Часть 1. Команды рисования.
  // Операторная скобка, устанавливающая режим рисования
  void          BeginPath(int iMaxVertex);
  // Команды отрисовки очередной вершины
  void          Vertex2d(double x, double y);
  void          Vertex2i(int x, int y);
  void          Color3d(double r, double g, double b);
  void          Color3i(int r, int g, int b);
  // Операторная скобка, заканчивающая процесс накопления информации
  void          EndPath();
  // Альтернативный способ задания информации:
  // Метод определяет массив данных о вершинах. Параметр 'iStride' задает
  // смещение в байтах между координатой 'y' предыдущей вершины и коор-
  // динатой 'x' последующей вершины. Если последовательность координат
  // непрерывна, то он должен быть установлен в 0.
  void          VertexPointer2d(int iStride,int iCount,void *aVertices);
  void          VertexPointer2i(int iStride,int iCount,void *aVertices);
  // Метод определяет массив данных о цветах вершин.
  void          ColorPointer1i(int iStride,int iCount,void *aRGBTriples);
  // Метод выполняет отрисовку массивов вершин
  void          DrawArrays(int iDrawMode);
  // =====================================================================
  // Часть 2. Определения применяемых к вершинам преобразований.
  void          GetMinMaxX(double *MinX, double *MaxX);
  void          GetMinMaxY(double *MinY, double *MaxY);
  void          UseCustomMinMaxX(double MinX, double MaxX, BOOL bUse);
  void          UseCustomMinMaxY(double MinY, double MaxY, BOOL bUse);
  void          Scale(double dFactorX, double dFactorY);
  void          Translate(double dTranslateX, double dTranslateY);
  void          Rotate(double Angle, double CX, double CY);
  // Установка параметров области вывода
  void          SetOutputRect(RECT *lprcOut);
  void          GetOutputRect(RECT *lprcOut);
  // Подгон под размер окна
  void          ScaleFromArrays(double dReqSizeX, double dReqSizeY,
    DWORD fuScaleFlags);
  void          TranslateFromArrays(double dReqStartX, double dReqStartY,
    DWORD fuFlags);
  // =====================================================================
  CPen          *GetPen() {return lpInitialPen;}
  CBrush        *GetBrush() {return lpInitialBrush;}
  TGraphVertex2d *GetZeroPoint() {return &vZeroPoint;}
  TGraphVertex2d *GetZoom() {return &vZoom;}
  double         *GetRotation() {return &dAngle;}
  // =====================================================================
  BOOL          LastError() {return bLastError;}
  // Перо по умолчанию
  CPen          *lpInitialPen;
  // Кисть по умолчанию
  CBrush        *lpInitialBrush;
};
// Представление области формата графика
class WARPAPI   CSamplesFormat
{
private:
  CDCObject     *lpDC;
  CGraphicsSamples *lpSamples;
  char          szBuffer[MAX_MARK_LENGTH];
  void          AutoLabelPlaces();
  void          DrawLabels();
  void          DrawGrid();
  DWORD         fuFlags;
  BOOL          bLastError;
  // Тексты меток
  char          szLabelX[MAX_LABEL_LENGTH];
  char          szLabelY[MAX_LABEL_LENGTH];
  // Шаг сетки в ЭКРАННЫХ координатах
  double        GridSizeX;
  double        GridSizeY;
  // Позиции меток в ЭКРАННЫХ координатах
  TGraphVertex2d LabelXPlace;
  TGraphVertex2d LabelYPlace;
  // Область вывода
  RECT          rcOut;
public:
  // Шрифты для меток - нормальный и повернутый на 90 градусов
  CFont         *fntLabelX;
  CFont         *fntLabelY;
  // Перо для сеток
  CPen          *pnGrid;
  // Перо для осей и засечек (рисуются, если не рисуются сетки)
  CPen          *pnAxis;
  // Перо для обрамляющего прямоугольника
  CPen          *pnFrame;
  // Число делений сетки по оси абсцисс
  int           iGridNumX;
  // Число делений сетки по оси ординат
  int           iGridNumY;
  // Число значащих цифр в тексте метки около оси абсцисс
  int           iDigitsX;
  // Число значащих цифр в тексте метки около оси ординат
  int           iDigitsY;
  // Параметры конструктора:
  //  - начальные значения флагов
  //  - объект, инкапсулирующий методы контекста устройства вывода
  //  - ряд данных
                CSamplesFormat(DWORD fuInitialFlags,CDCObject *lpDC,
    CGraphicsSamples *lpSamples);
                ~CSamplesFormat();
  // Метод устанавливает шаг сетки (в ИСХОДНЫХ единицах)
  void          SetGridSizes(double GridSizeX,double GridSizeY);
  // Метод устанавливает специальные пределы изменения
  void          UseCustomMinMaxX(double MinX, double MaxX, BOOL bUse);
  void          UseCustomMinMaxY(double MinY, double MaxY, BOOL bUse);
  // Метод устанавливает имена меток
  void          SetLabelNames(char *szLabelX, char *szLabelY);
  // Метод устанавливает область вывода
  void          SetOutputRect(RECT *rcOut);
  // Метод выполняет отрисовку меток и сетки
  void          Draw();
};
// =======================================================================
// 10.10.99
class WARPAPI   CWindowedControl
{
public:
  HWND          Handle;
  int           iControl;
                CWindowedControl() {}
                CWindowedControl(HWND Handle);
                CWindowedControl(HWND hDialog,int iControl);
  void          Init(HWND hDialog,int iControl);
  LRESULT       Perform(UINT Msg,WPARAM wParam,LPARAM lParam);
  int           From(int id) {return id==iControl;}
  char          *GetText();
  void          SetText(char *szStr);
  void          Move(int l,int t,int w,int h);
};

// Кнопки - обычные, триггерные и селективные
class WARPAPI   CButton : public CWindowedControl
{
public:
  CButton() : CWindowedControl() {}
  CButton(HWND hDialog,int iButton) : CWindowedControl(hDialog,iButton) {}
  int           IsChecked();
  void          Check(int Checked);
};

// Поля редактирования
class WARPAPI   CEdit : public CWindowedControl
{
public:
  CEdit() : CWindowedControl() {}
  CEdit(HWND hDialog,int iEdit) : CWindowedControl(hDialog,iEdit) {}
};

extern "C"
{
  void __declspec(dllexport) __stdcall utCenterWindow(HWND win);
}

#endif
