На этом шаге мы рассмотрим способ отображения текста в окне.
Под областью пользователя окна понимается изменяемая область, в которую 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.
На следующем шаге мы рассмотрим Windows-функцию Paint().