Шаг 9.
Библиотека OWL.
Оконная графика. Отображние текста в окне

    На этом шаге мы рассмотрим способ отображения текста в окне.

    Под областью пользователя окна понимается изменяемая область, в которую Windows-программа выводит данные. Любой тип данных (текст, растровое изображение и т.д.) выводится в графическом режиме. OWL осуществляет этот вывод с помощью реализации Windows-функций GDI и функции Paint(), вызываемой при необходимости перерисовки окна.

    Ниже приведем текст программы, отображающей текст в окне.

#include <owl\applicat.h>
#include <owl\framewin.h>
#include <owl\dc.h>

//Класс приложения
class TApp: public TApplication
{
  public:
	 TApp():TApplication(){}
	 void InitMainWindow();
};

//Класс основного окна
class TWndw:public TFrameWindow
{
  public:
	 TWndw(TWindow *parent,const char far *title);
  protected:
	 void EvLButtonDown(UINT,TPoint &point);
	 BOOL CanClose();
	 DECLARE_RESPONSE_TABLE (TWndw);
};

DEFINE_RESPONSE_TABLE1 (TWndw, TFrameWindow)
	EV_WM_LBUTTONDOWN,
END_RESPONSE_TABLE;

TWndw::TWndw(TWindow *parent, const char far *title):
		  TFrameWindow(parent,title)
{
	// Определить расположение и размеры окна.
	Attr.X=100;
	Attr.Y=100;
	Attr.W=400;
	Attr.H=300;
}
void TWndw::EvLButtonDown(UINT,TPoint &point)
{
	// Получить контекст устройства для области
	// пользовательского окна.
	TDC *DC= new TClientDC(HWindow);
	// Вывести текст в месте, указанном пользователем.
	DC->TextOut(point,"Щелчок!");
	// Удалить контекст устройства.
	delete DC;
}
BOOL TWndw::CanClose()
{
  int result=MessageBox("Вы действительно хотите закрыть окно?","Закрытие",
					 MB_YESNO | MB_ICONQUESTION);
  if (result==IDYES) return TRUE;
  else return FALSE;
}

void TApp::InitMainWindow()
{
  TFrameWindow *wndw=new TWndw(0,"Пример GDI-окна");
  SetMainWindow(wndw);
}

int OwlMain(int,char *[])
{
  return TApp().Run();
}
Текст этой программы можно взять здесь.

    Результат работы приложения изображен на рисунке 1:


Рис.1. Результат работы приложения

    Когда вы запускаете программу, представленную в этом примере, на экране появится окно. Нажмите кнопку мыши, и в том месте, куда указывает курсор мыши, появится слово "Щелчок!". Очевидно, программа перехватывает сообщение WM_LBUTTONDOWN; но вместо того, чтобы по нажатию левой кнопки мыши вывести окно сообщений, она выводит текст. Эта операция реализована в функции отклика на сообщение EvLButtonDown():

void TWndw::EvLButtonDown(UINT,TPoint &point)
{
	// Получить контекст устройства для области
	// пользовательского окна.
	TDC *DC= new TClientDC(HWindow);
	// Вывести текст в месте, указанном пользователем.
	DC->TextOut(point,"Щелчок!");
	// Удалить контекст устройства.
	delete DC;
}

    Эта функция не использует в качестве параметра виртуальный ключ-флаг, а использует координаты мыши, передаваемые в виде ссылки на объект класса TPoint, point. Функция использует координаты, переданные в point, чтобы определить место для вывода текста.

    Но первым делом EvLButtonDown() получает контекст устройства (Device Context, или DC) для области пользователя окна. Это делается динамически с помощью оператора new, который в данном случае возвращает указатель на класс TDC. Мы уже отмечали, что OWL поддерживает несколько классов DC, каждый для своего устройства. В данном случае функция использует TClientDC, который обеспечивает доступ к внутренней оконной области пользователя. Прототип конструктора объекта DC выглядит следующим образом:

    TClientDC(HWND wnd);

    Как видите, чтобы получить DC для оконной области пользователя, необходимо передать дескриптор окна. К счастью, любое окно, производное от класса TWindow, включает поле HWindow, содержащее этот дескриптор.

    Получив DC, функция отображает на экране слово "Щелчок!" в точке, координаты которой переданы функции через point. Она выполняет это, вызывая функцию-член TextOut() класса DC, являющуюся OWL-версией Windows-функции TextOut(). Ниже представлен прототип Windows API-версии функции TextOut() :

  BOOL  TextOut(HDC hDC, int  X, int  Y, LPSTR  lpString,   int  nCount);

    Здесь hDC - ссылка на контекст устройства, х и у - координаты точки, в которой вводится текст, lpString - указатель на строку, оканчивающуюся нулем "\0", nCount - число символов в строке. OWL-версия функции TextOut() переопределяется двумя следующими прототипами:

  BOOL  TextOut(const TPoint &p, const char far *string, int count = -1);
  BOOL  TextOut(int X, int Y, const char far *string, int count = -1);

    В обоих случаях OWL-версия не требует дескриптора контекста устройства. TextOut() уже является частью объекта DC. Объект знает свой собственный дескриптор, который хранится в защищенном поле Handle. Обе версии включают также количество вводимых символов, по умолчанию равное -1, что предписывает функции вводить строку целиком. Благодаря этому стандартному значению, не требуется указывать количество символов в строке, если нужно вывести полную строку. Наконец, OWL-версия TextOut() принимает координаты как в виде целых х и у, так и в виде объекта TPoint.

    Возвращаясь к программе, отметим, что последняя строка использует оператор delete для удаления объекта TClientDC.


    Замечания.
  1. Когда в приложении необходимо использовать OWL-объект, мы должны включить в исходный текст заголовочный файл объекта. Поскольку объект TClientDC является производным от OWL-класса TDC, чтобы сделать его доступным, необходимо включить заголовочный файл DC.H. Однако имейте в виду, что некоторые "малые" OWL-объекты используются в более значительных классах. Эти классы уже содержат объявления таких базовых объектов. Например, класс TDC объявляет такие графические объекты, как точки, перья, кисти, шрифты, растровые изображения, палитры и пиктограммы (иконки). Поэтому вы можете использовать соответствующие OWL-классы, не включая их заголовочные файлы в вашу программу, как и было сделано в случае с TPoint в приведенном примере.

  2. Поскольку Windows ограничивает число одновременно активных контекстов устройств, необходимо немедленно освободить DC, когда работа с ним закончена. Несоблюдение этого правила может повлечь неверную работу других приложений. Однако, в большинстве случаев классы, производные от OWL-класса ТDС, освобождают соответствующий контекст устройства Windows когда объект TDC удаляется, поэтому вам вряд ли придется освобождать контекст устройства Windows непосредственно в своей программе.

    На следующем шаге мы рассмотрим Windows-функцию Paint().




Предыдущий шаг Содержание Следующий шаг