Главная » C++, C++ Builder » Scribble: разработка C++ Builder

0

Назначение Scribble крайне просто. Когда пользователь нажимает кнопку мыши, программа начинает рисование. По мере того как мышь передвигается по экрану, программа соединяет точки, через которые прошла мышь, образуя линии. Этот процесс позволяет пользователю «рисовать» простые (а может, и не простые) фигуры на экране. На рис. 2.4 показан результат работы программы Scribble — улыбающаяся рожица.

Рис. 2.4. Окно программы Scribble с улыбающейся рожицей

Замечание

Вы найдете исходный текст программы Scribble в каталоге Chapter1\Scribble1 прилагаемого к книге компакт-диска.

В предисловии к книге я говорил, что было  бы  весьма  полезным  наличие  опыта программирования под Windows для работы с приведенными в книге примерами, и сейчас как раз тот самый случай, когда такой опыт мог бы помочь лучше разобраться в системе сообщений (messages) Windows. Процессы, происходящие в данном случае, достаточно просты. Когда пользователь нажимает на кнопку мыши и начинает двигать мышь, мы рисуем  линии, соединяющие точки. Что куда меньше понятно новичкам, так это то, как мы это делаем. Если вы опытный программист под Windows, то вы наверняка определите, что при  нажатии  на  левую кнопку мыши пользователем Windows сгенерирует сообщение WM_LBUTTONDOWN, адресованное нашему окну. Когда пользователь перемещает мышь, Windows генерирует сообщение WM_MOUSEMOVE. Наконец, когда пользователь отпускает левую кнопку мыши, Windows генерирует сообщение WM_LBUTTONUP. Вопрос в следующем: как теперь эта информация обрабатывается средой CBuilder?

CBuilder работает по системе, которая называется системой обработки  событий.  Каждое сообщение Windows, поступающее объекту из среды CBuilder, преобразуется в событие, которое может быть обработано этим объектом. В случае приведенных выше сообщений, объекты формы CBuilder вызывают три обработчика событий — OnMouseDown, OnMouseMove и OnMouseUp.

Замечание

Если вы программист, работавший на Visual C++ или Borland C++, то понятие обработчика событий может показаться вам немного странным. Обе эти среды используют одну и ту же концепцию, но подходят к ее осуществлению с разных сторон. И в Visual C++, и в Borland С++ карта сообщений определяет сообщение и метод класса, используемый для обработки этого сообщения. В CBuilder (и, конечно же, в Delphi) содержимое объектов само определяет, какие сообщения обрабатываются, и вызывает обработчики событий, определенные программистом. Различие состоит в том, что обработчики событий CBuilder, как мы увидим чуть позже, динамические, в то время как обработчики сообщений Visual C++ и Borland C++ определяются во время компиляции. В обоих случаях для исполнения используются методы объектов, но CBuilder применяет метод чуть более простой и гораздо более мощный.

Теперь давайте слегка напряжемся и добавим к нашей форме несколько обработчиков, чтобы приложение Scribble наконец заработало  как должно. Сначала добавим обработчик для события OnMouseDown. Поскольку это наш первый пример, я проведу вас через весь процесс его создания на случай, если вы не помните, как это делается. В дальнейшем я буду рассчитывать на то, что вы знаете что и как делать, и буду просто сообщать, какой обработчик добавить.

Если окно инспектора объектов закрыто, откройте его, нажав кнопку F11 или выбрав пункт меню View → Object Inspector. Выберите форму, щелкнув на ней мышью или выбрав ее из выпадающего комбинированного списка в верхней части инспектора объектов. Перейдите на страницу events (события) и в левой части инспектора объектов найдите событие OnMouseDown. Все события перечислены в алфавитном порядке, поэтому у вас не должно возникнуть проблем с поиском нужного. Щелкните в правую часть сетки инспектора объектов напротив события

OnMouseDown и наберите там OnMouseDown — это будет названием нового обработчика событий. Если вас смущает, что мы теперь имеем обработчик события с тем же именем, что и обрабатываемое им событие, то несколько позже в этой главе мы увидим, как изменить эту ситуацию. Нажмите клавишу Enter, чтобы подтвердить сделанные изменения.

После того как вы ввели имя метода и подтвердили свой выбор, CBuilder создаст новый обработчик в окне редактора. Введите следующие строки кода в метод OnMouseDown, отображенный в окне редактора:

void __fastcall TForm1::OnMouseDown(TObject *Sender, TMouseButton Button,

TShiftState Shift, int X, int Y)

{

FbMouseDown = TRUE; Canvas->MoveTo(X,Y);

}

Флаг FbMouseDown, показанный в предыдущем коде, должен  быть  добавлен  в  заголовочный файл (Unit1.h) и инициализирован в конструкторе. Этот флаг сигнализирует, нажата (TRUE) или нет (FALSE) кнопка мыши в окне. Ниже приведены изменения, которые надлежит произвести в заголовочном файле (показаны подсветкой):

//———————————————-

#ifndef Unit1.h

#define Unit1.h

//———————————————-

#include <vcl\Classes.hpp>

#include <vcl\Controls.hpp>

#include <vcl\StdCtrl.hpp>

#include <vcl\Forms.hpp>

//———————————————-

class TForm1 : public TForm

{

__published: // IDE-managed Components

void __fastcall OnMouseDown(TObject *Sender, TMouseButton Button,

TShiftState Shift, int X, intY); private: // User declarations BOOL FbMouseDown; public: // User declarations

__fastcall TForm1(TComponent* Owner);

};

//———————————————–

extern TForm1 *Form1;

//———————————————–

#endif

И вот, наконец, изменения, которые надо произвести в конструкторе класса

(в исходном файле Unit1.cpp):

__fastcall TForm1::TForm1(TComponent* Owner)

:TForm(Owner)

{

FbMouseDown = FALSE; // Установка флага нажатия

// кнопки мыши в "Ложь"

}

Давайте, перед там как двигаться дальше, взглянем на то, что у нас получилось. У класса TForm1

теперь   есть   private   (частная)   переменная,   определенная   программистом   —   FbMouseDown,

значение которой показывает, нажата ли в данный момент кнопка мыши. Если пользователь нажимает левую кнопку мыши внутри клиентской области окна, система обработки событий вызовет метод OnMouseDown. Этот метод просто-напросто устанавливает значение флага в TRUE (истина) и передвигает текущую позицию рисования в поле формы (то есть в Canvas) в позицию мыши. В обработчике для события CBuilder очень доступно передает нам информацию о позиции мыши в тот момент, когда на ней была нажата кнопка.

Вас может заинтересовать вопрос — а как CBuilder ассоциирует событие OnMouseDown с написанным нами методом OnMouseDown? Явно не по имени, поскольку обработчик может быть вызван по нашему желанию откуда угодно. Ни в приведенном выше коде, ни в коде заголовка вы не найдете ничего, что осуществляло бы ассоциирова ние. Это что —  магия  Borland?  Ответ кроется в файле Unit1.dfm, который содержит информацию о размещении и обработке формы для модуля Unit1. Если вы попробуете прочитать файл DFM (form definition file, файл  описания формы), используя стандартный текстовый редактор или набрав его имя в командной строке, то увидите, что он состоит из странных управляющих символов, в которых нет (или очень мало) смысла. Как же посмотреть на то, что происходит там, внутри?

Источник: Теллес М. – Borland C++ Builder. Библиотека программиста – 1998

По теме:

  • Комментарии