День до сдачи работы мы справимся, и ты получишь Отлично по своему предмету! Только представь ты занимаешься своим любимым делом, пока твои лохиодногруппники теряют свои нервные клетки Проникнись Это бесценное ощущение Курсовая,
Скачать 389.95 Kb.
|
4.6 Стратегия отладки Windows-программ Ошибки в программе могут быть самыми разнообразными. Но для Windows-приложений характерны следующие : - вызов неверной функции, когда вместо одной функции по ошибке вызывается другая; - вызовам Windows API передаются неправильные аргументы; - задание неверных параметров цикла; - ошибка в условии операторов if, switch, while и т.д., приводящая к неправильному ветвлению; - возникновение не предусмотренного программистом варианта реакции системы. Для отладки программ обычно используется несколько стандартных операций: * установка точек прерывания (breakpoints); * просмотр содержимого переменных и участков памяти; * подстановка ложных данных для моделирования ситуации "что - если"; * ложные вызовы. DOS-программу можно выполнять пошагово, перебираясь от одной строки исходного текста к другой В Windows же это нереально. Нужно поставить точку прерывания на интересующем вас участке программы и запустить ее на выполнение командой Run - Run. Достигнув точки прерывания, программа приостановит свое выполнение, давая возможность программисту приступить к отладочным действиям. В программах на C++ Builder, точки прерывания удобнее всего ставить внутри обработчиков событий. Простейший способ установить точку прерывания - нажать на клавишу Повторное нажатие на Другой способ установить точку прерывания - щелкнуть мышью на левом краю окна редактирования. Когда ошибочный обработчик найден, нужно приступать к уточнению места ошибки. Для этого Можно выполнять программу шаг за шагом командой Trace Into ( клавиша После того как программа отлажена, необходимо перетранслировать ее, установив в главном меню в разделе Options->C++ опцию Release. 4.7 Использование компонент VCL в разработке программ Использование меню. Страница Standard содержит наиболее часто используемые компоненты – к ним относятся компоненты MainMenu и PopupMenu. Каждому пользователю Windows, раскрывающееся меню представляет собой подробный список таких команд, как Open или Exit. В большинстве приложений в главном меню перечислены имена одного или нескольких раскрывающихся подменю. Главное меню (компонент MainMenu). Используется для создания главного меню приложения, которое всегда отображается под заголовком окна. Всплывающее меню (компонент PopupMenu). Используется для создания всплывающих меню, которые появляются при при щелчке правой кнопкой мыши, когда указатель, мыши находится внутри клиентной области окна. Для того чтобы построить главное меню программы, необходимо выполнить следующее: 1. На форму главного окна поместите объект MainMenu. По умолчанию в C++ Builder. ему присваивается имя MainMenu1. 2. Установите свойство формы Menu равным имени объекта MainMenu. 3. Дважды щелкните на объекте MainMenu1 и используйте Menu Designer для ввода команд меню. Для того чтобы создать всплывающее меню, которое появляется при щелчке правой кнопкой мыши, выполните следующее: 1. Поместите на форму объект РорupМеnu. По умолчанию в C++ Builder ему присваивается имя PopupMenu1. 2. Присвойте PopupMenu1 свойству формы PopupMenu. 3. Дважды щелкните на объекте PopupMenu1 и используйте Menu Designer для ввода команд меню. Рассмотрим пример – разработаем простейший редактор текста. Создайте файл с именем 1.txt в каталоге, в котором будет храниться пример и запишите в него какой-либо текст. Запустите C++ Builder. 1.Поместите на форму компонент Memo. Согласно рисунка измените размеры. В инспекторе объектов установите ScrollBars в позицию ssVertical (вертикальная полоса прокрутки). На поле Memo вы видите текст Memo1. Для того чтобы он исчезал при запуске программы щелкните мышью по форме и напишите между {и}; команду очистки окна Memo1: Memo1->Clear(); 2. Поместите на форму кнопку Button. Свойство Caption в инспекторе объектов измените на Close. Щелкните на кнопке. и напишите код: Close(); - по этой команде программа прекращает работу. 3. Поместите на форму компоненты MainMenu и PopupMenu. Щелкните по форме и напишите в свойствах MainMenu- MainMenu1 и PopupMenu - PopupMenu1 соответственно. 4.Щелкните два раза на компоненте MainMenu. Появляется конструктор меню. В инспекторе объектов свойство Сaption измените на &File(&- быстрая клавиша ALT+F). Нажмите клавишу Enter. Далее в конструкторе меню щелкните мышью под командой File и опять свойство Caption измените на &Open, ниже опять появляется синий квадратик напишите свойство Caption &Save, а затем на следующем пункте меню измените Caption на E&xit. 5.Щелкните мыщью рядом с &File (правее) и запишите в Caption &Help. Таким образом все пункты меню мы записали и они должны появитсяна форме. 6.Начнем ставить в соответствие событиям (пунктам меню) программный код. Щелкните мышью на команде File, поставте курсор на Open и щелкните мышью. между командами { и } запишите код: Memo1->Lines->LoadFromFile("1.txt"); По этой команде текст из файла 1.txt загрузится в окно Memo. Свойство Lines объекта Memo это объект типа строка символов, которая отображается в окне. Метод LoadFromFile позволяет загрузить файл в Memo. Перед нами редактор текста - текст можно модифицировать, а затем записать. 7.Щелкните мышью на команде File, поставте курсор на Save и щелкните мыщью. между командами begin и end; запишите код: Memo1->Lines->SaveToFile("1.txt"); По этой команде текст запишится в файл 1.txt. 8. Наиболее интерсные действия с командой Exit. Стандартно можно было-бы щелкнуть мышью на команде Exit и записать код Close();, но этот код у нас есть по нажатию клавиши Button программа прекращает работу, поэтому мы делаем так: 8.1.В инспекторе объектов в выпадающем меню (в шапке) выбираем опцию Exit1. 8.2 Переходим в инспекторе объектов на страницу Events и щелкаем мышью в поле события OnClick. 8.3.Выбираем Button1Click. То есть мы совмещаем события: - нажатие клавиши(закрытие программы); - выбор опции меню Exit. 9. В дизайнере меню заходи в раздел Help -щелкаем мышью и пишем код: Canvas->TextOut(10,10,"Помощи пока нет!"); 10. Добавляем всплывающее меню. Щелкаем дважды на компоненте PopupMenu. 11.Появляется дизайнер меню. Первую опцию меню указываем в Caption - &Open, следующую &Save и последнюю E&xit(также как в MainMenu). 12.Щелкаем на опции Open.В выпадающем меню инспектора объектов выбираем опцию Open2. Переходим в инспекторе объектов на страницу на страницу Event и щелкаем мышью в поле события OnClick. Находим Open1Click и щелкаем мышью (теперь мы совместили событие открытие файла 1.txt в меню MainMenu и PopupMenu); Соответственно выбираем опцию &Save и совмещаем с событием Save1Click. Далее совмещаем опцию Exit с событием Button1Click. Далее программу запоминаем и транслируем. Программа будет выглядеть так: //--------------------------------------------------------------------------- #include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { Memo1->Clear(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Open1Click(TObject *Sender) { Memo1->Lines->LoadFromFile("1.txt"); } //--------------------------------------------------------------------------- void __fastcall TForm1::Save1Click(TObject *Sender) { Memo1->Lines->SaveToFile("1.txt"); } //--------------------------------------------------------------------------- void __fastcall TForm1::Help1Click(TObject *Sender) { Canvas->TextOut(10,10,"Помощи пока нет!"); } //--------------------------------------------------------------------------- Кнопки переключатели и выключатели. Кнопки, переключатели и выключатели - это основа графического пользовательского интерфейса, поэтому C++ Builder предоставляет целый "набор" всевозможных кнопок, переключателей и выключателей. Кроме того, имеется возможность объединять группы кнопок и использовать организующие компоненты - фаски и панели. Кнопка (компонент Button). Стандартный управляющий элемент Windows. Кнопка с растровым изображением (компонент BitBtn). Компонент BitBtn работает также, как и компоненты Button, но отличаются от последних наличием цветной пиктограммы, визуально представляющей действие кнопки. Кнопка панели инструментов (компонент SpeedButton). Обычно эти компоненты используются для создания панелей инструментов. На кнопках BitBtn или SpeedButton отображается пиктограмма (glyph), которая представляет собой растровое изображение Windows. Несмотря на то, что размеры пиктограмм не ограничены, обычно применяется стандартный размер - 16х16 пикселей при 16 цветах. Свойство glyph компонента является объектом, имеющим тип TBitmap. Пиктограммы содержат от одного до четырех отдельных блоков, хранящихся в одном файле. эти блоки представляют различные состояния кнопки. 1. Состояние кнопки = ненажатое (обычное состояние). 2. Состояние кнопки = недоступное (отображение серым цветом; Enabled = false). 3. Состояние кнопки = нажатое (отображение смещенное и, возможно, затемненное). 4. Состояние кнопки = фиксированное нажатое (только для кнопок панели инструментов). Пиктограммы можно назначать как при создании формы, так и во время работы программы(например, для получения динамического визуального эффекта либо для изменения вида кнопки в зависимости от внешних условий). Для того чтобы пиктограмма загружалась во время работы, разместите объект BitBtn на форме, щелкните на нем дважды и в обработчик события OnClick вставьте следующие операторы: BitBtn1->Glyph->LoadFromFile (“alarm.bmp"); Выключатель (компонент CheckBox). Это также стандартный управляющий элемент Windows, состоящий из метки и небольшого квадратика. Щелкнув на нем, пользователь может включить или выключить параметр или режим, описанный меткой. Группа (компонент GroupBox). Данный компонент предназначен для логического объединения множества переключателей и других объектов. Фокус ввода пользователи могут перемещать между группами с помощью клавиши Переключатель (компонент RadioButton). На группу или панель можно поместить несколько переключателей, но в большинстве случаев для создания наборов переключателей гораздо удобнее использовать компонент RadioGroup. Кроме того, наборы переключателей можно распологать непосредственно на форме. Группа переключателей (компонент RadioGroup). Этот компонент имеет много общего с группой, но он намного удобнее в использовании при создании наборов переключателей. Для организации переключателей необходимо только указать текст переключаемых параметров в свойстве Items группы переключателей. Строка ввода с настройкой (компонент SpinEdit) - компонент, представляющий собой кнопку настройки, объединенную со строкой ввода. Щелчки на кнопке приводят к увеличению или уменьшению числа, находящегося в строке ввода. Кроме того, пользователи могут вводить число непосредственно в самой строке ввода, которая к ттому же распознает команды работы с буфером обмена Windows. Панель (компонент Panel). Данный компонент позволяет упорядочить загроможденные информацией окна, а также является основой создания панелей инструментов и строк состояния. Фаска (компонент Bevel). Этот чисто визуальный компонент выглядит в окне как прямоугольный выступ или углубление. Фаска также используется для создания горизонтальных и вертикальных линий. Рассмотри пример использования рассмотренных выше компонент. Начнем разработку нового проекта. Согласно рисунка поместим на верхнюю часть формы компонент Panel. Свойству Caption присвоим “Демонстрация”. Далее на форму добавим компонент Label и установим свойство Caption “Имя”. Под метку добавим компонент Edit. Используя инспектор объектов удалим символы из свойства Text объекта Edit. Далее добавим компонент Memo. В инспекторе объектов установим ScrollBars в позицию ssVertical (вертикальная полоса прокрутки). Далее в инспекторе объектов двойным щелчком откроем свойство Lines, удалим текст Memo1 и четыре раза нажмем клавишу Enter(будем работать с четыремя строками). Установим на форме компоненты RadioGroup, Scrollbar и ComboBox. Дважды щелкнем на правее свойства Items и введем четыре строчки: серый, голубой, желтый, красный. Дважды щелкнем по компоненте RadioGrouo и введем код: if(RadioGroup1->ItemIndex==0){Form1->Color=clSilver;} if(RadioGroup1->ItemIndex==1){Form1->Color=clBlue;} if(RadioGroup1->ItemIndex==2){Form1->Color=clYellow;} if(RadioGroup1->ItemIndex==3){Form1->Color=clRed;} Этот фрагмент кода позволяет изменять цвет формы в зависимости от отмеченной кнопки. Далее дважды щелкнем по компоненте Scrollbar и добавим код: RadioGroup1->ItemIndex=ScrollBar1->Position; Этот фрагмент кода позволяет изменять цвет формы в зависимости от положения ползунка. Поместим на форму копонент GroupBox и добавим две кнопки Button, две кнопки BitBtn , две RadioButton и две Checkbox. Щелкнем по кнопке Button1 и введем код: //Очистить содержимое Memo Memo1->Clear(); //Скопировать в Memo текст, введенный в Edit Memo1->Lines->Add(Edit1->Text); //Скопировать в Memo текст из Combobox Memo1->Lines->Add(ComboBox1->Text); // Если нажата первая радиокнопка, то цвет Memo белый if (RadioButton1->Checked) Memo1->Color=clWhite; // Если нажата первая радиокнопка, то цвет Memo светло-голубой if (RadioButton2->Checked) Memo1->Color=clAqua; Щелкнем по кнопке Button2 и введем код: Close(); //закончить работу Щелкнем по кнопке BitBtn1 и введем код: //если помечена кнопка Checkbox1, то размер шрифта на форме 12 // иначе размер шрифта 8 if (CheckBox1->State==cbChecked) Font->Size=12; else Font->Size=8; //если помечена кнопка Checkbox2, то цвет шрифта на форме фиолетовый // иначе цвет шрифта черный if (CheckBox2->State==cbChecked) Form1->Font->Color=clPurple; else Form1->Font->Color=clBlack; Щелкнем по кнопке BitBtn2 и введем код: Form1->Hide();// свернуть форму с именем Form1 AddTab->Show();// показать форму с именем AddTab Как работать с двумя формами рассмотрим дальше. Вся программа будет выглядеть следующим образом: //--------------------------------------------------------------------------- #include #pragma hdrstop #include "Unit1.h" #include "Unit2.h" //--------------------------------------------------------------------------- #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::RadioGroup1Click(TObject *Sender) { if(RadioGroup1->ItemIndex==0){Form1->Color=clSilver;} if(RadioGroup1->ItemIndex==1){Form1->Color=clBlue;} if(RadioGroup1->ItemIndex==2){Form1->Color=clYellow;} if(RadioGroup1->ItemIndex==3){Form1->Color=clRed;} } //--------------------------------------------------------------------------- void __fastcall TForm1::ScrollBar1Change(TObject *Sender) { RadioGroup1->ItemIndex=ScrollBar1->Position; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { Memo1->Clear(); Memo1->Lines->Add(Edit1->Text); Memo1->Lines->Add(ComboBox1->Text); if (RadioButton1->Checked) Memo1->Color=clWhite; if (RadioButton2->Checked) Memo1->Color=clAqua; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- void __fastcall TForm1::BitBtn1Click(TObject *Sender) { if (CheckBox1->State==cbChecked) Font->Size=12; else Font->Size=8; if (CheckBox2->State==cbChecked) Form1->Font->Color=clPurple; else Form1->Font->Color=clBlack; } //--------------------------------------------------------------------------- void __fastcall TForm1::BitBtn2Click(TObject *Sender) { Form1->Hide(); AddTab->Show(); } //--------------------------------------------------------------------------- Построим вторую страницу приложения. Добавим в разрабатываемый проект вторую форму и дадим ей имя AddTab и сохраним под именем AdditionalTab.pas. Разместим визуальные компоненты на форме согласно рисунка. Поместим на форму в левый нижний угол компонент Bevel. Поместим три кнопки типа BitBtn в нижний левый угол формы на компонент Bevel. Свойство Kind для BitBtn1 и BitBtn2 установим равным bkCustom, а для BitBtn3 – равным bkClose. Установим на кнопках для свойств Caption текст, соответствующий рисунку. Для каждой из кнопок установим гравировку (glyph), используя готовые гравировки, поставляемые в комплекте с языком или создавая свои с помощью редактора Image Editor в меню инструментов Tools. Добавляем код действия для кнопок: BitBtn1: Form1->Show();\\ показать форму Form1 AddTab->Hide();\\свернуть форму AddTab BitBtn2: ShowMessage("Пока НЕТ");\\следующей страницы пока нет BitBtn3: Form1->Close();//закрыть форму Form1 Для правильного закрытия приложения и освобождения ресурсов необходимо добавить для события Close формы Form1 код: Application->Terminate();\\освободить ресурсы В левом верхнем углу формы разместим компонент Shape (укажем в свойстве Shape значение stEllipse), компонент Panel и на нем две кнопки SpeedButton и компонент Image, в который можно загрузить какое-либо изображение. Кнопки SpeedButton могут находиться в состоянии: Up- верхнее, Disabled – отключено, Down – нижнее, Stay Down – прижатое. Для каждого состояния отображается соответствующий элемент гравировки. Для использования этих состояний с помощью встроеннного графического редактора создается матрица 16х64 точки. Изображение будет иметь четыре квадратные зоны. Установим свойство NumGlups для Speedbutton1 равным 4, а свойство GroupIndex равным 1. Дважды по кнопки SpeedButton1 и пишем код: if (SpeedButton1->Down==true) Image1->Visible=false; Shape1->Brush->Color=clRed; Код означает, что если нажата кнопка, то изображение Image1 исчезает, а изображение фигуры Shape1 красного цвета. Дважды щелкаем по кнопке SpeedButton2 и записываем код: if (SpeedButton1->Down=true) {Image1->Visible< Shape1->Brush->Color=clLime; Для SpeedButton1 используем свойство Hint (подсказка). В этом свойстве хранится строка подсказки, которая появляется, когда курсор мыши находится над кнопкой. ShowHint необходимо установить в true. Добавим на форму компонент Label свойство Caption зададим Phone. Под меткой установим компонент MaskEdit. Дважды щелкнем на свойстве EditMask и запусти редактор маски ввода. Далее щелкнем на Phone и нажмем клавишу OK. Компонент MasEdit будет настроен на прием телефонных номеров. Поместим на форму компонент StringGrid и установим свойства: RowCount и ColCount. Свойства FixedCols и FixedRows установим в 0. Подберем размер сетки чтоб были видны девять ячеек. Добавим на форму кнопку со свойством Caption Fill Grid. Дважды щелкнем на ней и наберем код: int x,y; for (x=0; (x<=StringGrid1->ColCount-1);x++) for ( y=0;(y<=StringGrid1->RowCount-1);y++) StringGrid1->Cells[x][y]=("Coord. "+ IntToStr(x)+"-"+IntToStr(y)); Далее поставим на форму панель с прокруткой ScrollBox и разместим на ней компоненты:BitBtn со свойством Kind равным bkHelp. Добавим на ScrollBox Panel. Дважды щелкаем на кнопке BitBtn4 и добавляем код: ShowMessage(" Test "); Компонент ScrollBox c размещенными на нем компонентами позволяет продемострировать способности показвать фрагменты, которые не помещаются в зоне использования. Общий вид программного модуля AddTab: //--------------------------------------------------------------------------- #include #pragma hdrstop #include "Unit2.h" #include "Unit1.h" //--------------------------------------------------------------------------- #pragma link "Grids" #pragma resource "*.dfm" TAddTab *AddTab; //--------------------------------------------------------------------------- __fastcall TAddTab::TAddTab(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TAddTab::BitBtn1Click(TObject *Sender) { Form1->Show(); AddTab->Hide(); } //--------------------------------------------------------------------------- void __fastcall TAddTab::BitBtn3Click(TObject *Sender) { Form1->Close(); } //--------------------------------------------------------------------------- void __fastcall TAddTab::FormClose(TObject *Sender, TCloseAction &Action) { Application->Terminate(); } //--------------------------------------------------------------------------- void __fastcall TAddTab::SpeedButton1Click(TObject *Sender) { if (SpeedButton1->Down==true) {Image1->Visible=false; Shape1->Brush->Color=clRed; } } //--------------------------------------------------------------------------- void __fastcall TAddTab::SpeedButton2Click(TObject *Sender) { if (SpeedButton1->Down=true) {Image1->Visible< Shape1->Brush->Color=clLime; } } //--------------------------------------------------------------------------- void __fastcall TAddTab::Button1Click(TObject *Sender) { int x,y; for (x=0; (x<=StringGrid1->ColCount-1);x++) for ( y=0;(y<=StringGrid1->RowCount-1);y++) StringGrid1->Cells[x][y]=("Coord. "+ IntToStr(x)+"-"+IntToStr(y)); } //--------------------------------------------------------------------------- void __fastcall TAddTab::BitBtn4Click(TObject *Sender) { ShowMessage(" Test "); } //--------------------------------------------------------------------------- void __fastcall TAddTab::BitBtn2Click(TObject *Sender) { ShowMessage("Пока НЕТ"); } //--------------------------------------------------------------------------- void __fastcall TAddTab::MaskEdit1Change(TObject *Sender) { } //--------------------------------------------------------------------------- Рассмотрим еще один проект. Поместим на форму согласно рисунка компоненты: TabControl (на него помести панель Panel с именем Tab1), ProgressBar, TrackBar, TreeView, Timer, OpenDialog, Edit, Label (с именем TreeView), Panel, Button (с именем Open Dialog). Дважды щелкнем на свойстве Tabs сомпоненты TabControl. В редакторе строк введем названия закладок – Tab1, Tab2, Tab3. Свойство Max компонентов ProgressBar и TrackBar установим равное 10. В событие OnChange компоненты TrackBar введем код: ProgressBar1->Position=TrackBar1->Position; Дважды щелкнем по компоненте Timer и добавим код к событию OnTimer, предварительно указав свойство Interval равным 1000(1 секунда): i++; //интервал счетчика 1 секунда Panel2->Caption = IntToStr(i);// панель показывает в секундах время // работы программы Необходимо внимательно посмотреть на листинг программы и обратить внимание на переменную i. Для компонента TreeView дважды щелкнем на поле справа от свойства Items, а затем добавим к дереву пункт Level1, затем к узлу второго уровня пункт Level2 и далее Level3. К кнопке OpenDialog добавим код: OpenDialog1->FileName="*.*"; if (OpenDialog1->Execute()){ Edit1->Text=OpenDialog1->FileName; В результате программа прнимет вид: //--------------------------------------------------------------------------- #include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma resource "*.dfm" TForm1 *Form1; int i=0; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::TrackBar1Change(TObject *Sender) { ProgressBar1->Position=TrackBar1->Position; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { OpenDialog1->FileName="*.*"; if (OpenDialog1->Execute()){ Edit1->Text=OpenDialog1->FileName; } } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { i++; Panel2->Caption = IntToStr(i); } //--------------------------------------------------------------------------- 4.8.Графические компоненты. Для работы с графикой в C++Builder имеются графические компоненты: Image - используется для импоpта на фоpму pастpовых изобpажений, пиктогpамм и метафайлов; - Shape - используется для создания геометpических фигуp;. - PaintBox - используйется для создания рисунков на компонентах, котоpые не имеют свойства Canvas (напpимеp, компонент Panel). В C++Builder гpафические опеpации выполняются с использованием свойства Canvas, котоpое поддеpживается многими компонентами. Напpимеp, свойство Canvas есть у фоpмы, а так же у TBitmap, TComboBox, TListBox, TPaintBox и дpугих компонентов. Canvas пpедставляет собой объект, наделенный собственными полномочиями, для чего класс TCanvas поддеpживает множество свойств, методов и событий. Чаще всего используется свойство Canvas. В пpоцессе pакзpаботки это свойство недоступно в окне Object Inspector. Для того, чтобы использовать Canvas, необходимо написать опеpатоpы, котоpые пpисваивают свойствам Canvas значения и вызывают методы Canvas. В таблице приведены методы, свойства и события, реализуемые TСanvas.
Рассмотрим примеры: Все визуальные компоненты имеют свойства Top (координата X) и Left (координата Y). Значения X и Y измеряются в пикселах (пиксел - наименьшая частица поверхности рисунка, которой можно манипулировать). В зависимости от количества бит, на пиксел различаются различные виды графики от 8- битовой до 24-битовой. В связи с этим возможно отображение до 16 миллионов цветов в стандарте RGB. Рассмотрим пример рисования синусоиды при нажатии кнопки на форме: //--------------------------------------------------------------------------- #include #include #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { float X,Y; int PX,PY; int H; //определяем половину стороны внизу формы H=Form1->Height / 2; for (PX= 0; PX < Form1->Width; PX++) { //масштаб X приводится к 2 ПИ, чтоб сделать //полную волну X=PX*(2*3.1415/Form1->Width); Y=sin(X); PY=(0.6*Y*H)+H; Canvas->Pixels[PX][PY]= 0;//устанавливаем черный цвет пикселя } } //--------------------------------------------------------------------------- Каждое свойство Canvas имеет воображаемое перо для рисова- ния линий и контуров и команды: - Form1->Canvas->MoveTo(X,Y); -передвигает перо в точку с координатами(X,Y) без рисования; - Form1->Canvas->Point(X,Y);- рисует точку; - Form1->Canvas->LineTo(X,Y); -чертит линию от текущей по- зиции до точки с координатами X,Y; Form1->Canvas->Pen->Color:=цвет; - устанавливает цвет пе- ра(clBlue - голубой или RGB(0,0,255)); - Form1->Canvas->Pen->Width:=толщина; - устанавливает толщи- ну пера в пикселях; - Form1->Canvas->Pen->Style:=стиль; - устанавливает стиль пе- ра(например,пунктирная линия - psDot); - Form1->Canvas->Pen->Mode:=режим; - устанавливает режим ри- сования(pmNot- цвет пера инверсный цвету фона, pmCopy - перо текущего цвета); - Form1->Canvas->Brush->Color:=цвет; - устанавливает цвет закрашенного графического объекта; - Form1->Canvas->Brush->Style:=стиль; - стиль закраски(напри- мер,bsSolid - закраска одним цветом, bsCross -решеткой). Анимация в C++ Builder. Анимация - это движущаяся графика. Рассмотрим программу, которая создает анимационную последовательность изображений 10 эллипсов, которые движутся от середины компонента PaintBox к его границам в случайных направлениях при нажатии кнопки Button. Процедура рисует эллипс, а затем стирает его изображение. //--------------------------------------------------------------------------- #include #pragma hdrstop #include #include "Unit1.h" //--------------------------------------------------------------------------- #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { double RadReal; int Angle,X,Y; int Count,Count2; for(Count2= 1; Count2< 10; Count2++) { Angle = random(368); RadReal = (Angle * M_PI)/180; for(Count= 1; Count< 100; Count++) { X = (double)/*<<-------*/(Count*sin(RadReal))+100; Y = (double)/*<<-------*/(Count*cos(RadReal))+100; // рисуем эллипс голубым цветом PaintBox1->Canvas->Brush->Color =clBlue; PaintBox1->Canvas->Ellipse (X-6,Y-6,X+6,Y+6); // стираем эллипс белым цветом PaintBox1->Canvas->Brush->Color = clWhite; PaintBox1->Canvas->Rectangle(0,0,200,200); } } } //--------------------------------------------------------------------------- Если запустить программу на выполнение, то изображение эллипсов будет мерцать, хотя они будут двигаться очень быстро. Для преодоления этого недостатка в аннимации используют метод двойной буферизации. В этом случае используют две плоскости - одна отображается на экране, а вторая используется для рисования.Далее плоскости меняются местами. Одним из способов организации двойной буферизации - создание в памяти битовой матрицы в качестве промежуточного буфера. Изображение рисуется в битовой матрице, а по завершению кадра копируется в отображаемый буфер. Рассмотрим предыдущий пример с использованием битовой матрицы. //--------------------------------------------------------------------------- #include #pragma hdrstop #include #include "Unit1.h" //--------------------------------------------------------------------------- #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { double RadReal; int Angle,X,Y; int Count,Count2; // создание битовой матрици Graphics::TBitmap *TheBitmap = new Graphics::TBitmap(); // определяем ее размеры TheBitmap->Height = 200; TheBitmap->Width = 200; for(Count2= 1; Count2< 10; Count2++) { Angle = random(368); // занести случайное число RadReal = (Angle * M_PI)/180; for(Count= 1; Count< 100; Count++) { X = (double)(Count*sin(RadReal))+100; Y = (double)(Count*cos(RadReal))+100; // очистка экрана TheBitmap->Canvas->Brush->Color = clWhite; TheBitmap->Canvas->Rectangle(0,0,200,200); // рисование эллипса TheBitmap->Canvas->Brush->Color = clBlue; TheBitmap->Canvas->Ellipse(X-6,Y-6,X+6,Y+6); // копирование битовой матрици на экран PaintBox1->Canvas->CopyRect(Rect(0,0,200,200), TheBitmap->Canvas, Rect(0,0,200,200)); } } // освобождаем память выделенную под битовую матрицу delete TheBitmap; } //--------------------------------------------------------------------------- При запуске примера видно, что эллипсы движутся плавно, но процедура выполняется медленнеее |