Візуальний облік вхідних даних інтерфейсу RS-232
p align="left">Поліпшене налагодженняІнтегрований відладчик має багато нових властивостей, включаючи віддалені і багатопроцесорне налагодження, перегляд коду центрального процесора, інспекторів, удосконалені точки переривання, відладчик специфічних підміню і закріплених вікон. Удосконалення Active Delphi4 забезпечує розширену підтримку Active. Удосконалення VCL Ієрархія об'єктів Delphi була розширена, щоб включити новий компонент для NT Service додатків. Крім того, новий компонент виконуваного списку (на Стандартній сторінці палітри), дозволяє Вам централізувати керування меню і команд від кнопок. Керування VCL розширене, щоб підтримувати drag-and-drop перетаскування, забезпечувати додатковий контроль над розміщенням вікна, і багато чого іншого. 4. ПРОЕКТНО-ТЕХНОЛОГІЧНИЙ РОЗДІЛ 4.1 Опис діаграми станів Розглянемо діаграму стану програми, яку зображено на рис. 1. Рис. 1. Діаграма стану програми При ініціалізації головної форми здійснюються початкові настройки для відображення вхідних даних та стандарнте заповнення структур для роботи з портами. Після ініціалізації основної форми користувач має доступ до Головного меню та панелі інструментів. При виборі пункта Головного меню або кнопки з панелі інструментів відбуваєтьсявиконання певних дій. Опишемо основні пункти Головного меню. Меню включає в себе наступні пункти: Файл Запуск Вид Настройка Допомога Пункт Файл виконує основні операції збереження даних, створення нового графіка та вихід. Пункт Файл містить наступні операції: Новий графік. Призначений для очищення динамічного списку, який містить в собі дані, отримані при зчитуванні з порта або створені генератором. Завантажити дані. Призначений для завантаження даних в динамічний список з файла, який зберігав користувач. Файл повинен мати розширення *.grf, та містити такі дані: дату створення виміру, знак „|”, числове значеня виміру(тип integer). Зберегти графік. Призначений для збереження графіку, який отримав користувач на екрані в результаті роботи програми. Якщо користувач бажає зберегти графік, який не відображається на екрані, то для цього йому необхідно отримати зображення необхідної частини графіка за допомогою полоси прокрутки. Зберегти дані. Призначений для збереження результатів вимірювання в файлі з розширенням *.grf. Вихід. Вихід з програми без попередження про збереження результатів. Пункт Запуск має всього два підпункти, які призначені відповідно для запуску та зупинки отримання даних. При запуску дані, що надійшли передаються в динамічний список, який в подальому є основою для відображення даних на екрані в графічному та текстовому вигляді. Зупинка призначена для зупинки таймера відліку, який призначений для отримання даних з порту в період вказаний користувачем. Пункт Вид призначений для вибору графічного відображення даних. Даний пункт містить групу перемикачів, що дозволяють відображати графік у вигляді простого графіку функції, або у вигляді стовбцевої гістограми. Пункт Настройка призначений для задання опцій портів, а також відображення графіка функції в необхідному для користувачу вигляді. Даний пункт розділений на дві частини: Вибір джерела вхідних даних. Задання опції відображення графіка для сітки та осей координат. Вибір джерела даних являє собою радіогрупу підпунктів для вказання звідки саме будуть зчитуватися дані. Тут передбачена подальше вдосконалення програми, та розширення її можливостей для роботи з LPT портами. Для наглядного зображення працездатності програми в програмі було також використано генератор випадкових чисел. Задання опцій відображення призначені для вибору користувачем можливих опцій настройки портів та таймера, задання відображення осей координат та сітки графіка, вибір кольорів та інше. Розділ Допомога призначений для виводу інформації про прграму, а також виклик вікна, в якому виводиться інструкція користувача даної програми. Для зручності користування програмою всі основні дії, які пов'язані з роботою програми, продубльовані у вигляді кнопок та інших елементів інтерфейсу користувача на основній формі. Так було створено Панель інструментів та задання опцій таймера. 4.2 Опис відношення модулів Рис. 2. Відношення модулів Ініціалізує візуальну обробку даних модуль MainForm. На даній формі ми розмістили елементи інтерфейсу користувача, компоненту для порта, компоненти для роботи головного меню, а також основну компоненту для відображення даних - GraphicDiagram. Як додаткові елементи інтерфейсу, на основну форму були добавлені компоненти для запису та зчитування файлів даних та полосу прокрутки, а також включає в себе основну роботу з реакціями на натискування кнопок панелі інструментів, відображення настройки частоти таймера. Модуль СPort включає в себе всі необхідні структири для функціонування СОМ-порта, а також процедури та функції для настройки порта, отримання та запис даних в порт та деякі інші. Модуль Unit3 призначений для створення додаткових елементів інтерфейсу користувача, і включає в себе відображення форми для задання опцій відображення графіка. В даному модуді створерий багатосторінковий блокнот, на листах якого відображаються опції відображення осей координат та сітки графіка. Модуль Unit4 призначений для запуску окремої модальної форми настройки частоти таймера. Тут вказується частота, з якою програма буде звертатися до джерела даних для їх отримання. Частоту необхідно задавати в мілісекундах. 4.2 Техніко-економічні показники Програмний продукт складається з файлів: MainForm.dcu MainForm.dfm - основна форма проекту MainForm.pas CPort.dcu CPort.dfm - файли, які оперують структурами СОМ-портів CPort.pas Project1.cfg Project1.dof Project1.dpr - файли проекту Project1.dsk Project1.exe Project1.res Unit3.dcu Unit3.dfm- файли, що релізують настройку відображення графіка Unit3.pas Unit4.dcu Unit4.dfm- реалізація форми настройки частоти таймера Unit4.pas aboutBox.dcu aboutBox.dfm - форма відомостей про програму та інструкція aboutBox.pas користувача Загальний розмір папки з проектом та тестовими результами становить 1,03 Мb. Запускний файл Project1.exe має розмір 510Кb та отриманий за допомогою компілятора Inprise DELPHI 6.0. 4.5. Виклик та завантаження Трансляція, редагування, завантаження та виконання програми відбувається за допомогою стандартних засобів операційної системи та інтегрованого середовища Delphi 6. Для завантаження програми необхідно завантажити файл Project1.exe. 5. ОПИС РОБОТИ З ПРОГРАМОЮ 5.1 Головна форма програми Рис.3 Основна форма програми. На рис.3. зображений вигляд основної форми. Закриття цього вікна приведе до завершення роботи програми. У верхній частині форми ми можемо побачити головне меню форми, яке і відповідає за основні дії в програмі. Дане меню створене як більшусть стандартних меню ОС Windows, і тому не вимагає від користувача засвоєння нових принципів при роботі з данию програмою. Головна форма, як видно з рис.3 містить наступні елементи інтерфейсу користувача: Головне меню Панель інструментів Панель для відображення графіка Полосу прокрутки Елементи для відображення 15 останніх проведених вимірів Елементи для задання частоти запуску таймера Для запуску програми необхідно натиснути зелену кнопку на Панелі інструментів, або відповідний підпункт меню Запуск. При цьому на графіку починають з'являтися результати вимірів, а також починають змінюватися текстові значення 15 останніх результатів вимірювань. Одночасно з натискання кнопки Запуск інші кнопки Панелі інструментів стають неактивними (крім кнопки Зупинити та Про програму). Відповідно до змін на Панелі інструментів неактичними стають також відповідні підпункти основного меню. Це здійснено для того, щоб користувач не мав змоги пошкодити дані, які знаходяться в динамічному списку. 5.2 Компонент GraphicDiagram та зміна його вигляду В центрі головної форми знаходиться розроблена мною компонента для зображення графіку GraphicDiagram. Дана компонента призначена для автоматизованого відображення даних, які знаходяться в динамічному списку даної компоненти. Графік може мати різний вигляд, в залежності від бажань користувача. Він може зображатися у вигляді звичайного графіка функції та лінійної гістограми. Зображення графіка можна змінити за допомогою задання опцій відображення графіка, які знаходяться в підпункті Опції графіка меню Настройки. В даному меню можна змінити відображення осей координат, сітки графіка, а також відповідні їм кольори. По бажанню користувача, графік може зображатися без осей координат та сітки графіка, або мати різні поєднання даних опції. Вигляд даного вікна можна побачити на рис.4. Рис.4. Вікно для задання опцій відображення графіка Для вибору кольору зображення осей або сітки в програмі було використано компонент ColorBox. Зміни у відображенні графіка здійснюються одразу ж після натиснення кнопки Ок. 5.3 Збереження даних та їх формат Для збереження даних служать кнопки Зберегти дані та Зберегти графік. Існують також відповідні підпункти в меню Файл. При натисненні на дані кнопки відкриваються відповідно діалоги для збереження та читання даних з файлів. В даних діалогах користувач може вибирати каталоги, куди необхідно записати дані, а також створювати нові, якщо це необхідно. Дані діалоги надають зручний інтерфейс для користувача. Рис 5. Вікно для збереження даних Зберігати графіки можна в графічних форматах файлу. В програмі реалізовані наступні формати графічних файлів: Bitmaps (*.bmp) JPEG Image File (*.jpg) JPEG Image File (*.jpeg) Icons (*.ico) All (*.jpg;*.jpeg;*.bmp;*.ico;*.emf;*.wmf) Збереження текстових даних проводиться в текстових файлах з розширенням *.grf. Формат збереження даного файлу наступний: Час створення виміру Знак „|” Числове значення виміру Полоса прокрутки, що зназодиться на основній формі призначена для прокрутки зображення графіка. На початку роботи програми вона є неактивною. Неактивною вона є до тих пір, поки кількість вимірів не перейде за максимальну кількість вимірів, що можуть зображатися на графіку. Ще однією важливою умовою активізації полоси прокрутки являється зупинка отримання вимірів. Для збереження певної частини графіка, необхідно за допомогою полоси прокрутки вибрати фрагмент графіка, який необхідно записати у файл, та виконати дію запису графіку. 5.4 Додаткові елементи інтерфейсу До додаткових елементів інтерфейсу відносяться елементи для текстового представлення відображуваної інформації, та елементи встановлення часу спрацювання таймера. В нижній частині головної форми присутне текстове представлення 15 останніх результатів вимірювань. Дане текстове представлення змінюється зі зміною останніх даних, і не змінюється при прокрутці графічного зображення. Також в нижній частині реалізовані елементи для швидкої зміни частоти запуску таймера. По замовчуванню таймер спрацювує кожні 200 млс, що призводить до зчитування даних з джерела, та занесення значення в динамічний список. Дані елементи інтерфейсу користувача програми можна побачити на рис.3. ВИСНОВОК Програма „Візуальний облік вхідних даних інтерфейсу RS-232” призначена для ведення обліку даних, що поступають на вхід стандартного інтерфейсу RS-232(COM-порт), а також для графічного відображення вхідних даних у вигляді графіку та збереження отриманих даних у файлах відповідних форматів. Програма дозволяє відображувати дані, що приходять на СОМ-порти, у вигляді, який необхідний користувачу. Для відображення графіку використовуються низка опцій, за допомогою яких користувач може отримати зображення графіка таким, який йому необхідний. Програмний продукт розрахований на користувачів, яким необхідно досліджувати особливості роботи пристроїв, які підключаються до стандартних інтерфейсів ЕОМ. Програма створена для Win32 операційних систем і має зручний та лекий в засвоєнні графічний інтерфейс, оскільки дуже нагадує стандартні інтерфейси Windows. Розроблені діалоги, підказки та інструкція дозволяють користувачам, у яких малий досвід роботи з комп'ютером та подібним програмним забезпеченням, в короткі сроки освоїти програму. Програма реалізована за допомогою сучасних інструментальних засобів візуальної об'єктно-орієнтованої мови програмування Delphi 6.0 та задовільняє всі пункти передбачені в технічному завданні. ЛІТЕРАТУРА 1. Ай Пен, Разработка периферийных устройств. 2. Титов Олег, Работа с коммуникационными портами (COM и LPT) в программах для Win32. 3. Как программировать на Delphi 4.0: Пер. с англ./ Франк Энго. - К.: Издательство “ДиалСофт”, 1999. - 430с. 4. Надежность и эффективность в технике: Справочник: в 10 т.-М.:Машиностроение: Том 5. Проетный анализ надежности. - 1988 г., 316 с. 5. Основы эксплуатации ЭВМ: Учеб. Пособие для вузов/Под ред. Б.М. Кагана. - 2-е изд., перераб и доп.-М.: Эенергоатомиздат, 1988. -432 с.: ил. 6. Секреты 32-разрядного программирования в Delphi: Пер. с англ./ Сван Том. - К.: Диалектика, 1997. - 480с., ил. 7. Секреты Delphi 2: Пер. с англ./Рэй Лишнер. - К.: НИПФ «ДиаСофтЛтд.», 1996. - 800 с. ДОДАТОК ТЕКСТ ПРОГРАМИ “ВІЗУАЛЬНИЙ ОБЛІК ВХІДНИХ ДАНИХ ІНТЕРФЕЙСУ RS-232” Текст основної програми program Project1; uses Forms, MainForm in 'MainForm.pas' {Form1 Головна форма}, GraphicDiagram in 'GraphicDiagram.pas', Unit3 in 'Unit3.pas' {Form3}, aboutProgram in 'aboutProgram.pas' {AboutBox}, Unit4 in 'Unit4.pas' {Form4}; {$R *.res} begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.CreateForm(TAboutBox, AboutBox); Application.CreateForm(TForm3, Form3); Application.CreateForm(TForm4, Form4); Application.Run; end. Текст форми MainForm unit MainForm; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Menus, ExtCtrls, Buttons, StdCtrls, GraphicDiagram, ExtDlgs, ComCtrls, ToolWin, ActnList, ImgList; type TForm1 = class(TForm) MainMenu1: TMainMenu; Fileitem: TMenuItem; ItemNew: TMenuItem; N2: TMenuItem; SavePicture: TMenuItem; SaveData: TMenuItem; N5: TMenuItem; ItemExit: TMenuItem; Run: TMenuItem; StartLoad: TMenuItem; Pause: TMenuItem; Face: TMenuItem; Pilar: TMenuItem; Lines: TMenuItem; Options: TMenuItem; COMport: TMenuItem; LPTport: TMenuItem; Generator: TMenuItem; N19: TMenuItem; PortOption: TMenuItem; GeneratorOption: TMenuItem; Help: TMenuItem; About: TMenuItem; UserGuide: TMenuItem; Panel1: TPanel; PanelInstrument: TPanel; SpeedButton1: TSpeedButton; SpeedButton3: TSpeedButton; SpeedButton2: TSpeedButton; SpeedButton4: TSpeedButton; SpeedButton5: TSpeedButton; SpeedButton6: TSpeedButton; Timer1: TTimer; GraphicDiagram1: TGraphicDiagram; ScrollBar1: TScrollBar; SavePictureDialog1: TSavePictureDialog; SaveDialog1: TSaveDialog; ActionList1: TActionList; ImageList1: TImageList; newGraphic: TAction; saveDataGr: TAction; LoadDataGR: TAction; SaveGraph: TAction; StartGr: TAction; StopGr: TAction; HelpPr: TAction; ExitPr: TAction; N7: TMenuItem; SpeedButton7: TSpeedButton; N8: TMenuItem; OpenDialog1: TOpenDialog; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; Edit7: TEdit; Edit8: TEdit; Edit9: TEdit; Edit10: TEdit; Edit11: TEdit; Edit12: TEdit; Edit13: TEdit; Edit14: TEdit; Edit15: TEdit; Label1: TLabel; Edit16: TEdit; BitBtn1: TBitBtn; procedure ItemExitClick(Sender: TObject); procedure Panel1Resize(Sender: TObject); procedure FormResize(Sender: TObject); procedure PanelInstrumentResize(Sender: TObject); procedure ItemNewClick(Sender: TObject); // procedure SavePictureClick(Sender: TObject); // procedure SaveDataClick(Sender: TObject); procedure PauseClick(Sender: TObject); procedure ClearClick(Sender: TObject); procedure LinesClick(Sender: TObject); procedure Start(Sender: TObject); procedure FormCreate(Sender: TObject); procedure SavePictureClick(Sender: TObject); procedure GeneratorClick(Sender: TObject); procedure LPTportClick(Sender: TObject); procedure COMportClick(Sender: TObject); procedure ScrollBar1Scroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); procedure N2Click(Sender: TObject); procedure N3Click(Sender: TObject); procedure N4Click(Sender: TObject); procedure N6Click(Sender: TObject); procedure AboutClick(Sender: TObject); procedure newGraphicExecute(Sender: TObject); procedure ExitPrExecute(Sender: TObject); procedure StartGrExecute(Sender: TObject); procedure StopGrExecute(Sender: TObject); procedure SaveGraphExecute(Sender: TObject); procedure saveDataGrExecute(Sender: TObject); procedure HelpPrExecute(Sender: TObject); procedure LoadDataGRExecute(Sender: TObject); procedure ChangeTable(k:integer); procedure BitBtn1Click(Sender: TObject); procedure GeneratorOptionClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation uses Unit3, aboutProgram, Unit4; {$R *.dfm} procedure TForm1.ItemExitClick(Sender: TObject); begin close; end; procedure TForm1.ChangeTable(k:integer); var t:integer; begin t:=GraphicDiagram1.GetPointsCount; if t<>0 then begin if t>15 then begin Edit1.Text:=Edit2.Text; Edit2.Text:=Edit3.Text; Edit3.Text:=Edit4.Text; Edit4.Text:=Edit5.Text; Edit5.Text:=Edit6.Text; Edit6.Text:=Edit7.Text; Edit7.Text:=Edit8.Text; Edit8.Text:=Edit9.Text; Edit9.Text:=Edit10.Text; Edit10.Text:=Edit11.Text; Edit11.Text:=Edit12.Text; Edit12.Text:=Edit13.Text; Edit13.Text:=Edit14.Text; Edit14.Text:=Edit15.Text; Edit15.Text:=IntToStr(k); end else begin case t of 1: Edit1.Text:=IntToStr(GraphicDiagram1.GetValue(0)); 2: Edit2.Text:=IntToStr(k); 3: Edit3.Text:=IntToStr(k); 4: Edit4.Text:=IntToStr(k); 5: Edit5.Text:=IntToStr(k); 6: Edit6.Text:=IntToStr(k); 7: Edit7.Text:=IntToStr(k); 8: Edit8.Text:=IntToStr(k); 9: Edit9.Text:=IntToStr(k); 10: Edit10.Text:=IntToStr(k); 11: Edit11.Text:=IntToStr(k); 12: Edit12.Text:=IntToStr(k); 13: Edit13.Text:=IntToStr(k); 14: Edit14.Text:=IntToStr(k); 15: Edit15.Text:=IntToStr(k); end; end; end; end; procedure TForm1.Panel1Resize(Sender: TObject); begin // panel1.Width:=form1.Width-10; // panel1.Height:=form1.Height-200; end; procedure TForm1.FormResize(Sender: TObject); begin GraphicDiagram1.Resize(TControl(panel1)); // panel1Resize(self); PanelInstrumentResize(self); end; procedure TForm1.PanelInstrumentResize(Sender: TObject); begin PanelInstrument.Width:=form1.Width-10; end; procedure TForm1.ItemNewClick(Sender: TObject); var n:integer; begin GraphicDiagram1.Clear; ScrollBar1.Enabled:=false; end; procedure TForm1.PauseClick(Sender: TObject); begin if GraphicDiagram1.GetPointsCount<>1 then begin if SpeedButton4.Caption='Запуск' then begin Fileitem.Enabled:=false; // Interpolation.Enabled:=false; Options.Enabled:=false; SpeedButton1.Enabled:=false; SpeedButton2.Enabled:=false; SpeedButton3.Enabled:=false; SpeedButton4.Caption:='Зупинити'; StartLoad.Caption:='Зупинити'; Timer1.Interval:=GraphicDiagram1.NumMiliSec; Timer1.Enabled:=True; Pause.Enabled:=true; SpeedButton5.Enabled:=true; end else begin if GraphicDiagram1.GetPointsCount>GraphicDiagram1.DrawCount then begin ScrollBar1.Enabled:=true; ScrollBar1.SetParams(GraphicDiagram1.GetPointsCount,0,GraphicDiagram1.GetPointsCount); end; Fileitem.Enabled:=true; // Interpolation.Enabled:=true; Options.Enabled:=true; SpeedButton1.Enabled:=true; SpeedButton2.Enabled:=true; SpeedButton3.Enabled:=true; SpeedButton4.Caption:='Запуск'; StartLoad.Caption:='Запуск'; Timer1.Enabled:=false; Pause.Enabled:=false; SpeedButton5.Enabled:=false; //Stop; end; end else begin ScrollBar1.Enabled:=false; Pause.Enabled:=false; SpeedButton5.Enabled:=false; end; end; procedure TForm1.ClearClick(Sender: TObject); begin form1.ItemNewClick(self); end; procedure TForm1.Start; var n:TPoint; begin new(n); n^:=Random(255); GraphicDiagram1.AddValue(n); ChangeTable(n^); end; procedure TForm1.LinesClick(Sender: TObject); begin if not(Lines.Checked)then begin GraphicDiagram1.TypeDiagram:=tdLine; Lines.Checked:=true; Pilar.Checked:=false; end else begin GraphicDiagram1.TypeDiagram:=tdColumn; Lines.Checked:=false; Pilar.Checked:=true; end; end; procedure TForm1.FormCreate(Sender: TObject); begin inherited; randomize; Form1.Pause.Enabled:=false; Form1.SpeedButton5.Enabled:=false; ScrollBar1.Enabled:=false; Edit1.Text:='0'; // SaveDialog1.Create(self); end; procedure TForm1.SavePictureClick(Sender: TObject); var k:integer; t:String; begin if SavePictureDialog1.Execute then begin t:=SavePictureDialog1.FileName; repaint; k:=GraphicDiagram1.SavePicture(t); if k=0 then MessageDlg('Помилка при записі файла '+t,mtError,[mbOk],0); end; end; procedure TForm1.GeneratorClick(Sender: TObject); begin if not(Generator.Checked) then begin Generator.Checked:=true; COMport.Checked:=false; LPTport.Checked:=false; end; end; procedure TForm1.LPTportClick(Sender: TObject); begin if not(LPTport.Checked)then begin Generator.Checked:=false; COMport.Checked:=false; LPTport.Checked:=true; end; end; procedure TForm1.COMportClick(Sender: TObject); begin if not(COMport.Checked)then begin Generator.Checked:=false; COMport.Checked:=true; LPTport.Checked:=false; end; end; procedure TForm1.ScrollBar1Scroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); begin if ScrollCode=scEndScroll then begin if (ScrollPos<>0) and (ScrollPos<>GraphicDiagram1.GetPointsCount) then begin GraphicDiagram1.DrawStart:=ScrollPos-1; GraphicDiagram1.Invalidate; end else if ScrollPos=0 then begin GraphicDiagram1.DrawStart:=0; GraphicDiagram1.Invalidate; end else begin GraphicDiagram1.DrawStart:=ScrollPos-1; GraphicDiagram1.Invalidate; end; end; end; procedure TForm1.N2Click(Sender: TObject); begin Form3.Showmodal; end; procedure TForm1.N3Click(Sender: TObject); begin //form2.Show; end; procedure TForm1.N4Click(Sender: TObject); begin form3.Show; end; procedure TForm1.N6Click(Sender: TObject); begin // form4.show; end; procedure TForm1.AboutClick(Sender: TObject); begin aboutbox.showmodal; end; procedure TForm1.newGraphicExecute(Sender: TObject); begin form1.ItemNewClick(self); end; procedure TForm1.ExitPrExecute(Sender: TObject); begin close; end; procedure TForm1.StartGrExecute(Sender: TObject); begin ScrollBar1.Enabled:=false; Fileitem.Enabled:=false; // Interpolation.Enabled:=false; Options.Enabled:=false; SpeedButton1.Enabled:=false; SpeedButton2.Enabled:=false; SpeedButton3.Enabled:=false; Timer1.Interval:=GraphicDiagram1.NumMiliSec; Timer1.Enabled:=True; Pause.Enabled:=true; SpeedButton5.Enabled:=true; end; procedure TForm1.StopGrExecute(Sender: TObject); begin if GraphicDiagram1.GetPointsCount>GraphicDiagram1.DrawCount then begin ScrollBar1.Enabled:=true; ScrollBar1.SetParams(GraphicDiagram1.GetPointsCount,0,GraphicDiagram1.GetPointsCount); end; Fileitem.Enabled:=true; // Interpolation.Enabled:=true; Options.Enabled:=true; SpeedButton1.Enabled:=true; SpeedButton2.Enabled:=true; SpeedButton3.Enabled:=true; Timer1.Enabled:=false; Pause.Enabled:=false; end; procedure TForm1.SaveGraphExecute(Sender: TObject); begin SavePictureClick(Sender); end; procedure TForm1.saveDataGrExecute(Sender: TObject); begin if SaveDialog1.Execute then GraphicDiagram1.SaveData(SaveDialog1.FileName); end; procedure TForm1.HelpPrExecute(Sender: TObject); begin aboutBox.ShowModal; end; procedure TForm1.LoadDataGRExecute(Sender: TObject); begin if openDialog1.Execute then begin if fileExists (openDialog1.FileName) then GraphicDiagram1.LoadData(openDialog1.FileName) else messageDlg('Немає такого файлу!!',mtError,[mbOk],0); end; end; procedure TForm1.BitBtn1Click(Sender: TObject); begin try GraphicDiagram1.NumMiliSec:=StrToInt(Edit16.Text); except MessageDlg('Число повинне бути цілим та додатнім!!!',mtError,[mbOk],0); end end; procedure TForm1.GeneratorOptionClick(Sender: TObject); begin Form4.showmodal; end; end. Текст компонента GraphicDiagram unit GraphicDiagram; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; const WM_MYMessage = WM_USER+1000; const MAX_COUNT = 10000; type TTypeDiagram = (tdLine,tdColumn,tdUser); TPoint = ^Longint; TPointArray = TList; TCount = 0..MAX_COUNT; TnewMouseMoveEvent = procedure (Sender:TObject;Shift:TShiftState;x,y:integer; var DoDefault:boolean) of Object; TGraphicDiagram = class(TGraphicControl) private FTypeDiagram:TTypeDiagram; FpointStart:Longint;//початок відображення точок на графіку FPointDrawCount:Longint; //Кінець відображення точок на графіку FNumSeccond,FNumMSeccond:word; // кількість мілісекунд, після яких добавляється точка FPointYMax:Longint; //максимальна точка по Ігрик FDrawX:Boolean; FDrawY:Boolean; FDRAWColor:TColor; FDrawGridX:Boolean; FDrawGridY:Boolean; FDrawGridColor:TColor; FPointsValue:TPointArray; // тільки додатні елементи FDataStart,FDataStop:TDateTime;//початок відображення точок на графіку FEnabled:Boolean; FOnMouseMove:TnewMouseMoveEvent; OurTime:longint; MashtabX:real; MashtabY:real; FMashTab:Boolean; //маштаб якщо він змінився то true // function GetValue(index:Longint): Longint; //читає точку Procedure SetValue(index,value:Longint); //добавляє точку procedure SetTypeDiagram(typeD:TTypeDiagram); procedure SetMashtabX; procedure SetMashtabY; protected procedure paint;override; procedure WritePoints(stream:TStream);virtual; procedure ReadPoints(stream:TStream);virtual; procedure DefineProperties(Filer:TFiler);override; procedure WMMouseMove(var Mes:TWMMouse); message WM_MOUSEMOVE; procedure MyMouseMove(Shift:TShiftState;x,y:integer);dynamic; Procedure WMMyMessage(var Mes:TMessage); message WM_MyMessage; public { Public declarations } constructor create(AOwner:TComponent);override; destructor Destroy; override; procedure AddValue(value:TPoint);overload; function GetPointsCount:Longint; //читає точку function getList:TPointArray; function SaveData(filename:String):integer; function LoadData(filename:String):integer; function SavePicture(filename:String):integer; procedure Start; procedure Stop; procedure Clear; procedure Resize(Sender:TControl); function GetValue(index:Longint): Longint; //читає точку // procedure AddValue(value:longint);overload; published { Published declarations } property TypeDiagram:TTypeDiagram read FTypeDiagram write FTypeDiagram; property DrawCount:integer read FPointDrawCount Write FPointDrawCount; property DrawX:Boolean read FDrawX Write FDrawX; property DrawY:Boolean read FDrawY Write FDrawY; property DrawGridX:Boolean read FDrawGridX Write FDrawGridX; property DrawGridY:Boolean read FDrawGridY Write FDrawGridY; property DrawColor:TColor read FDrawColor Write FDrawColor; property DrawGridColor:TColor read FDrawGridColor Write FDrawGridColor; property DrawStart:integer read FPointStart Write FPointStart; property NumSeccondShow:word read FNumSeccond write FNumSeccond stored false; property NumMiliSec:word read FNumMSeccond write FNumMSeccond stored false; property OnMouseMove:TnewMouseMoveEvent read FOnMouseMove write FOnMouseMove; end; procedure Register; implementation procedure TGraphicDiagram.Resize; begin Height:=Sender.Height-30; Width:=Sender.Width-15; invalidate; end; function TGraphicDiagram.getList:TPointArray; begin result:=FPointsValue; end; procedure TGraphicDiagram.Start; begin FDataStart:=now; end; procedure TGraphicDiagram.Stop; begin FDataStop:=now; end; destructor TGraphicDiagram.destroy; begin Self.clear; inherited; end; procedure TGraphicDiagram.Clear; var l:^Longint; i:TPoint; n:Longint; begin n:=FPointsValue.Count-1; FPointsValue.clear; FpointStart:=0; new (i); i^:=0; AddValue(i); invalidate; end; function TGraphicDiagram.LoadData; var i:Longint; n:^Longint; f:textFile; st:String; begin result:=-1; FpointsValue.Clear; FpointStart:=0; if not FileExists(filename) then exit; assignFile(f,filename); reset(f); while not eof(f) do begin readln(f,st); i:=pos('|',st); if i=0 then Exception.create('Неправильний формат файлу '+filename); FDataStart:=StrToDateTime(copy(st,1,i-1)); new (n); n^:= StrToInt(copy(st,i+1,10)); FpointsValue.add(n); end; closeFile(f); invalidate; result:=0; end; function TGraphicDiagram.SavePicture; var tp:TBitMap; st:TStream; p:pointer; rin:TRect; begin rin:=Rect(0,0,width,height); //TCanvas tp:= TBitmap.Create; // p:=addr(self.canvas.pixels[0,0]) tp.width:=width; tp.height:=height; tp.canvas.CopyRect (rin, self.canvas,rin); tp.SaveToFile (filename); tp.free; end; function TGraphicDiagram.SaveData; var i:Longint; n:^Longint; f:textFile; begin result:=-1; assignFile(f,filename); rewrite(f); for i:=0 to FPointsValue.count-1 do begin n:=FpointsValue.items[i]; writeln(f,DateTimeToStr(FDataStart+(FDataStart-FDataStop)/FPointsValue.count),'|',n^); end; closeFile(f); result:=0; end; function TGraphicDiagram.GetPointsCount:Longint; // begin result:=FPointsValue.Count; end; procedure TGraphicDiagram.SetTypeDiagram(typeD:TTypeDiagram); begin FTypeDiagram:=typeD; invalidate; end; procedure TGraphicDiagram.WMMouseMove(var Mes:TWMMouse); begin inherited; if not (csNoStdEvents in ControlStyle) then with mes do MyMouseMove (KeysToShiftState(Keys),Xpos,YPos); end; procedure TGraphicDiagram.MyMouseMove(Shift:TShiftState;x,y:integer); var def:Boolean; begin def:=true; if Assigned(FOnMouseMove) then FOnMouseMove(Self,shift,x,y,def); {if def then оброблювач по замовчуванню!!!} end; procedure TGraphicDiagram.WMMyMessage(var Mes:TMessage); begin Canvas.Pen.Color:= clRed; inValidate; end; procedure TGraphicDiagram.DefineProperties(Filer:TFiler); begin inherited DefineProperties(Filer); // Filer.DefineBinaryProperty('TypeDiagram',ReadType,WritePoints,true); end; procedure TGraphicDiagram.WritePoints(stream:TStream); begin // stream.WriteBuffer(FPointsValue,SizeOf(FPointsVAlue)); end; procedure TGraphicDiagram.ReadPoints(stream:TStream); begin // stream.ReadBuffer(FPointsValue,SizeOf(FPointsVAlue)); end; constructor TGraphicDiagram.create; var i:integer; n:TPoint; begin inherited create (AOwner); FDrawColor:=clBlack; FDrawGridColor:=clBlack; FDrawX:=true; FDrawY:=true; FDrawGridX:=true; FDrawGridY:=true; FPointYMax:=1; Height:=100; Width:=200; FNumSeccond:=20; FNumMSeccond:=200; FPointDrawCount:=(FNumSeccond*1000) div FNumMSeccond; MashtabX:=Width/FPointDrawCount; MashtabY:=(Height-30); FTypeDiagram:= tdColumn; FPointsValue:=TList.Create; new (n); n^:=0; addValue(n); FEnabled:=true; FMashTab:=true; //маштаб по Ігрику end; function TGraphicDiagram.getValue; begin if index<FPointsValue.count then Result:=Longint(FPointsValue.items[index]) else result:=0; end; procedure TGraphicDiagram.setValue; var l:^Longint; begin if index<FPointsValue.count then begin l:=FPointsValue.Items[index]; if l<>nil then dispose(l); FPointsValue.Items[index]:=@value; if value>FPointYMax then begin FPointYMax:=Value; FMashtab:=true; end; invalidate; end; end; procedure TGraphicDiagram.AddValue(value:TPoint); var knum:Longint; begin FPointsValue.Add(value); knum:=FPointsValue.Count; if ((knum-FPointStart)+3>FPointDrawCount) then FPointStart:=knum-FPointDrawCount+3; if value^>FPointYMax then begin FPointYMax:=Value^; FMashtab:=true; end; invalidate; end; //Встановлення маштабу по Y procedure TGraphicDiagram.SetMashtabY; begin try MashtabY:=(Height-30)/FPointYMax; except MashtabY:=(Height-30)/10 end; end; //Встановлення маштабу по X procedure TGraphicDiagram.SetMashtabX; begin MashtabX:=(width-10)/FPointDrawCount; end; procedure TGraphicDiagram.paint; var i:longint; //Отримання координати Х точки у відповідності до маштабу по Х function GetX(p:longint):integer; begin result:=10 + Round(p*MashtabX); end; //Отримання координати Y точки у відповідності до маштабу по Y function GetY(p:longint):integer; begin result:=Height -10 - Round(p*MashtabY); end; procedure drawKoordinate; var i:integer; temp:TColor; begin with canvas do begin //Відобрахкння координатних осей pen.Width:=2; temp:=pen.Color; pen.Color:=FDrawColor; //Вісь Х if FDrawX then begin moveTo(10,height-10); lineTo(width-5,height-10); moveTo(width-5,height-10); lineTo(width-15,height-15); moveTo(width-5,height-10); lineTo(width-15,height-5); //Поділки на вісі Х for i:=0 to 9 do begin moveTo(10+(width) div 10 *i,height-5); lineTo(10+(width) div 10 *i,height-15); end; end; //Вісь Y if FDrawY then begin moveTo(10,height-10); lineTo(10,5); moveTo(10,5); lineTo(5,15); moveTo(10,5); lineTo(15,15); //Поділки на вісі Y for i:=0 to 9 do begin moveTo(5,height-10- height div 10*i); lineTo(15,height-10- height div 10*i); end; end; moveTo(10,height-10); pen.Width:=1; pen.Style:=psDot; pen.Color:=FDrawGridColor; //Відображення координатної сітки if FDrawGridX then begin //Сітка по вісі Х for i:=0 to 9 do begin moveTo(10+(width) div 10 *i,height-5); lineTo(10+(width) div 10 *i,0); end; end; if FDrawGridY then begin //Сітка по вісі Y for i:=0 to 9 do begin moveTo(5,height-10- height div 10*i); lineTo(width,height-10- height div 10*i); end; end; moveTo(10,height-10); pen.style:=psSolid; pen.Color:=temp; end; end; var l:longint; p:^Longint; rx:longint; ry:longint; begin if FMashtab then begin SetMashtabX; SetMashtabY; end; if csDesigning in ComponentState then inherited Canvas.pen.Style:= psDash else inherited Canvas.pen.Style:= psSolid; l:=FPointsValue.Count-1; with inherited Canvas do begin Brush.Style:=bsClear; // Rectangle(0,0,Width,Height); p:=FPointsValue.items[FPointStart]; moveTo(0,GetY(p^)); pen.Style:= psSolid; pen.color:=clBlack; DrawKoordinate; if FTypeDiagram=tdLine then for i:=FPointStart to l do begin p:=FPointsValue.items[i]; rx:=GetX(i-FPointStart); ry:=GetY(p^); LineTo(rx,ry) end else if FTypeDiagram=tdColumn then begin Brush.Style:= bsSolid; Brush.Color:= clBlue; for i:=FPointStart to l do begin p:=FPointsValue.items[i]; rx:=GetX(i-FPointStart); ry:=GetY(p^); FillRect(Rect(rx,Height-10,rx+1,ry)); end; end; end; end; procedure Register; begin RegisterComponents('ActiveX', [TGraphicDiagram]); end; end. Текст модуля Unit3 unit Unit3; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, ComCtrls, StdCtrls, Buttons, ExtCtrls; type TForm3 = class(TForm) PageControl1: TPageControl; TabSheet1: TTabSheet; TabSheet2: TTabSheet; BitBtn1: TBitBtn; BitBtn2: TBitBtn; GroupBox1: TGroupBox; RBX: TRadioButton; RBY: TRadioButton; RbXY: TRadioButton; RBNone: TRadioButton; GroupBox2: TGroupBox; RBGX: TRadioButton; RBGY: TRadioButton; RBGXY: TRadioButton; RBGNone: TRadioButton; ColorBox1: TColorBox; ColorBox2: TColorBox; procedure FormShow(Sender: TObject); procedure BitBtn1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form3: TForm3; implementation uses MainForm; {$R *.dfm} procedure TForm3.FormShow(Sender: TObject); begin with Form1 do if GraphicDiagram1.DrawX and GraphicDiagram1.DrawY then RBXY.Checked:=true else if GraphicDiagram1.DrawX then RBX.Checked:=true else if GraphicDiagram1.DrawY then RBY.Checked:=true else RBNONe.Checked:=true; end; procedure TForm3.BitBtn1Click(Sender: TObject); begin with Form1 do begin //Перевірка для осей координат if RBXY.Checked then begin GraphicDiagram1.DrawX:=true; GraphicDiagram1.DrawY:=true;end; if RBY.Checked then begin GraphicDiagram1.DrawX:=false; GraphicDiagram1.DrawY:=true;end; if RBX.Checked then begin GraphicDiagram1.DrawX:=true; GraphicDiagram1.DrawY:=false;end; if RBNone.Checked then begin GraphicDiagram1.DrawX:=false; GraphicDiagram1.DrawY:=false;end; //Перевірка для сітки if RBGXY.Checked then begin GraphicDiagram1.DrawGridX:=true; GraphicDiagram1.DrawGridY:=true;end; if RBGY.Checked then begin GraphicDiagram1.DrawGridX:=false; GraphicDiagram1.DrawGridY:=true;end; if RBGX.Checked then begin GraphicDiagram1.DrawGridX:=true; GraphicDiagram1.DrawGridY:=false;end; if RBGNone.Checked then begin GraphicDiagram1.DrawGridX:=false; GraphicDiagram1.DrawGridY:=false;end; GraphicDiagram1.DrawColor:=ColorBox2.Selected; GraphicDiagram1.DrawGridColor:=ColorBox1.Selected; GraphicDiagram1.Invalidate; end; end; end.
Страницы: 1, 2
|