Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции.doc
Скачиваний:
17
Добавлен:
14.02.2015
Размер:
641.54 Кб
Скачать

Думайте о пользователе

Windows— это вытесняющая многозадачная среда. Это означает, что если программа работает слишком долго, то пользователь может переключиться на другую программу. Однако, поскольку Windows сконструирована определенным образом, эта вытесняющая многозадачность не всегда работает так, как бы вам хотелось. Например, предположим, что ваша программа тратит на обработку отдельного сообщения минуту или больше. Да, пользователь может переключиться на другую программу. Но пользователь ничего не в состоянии сделать с вашейпрограммой. Пользователь не может изменить размер окна вашей программы, закрыть его, т. е. вообще ничего. Так происходит потому, что, хотя ваша оконная процедура и должна выполнять все эти задачи, но она занята выполнением слишком долгой работы. Конечно, может показаться, что оконная процедура не выполняет операций по изменению размера и перемещению собственного окна, но, тем не менее, она это делает. Это часть работы функцииDefWindowProc, которую, в свою очередь, необходимо считать частью оконной процедуры.

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

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

Лекция 2. Первая программа наC++Builder

Первая наша программа будет рисовать на форме звездочку. Количество вершин у звездочки будет задаваться пользователем. Кроме того, пользователь будет задавать еще одно число, определяющее, через сколько вершин происходит соединение (если это число равно один, то получается не звездочка, а просто многоугольник, если два, то при соединении одну вершину пропускаем) и т. п.. Рисование будет присходить при нажатии на кнопку.

Итак, запустите C++Builder, и разместите на появившейся форме дваEdit'а и одну кнопку (компонентButton) и дваlabel'а:

Задайте свойства Captionдляlabel'ов как "n:" и "m:" соответственно. Для кнопки же свойствоCaptionустановите в "Нарисовать". После размещения элементов наша форма должна выглядеть приблизительно так:

Теперь займемся кодом. Все рисование на форме происходит, как правило, в обработчике OnPaint. Есть еще и много других обработчиков -OnCreate(его код выполняется при создании формы),OnClick(код выполняется, когда пользователь щелкает на форме). Для того, чтобы создать заготовку для соответствеющего обработчика, выбираем нужный пункт вcombobox'еObjectInspector'а, затем щелкаем на вкладочкеEventsчуть пониже и делаем двойной щелчок на строке с нужным именем обработчика:

В окно кода вносим следующие строки:

...

void __fastcall TForm1::FormPaint(TObject *Sender)

{

int r=30; //Радиус

int x=50, y=50; //Центр звезды

constfloatpi=3.1415926;

Canvas->MoveTo(x+r,y); //Переходим в начальную точку

for(int i=1; i<=n; i++){

//Рисуем в цикле

Canvas->LineTo(x + cos(i*m*pi*2/n) * r, y + sin(i*m*pi*2/n) * r);

}

}

...

Этот код и рисует звезду с центром в точке (50, 50) и радиуром 30. С алгоритмом рисования мы сейчас разбираться не будем. Отметим только, чт мы использем тут синусы и косинусы. А это значит, что файл с соответствующими функциями надо подключить (а то компилятор будет ругаться, что не знает он, что такое sinиcos). Для подключения добавьте с начале файла следующую строку:

...

#include"Unit1.h"

#include

...

Еще во вставленном коде мы используем две неописанные пока переменные nиm. Именно они и оперделяют, сколько у нашей звездочки будет лучей (n) и через сколько вершин происходит соединение (m). Эти две переменные надо ввести в переменные классаTForm1 (в заголовочном файле *.h):

private: // User declarations

int n, m;

...

Далее этим переменным надо задать некоторое начальное значение. Это мы сделаем в обработчике OnCreateдля нашей формы. Для создания заготовки для обработчика делаем двойной щелчок на строкеOnCreateвObjectInspector'е. Кроме того, здесь же мы зададим некоторые начальное значения для нашихedit'ов:

void __fastcall TForm1::FormCreate(TObject *Sender)

{

n=5;

m=2;

Edit1->Text="5";

Edit2->Text="2";

}

Двигаемся дальше. Теперь нам надо написать обработчик для нашей кнопки. Можно опять воспользоваться ObjectInspector'ом, но проще сделать в конструкторе формы двойной щелчок на кнопке. В созданной заготовке напечатайте следующие строки:

void__fastcallTForm1::Button1Click(TObject*Sender)

{

n=StrToInt(Edit1->Text); //Количество лучей

m=StrToInt(Edit2->Text); //Через сколько соединяем

Invalidate();

}

В этом коде мы читаем значения из наших edit'ов, превращаем их в целые числа с помощью функцииStrToIntи затем вызываем функциюInvalidate(), которая заставляет наше окно перерисоваться с новыми значениямиnиm. Вообще говоря, методInvalidate() отправляет нас в обработчик дляOnPaint, в котором мы собственно говоря нашу звезду и рисуем.

Запускаем программу и смотрим на результат:

Если зададите другие значения для nиm, то и звездочка будет другой.

С первой программой все!

Теперь сделаем простой текстовый редактор

На этом занятии мы с вами сделаем простой текстовый редактор. Будет он уметь следующее - открывать текстовые файлы и сохранять внесенные пользователем изменения. Наша программа будет использовать стандартные диалоги - для открытия и сохранения файлов соответственно. Итак, запустите C++Builder, и разместите на форме компонентыMemo(с вкладкиStandardПалитры компонетов) иOpenDialogиSaveDialog(с вкладкиDialogs):

Далее измените свойство Alignдля компонентаMemo1 наalClient. Это означает, что он будет занимать всю клиентсткую область, т. е. наш редактор будет занимать все окно. Еслы мы в работающей программе поменяем размер, то все равно нашMemo1 будет "растянут" на всю форму. После внесенных изменений наша форма пример приблизительно следующий вид:

Теперь приступаем к коду. Мы хотим, что бы диалог для сохранения появлялся при нажатии на крестик в правом верхнем углу или при комбинации клавиш Alt+F4. При этом мы хотим, чтобы такой диалог появлялся только тогда , когда документ как-то изменили. А если в редактируемый документ никакие изменения не вносились, то и диалог появлятся не будет. Для этого добавляем черезObjectInspectorобработчик дляOnCloseформыForm1.Вписываем в обработчик следующие строки:

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)

{

if(bDirty){ //Если документ изменялся

//Вызываем диалог

SaveDialog1->Execute();

//Сохраняем данные в файле

Memo1->Lines->SaveToFile(SaveDialog1->FileName);

}

}

Здесь мы используем переменную bDirtyтипаbool, показывающую, был документ изменен или нет. Ее мы еще не ввели. Исправим это в заголовочном файле (с расширением *.h):

...

public: // User declarations

bool bDirty;

Добавим обработчик для OnCreateдля нашей формы и впишем него строку:

void __fastcall TForm1::FormCreate(TObject *Sender)

{

bDirty=false; //Изменений в документе пока нет

}

Теперь добавим код, выполняющийся при изменении текста в Memo1:

void __fastcall TForm1::Memo1Change(TObject *Sender)

{

bDirty=true; //Документ изменили

}

С сохранением в файл все. Теперь остается добавить диалог для открытия файла. Давайте сделаем так, чтобы он появлялся при двойном щелчке на нашем Memo1. Для этого в обработчик дляOnDblClickнашегоMemo1 добавьте следующий код:

void __fastcall TForm1::Memo1DblClick(TObject *Sender)

{

OpenDialog1->Execute();

//Загружаем данные их файла

Memo1->Lines->LoadFromFile(OpenDialog1->FileName);

//Устанавливаем признак того, что документ не менялся

bDirty=false;

}

Все! Запускаем программу. Двойным щелчком можно загрузить в программу некоторый файл, поредактировать его и сохранить. Конечно, наша программа не работает как настояшие редакторы (например, что будет, если мы в диалоге для сохранения файла не выберем ни одного файла? Ничего хорошего).