yandex rtb 1
ГоловнаЗворотній зв'язок
yande share

Объектно-ориентированное программирование

Лекция 11.

Простейшая программа для Windows с использованием MFC

 

Операционная система Windows обладает следующими особенностями, представляющими интерес для разработчиков приложений:

-          графический интерфейс, обеспечивающий пользователю удобство в работе и привлекательное графическое изображение;

-          приложение выполняется в собственных окнах. Каждое приложение располагает, по крайней мере, одним собственным окном. Через окна приложения выполняется ввод-вывод информации пользователя. С точки зрения пользователя приложение отождествляется с главным окном. Для программиста окно – визуальный интерфейс;

-          Работа в Windows ориентирована на события. Приложение в большинстве случаев выполняется отдельными фрагментами. После того как будет решена отдельная подзадача, управление передается Windows, которая может вызывать по мере надобности другие приложения. Какой-либо ввод  со стороны пользователя (активация окна, вызов команды меню и т.д.) инициирует событие Windows. Событие обрабатывается и программное управление передается в соответствующее приложение. Происходит это при помощи сообщений, описывающих изменения в окружающей приложение среде. Каждое сообщение связано с конкретным окном, с каждым из которых связана конкретная оконная процедура – специальная функция, отвечающая за обработку поступающих сообщений. Для приложения это означает, что оно вызывается для обработки события, соответственно на него реагирует и затем возвращается в неактивное состояние. Для сравнения: DOS-программа, будучи однажды вызвана, выполняется до тех пор, пока не закончится или не будет прервана.

Для программирования в среде Windows разработан API (Application Programming Interface – интерфейс прикладного программирования). Он представляет набор функций, при помощи которых любое приложение может взаимодействовать с Windows. API содержит примерно 2000 функций, несколько сот сообщений, предопределенных констант, макросов. Для облегчения программирования разработана библиотека классов MFC (Microsoft Foundation Classes). Она представляет иерархически упорядоченное множество классов, охватывающее большую часть функциональных возможностей Windows.  MFC предоставляет разработчику механизмы, которые, не нарушая идеологию операционной системы, существенно ее расширяют и упрощают. Конструкторы классов, их методы берут на себя большую часть рутинной работы.

Любая программа, использующая MFC для работы под Windows, должна определить два класса. Первый – производный класс от класса CWinApp, позволяющий создать приложение. Второй – производный класс от класса, определяющего окно. В большинстве случаев это класс CFrameWnd.

Класс CWinApp является базовым классом, из которого формируется обязательный объект - приложение. Основными задачами этого объекта являются инициализация и создание главного окна, а затем опрос системных сообщений. Инициализация окна производится путем переопределения виртуальной функции InitInstance. В этой функции создается объект класса, производного от одного из оконных классов Windows. В ней же вызываются функции, показывающие окно (ShowWindow) и прорисовывающую окно (UpdateWindow).

Само окно создается в конструкторе класса, производного от оконного класса. Это делается, например, с помощью функции Create. В этой функции определяется заголовок окна, его стиль, координаты, и некоторые другие параметры.

Этого достаточно, чтобы на экран выводилось окно определенного нами стиля. Однако это окно не будет обрабатывать никаких сообщений и не будет ничего выводить на экран. Для этого необходимо сделать следующее:

-                      определить карту сообщений для нашего окна (MESSAGE MAP)

-                      написать обработчики сообщений.

В нашей программе мы обрабатываем два сообщения – сообщение о щелчке левой кнопкой мыши (ON_WM_LBUTTONDOWN) и сообщение о необходимости перерисовки окна(ON_WM_PAINT). Для них предусмотрены обработчики с соответствующими именами – OnLButtonDown и OnPaint.

Поясним, для чего необходим обработчик OnPaint. Забота о сохранении содержимого окна ложится на программиста. Если окно оказалось частично или полностью перекрыто другим окном, содержимое окна теряется. Когда закрытая часть окна снова становится видимой, Windows посылает сообщение WM_PAINT о необходимости прорисовки окна заново, что и должен сделать соответствующий обработчик.

Коротко рассмотрим, как устроен графический вывод в системе Windows. Весь вывод реализован на принципе унификации работы с физически различными устройствами (экран, принтер и т.п.). Для всех устройств приложение использует одни и те же функции. Система сама распознает устройство вывода и активизирует соответствующий драйвер. Для реализации такого подхода в Windows предусмотрен специальный объект, называемый контекстом устройства. Именно он хранит информацию как об устройстве вывода, так и о параметрах рисования. В представленной ниже программе используются два контекста:

-                      CPaintDC используется для вывода в окно в обработчике сообщения о необходимости перерисовки окна

-                      lientDC используется для вывода в клиентскую (рабочую) область окна. Может использоваться для графического вывода в любой функции.

В программе также используется собственный класс, производный от класса CPoint (хранит информацию о точке). Мы дополнили его строкой, хранящей некоторое сообщение и методами, позволяющими менять параметры. Заметим, что объекты нашего класса мы описали как глобальные, видимые всем функциям нашей программы. Альтернативный вариант – описать их как часть класса, производного от класса окна.

Файл simple.h

#include <afxwin.h>

class simpleApp: public CWinApp {

public:

  virtual BOOL InitInstance();

};

class simpleWin: public CFrameWnd {

public:

  simpleWin();

  DECLARE_MESSAGE_MAP();

protected:

  void OnLButtonDown(UINT,CPoint);

  void OnPaint();

};

Файл simple.cpp

#include "simple.h"

#include "myclass.h"

myPoint *p,pm;

bool click=false;

simpleApp App;

simpleWin::simpleWin() {

  LPCTSTR classname=NULL;

  Create(classname,"Простая программа",WS_OVERLAPPEDWINDOW | WS_VSCROLL, CRect(200,200,600,400),0,0,0,0);

  p=new myPoint;

  p->setXY(100,100);

  p->setMessage(".Эта точка(100,100) определена нами");

  pm.setMessage("Здесь щелкнули мышкой");

}

BOOL simpleApp::InitInstance() {

  simpleWin *pMainWnd = new simpleWin;

  m_pMainWnd=pMainWnd;

  m_pMainWnd->ShowWindow(m_nCmdShow);

  m_pMainWnd->UpdateWindow();

  return TRUE;

}

BEGIN_MESSAGE_MAP(simpleWin,CFrameWnd)

  ON_WM_LBUTTONDOWN()

  ON_WM_PAINT()

END_MESSAGE_MAP()

void simpleWin::OnLButtonDown(UINT nFlags,CPoint point) {

  click=true;

  CClientDC dc(this);

  CRect rect;

  GetClientRect(&rect);

  dc.FillRect(rect,WHITE_BRUSH);

  dc.TextOut(p->getX(),p->getY(),p->getMessage());

  pm.setXY(point.x,point.y);

  dc.TextOut(pm.getX(),pm.getY(),pm.getMessage());

}

void simpleWin::OnPaint() {

  CPaintDC dc(this);

  dc.TextOut(p->getX(),p->getY(),p->getMessage());

  if (click) {

              dc.TextOut(pm.getX(),pm.getY(),pm.getMessage(););

  }

}

 

Файл myclass.h

#include <afxwin.h>

class myPoint: public CPoint{

private:

  char message[100];

public:

  myPoint(int x=0, int y=0,char* mes="") :CPoint(x,y) {

              strcpy(message,mes);

  }

  void setXY(int x, int y) {

              CPoint::x=x; CPoint::y=y;

  }

  void setMessage(char *mes) {

              strcpy(message,mes);

  }

  char* getMessage() {

              char *mes=new char[100];

              strcpy(mes,message);

              return mes;

  }

  int getX() {return CPoint::x;}

  int getY() {return CPoint::y;}

};

 

13