Візуальний облік вхідних даних інтерфейсу RS-232
Вікна інструментів, що закріплюються
IDE (Інтегроване Середовище Розробки) містить більш гнучку конфігурацію вікон інструментів, які можна закріплювати з редактором коду. Просто перетягніть і відпустіть вікно інструменту до того місця, до якого хочете. Провідник коду і менеджер проекту можна як закріплювати, так і не закріплювати.
Поліпшене налагодження
Інтегрований відладчик має багато нових властивостей, включаючи віддалені і багатопроцесорне налагодження, перегляд коду центрального процесора, інспекторів, удосконалені точки переривання, відладчик специфічних підміню і закріплених вікон.
Удосконалення 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
|