Элементы технологии программирования
в примерах и упражнениях
Уче6ное пособие
2010г.
СОДЕРЖАНИЕ
Введение
1. Элементы объектно-ориентированного программирования
1.1. Определение класса и пользование его экземплярами
1.2. Наследование
1.3. Полиморфизм
1.4. Свойства и события (методы объекта, делегаты)
1.5. Класс классов
2. Организация типовых оконных приложений
2.1. Оконные приложения в IDE Delphi c библиотекой VCL
2.2. Приложение Windows Forms в Microsoft Visual Studio 2008 для среды CLR на языке C#
2.3. Приложение Windows Forms в Microsoft Visual Studio 2008 для среды CLR на языке C++
2.4. Приложение Windows Forms в Microsoft Visual Studio 2008 для среды Win32
3. Списки и таблицы
3.1. Прото-СУБД на основе класса TStringList и TStringGrid (библиотека VCL Delphi)
4. Разработка и верификация расчётных приложений
4.1. Спецификация программы uWert
4.2. Текст программы uWert
4.3. Доказательство корректности программы uWert
5. Организация многооконного интерфейса и диалога в приложениях
5.1. Многооконный интерфейс на основе сохраняемых форм
5.2. Диалог на основе динамически создаваемых форм
5.2.1. Проект диалоговой функции в Delphi
5.2.2. Проект диалоговой функции в Microsoft Visual Studio 2008 (CLR, язык C#)
5.2.3. Проект диалоговой функции в Microsoft Visual Studio 2008 (CLR, язык C++)
6. Проектирование классов
6.1. Основы модельно-ориентированного проектирования
6.2. Проект разработки компьютерной поддержки библиотеки
Приложения.
1. Синтаксис и семантика класса в языках Object Pascal, C#, C++, Java
2. Основы языка UML
Введение
Данное учебное пособие сложилось в ходе преподавания технологий программирования студентам 2-го курса, то есть студентам, заведомо не имеющим заметного опыта и широкого кругозора в области программирования. Поэтому пособие преследует до известной степени разнородные цели: ознакомить со сквозным процессом разработки программ в духе современного Software Engineering, ввести в использование современных интегральных сред программирования и просто поучить разработке программ, уровень сложности алгоритмизации в которых превышает уровень обычных, преимущественно тривиальных примеров.
Первый раздел содержит примеры простейших приёмов объектно-ориентированного программирования, которые нужны для дальнейшего, но, как показывает опыт преподавания, усваиваются бывшими школьниками далеко не сразу.
Второй раздел «Организация типовых оконных приложений» позволяет с полным пониманием приступить к использованию интегральных сред программирования Borland Delphi и Microsoft Visual Studio и служит иллюстрацией масштабного применения объектно-ориентированного стиля программирования.
Третий раздел «Списки и таблицы» по замыслу должен помочь освоить важнейшие типы данных. В данной редакции пособия в этом разделе приведён пример использования класса TStrings. Этот пример позволяет подвести студентов к проблемам реализации реляционной модели данных в СУБД. Материал на ту же тему содержится и в пункте 6.2.4 раздела 6.
Четвёртый раздел «Разработка и верификация расчётных приложений» содержит программу вычисления значения регулярного арифметического выражения и верификацию её путём формального доказательства.
Пятый раздел «Организация многооконного интерфейса и диалога в приложениях» по содержанию и целям является развитием второго раздела.
Шестой раздел демонстрирует проектирование АСУ библиотеки по методике, в целом соответствующей методике Rational Unified Process (RUP). Для документирования проекта используется язык UML, разрабатываемый силами Object Management Group (OMG). Полный исходный текст проектируемой программы вряд ли когда-нибудь войдёт в пособие из-за своего объёма. Приведён лишь его фрагмент, иллюстрирующий одно из ключевых проектных решений.
Во всех разделах сформулированы упражнения, позволяющие практиковаться в проектировании, разработке и исследовании программ, отталкиваясь от приведённых примеров, то есть – на достаточно объёмном и сложном материале.
Школьные и вузовские образовательные программы по информатике в настоящее время устроены в своём большинстве так, что студенты вначале знакомятся с языком Pascal в версии Turbo, а затем – в объектной (Object) версии. Поэтому вполне актуально проводить обучение современным представителям семейства C-подобных языков, соотнося учебный материал по этим языкам со знаниями языка Pascal, которые, с большой вероятностью, имеются у учащихся. Соответственно, пособие содержит тексты на языках Object Pascal (Delphi), C++ и С# и побуждает упражняться в понимании, переработке и доработке этих текстов.
Характер изложения материала в каждом из разделов умышленно усложняется от начала к концу. Начальные части разделов легко доступны всем читателям, в том числе тем, кто знакомится с темой. Уровень изложения в конце разделов позволит быстро освоить их продвинутым читателям и составит полезную нагрузку для остальных.
1. ЭЛЕМЕНТЫ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ
1.1. Определение класса и пользование его экземплярами
Пример консольного приложения IDE Delphi, в котором определён класс A как наследник класса TComponent:
program ClassTest01;
{$APPTYPE CONSOLE}
uses SysUtils, classes;
type A = class(TComponent)
public
f: extended;
procedure S;
constructor create(AOwner:TComponent);
end;
procedure A. S;
var x: integer;
function Fact(n: extended):extended;
begin
if n=1 then result:=1
else result:=n*Fact(n-1)
end;
begin
write('Proc S from class A calculates factorial of ');
read(x);
// f:=x;
// write('is '+FloatToStr(Fact(f));
write('is '+FloatToStr(Fact(x));
read(x)
end;
constructor A. create(AOwner:TComponent);
begin
inherited create(AOwner)
end;
var x: A;
begin
x:=A. create(nil);дол
x. S;
end.
Процедура S запрашивает число у оператора, вычисляет и выводит его факториал, как показано на следующем рисунке.

Если в методе используются только методы данного класса, она может быть вызвана от переменной x типа А без порождения экземпляра класса. Однако если использовать, например, поля, как показано в закомментаренных строках примера, тогда экземпляр класса должен быть создан вызовом конструктора класса.
1.2. Наследование
Если в программу ClassTest01, приведённую в п.1.1, ввести определение класса C, наследника класса A,
type C = class(A) constructor create(AOwner:TComponent); end;
то процедуру S можно вызвать от класса С:
var x: С;
begin x. S end.

Однако если в класс C ввести объявление метода с именем S,
type C = class(A)
procedure S;
constructor create(AOwner:TComponent);
end;
а в программу – соответствующее, например, такое определение:
procedure C. S;
var x: integer;
begin
writeln('Proc S from class C');
readln(x)
end;
то процедура C. S “экранирует” процедуру S класса A. При том же обращении к S будет вызвана процедура S из класса A:

1.3. Полиморфизм
Полиморфизм обеспечивается динамическим связыванием переменной с классом присвоенного ей объекта. В следующем примере ClassTest02:
program ClassTest02;
{$APPTYPE CONSOLE}
uses SysUtils, classes;
type A = class(TComponent)
procedure M; virtual;
constructor create(AOwner:TComponent);
end;
type C = class(A)
procedure M; override;
constructor create(AOwner:TComponent);
end;
procedure A. M;
var x: integer;
begin
writeln('Proc M from class A');
readln(x)
end;
constructor A. create(AOwner:TComponent);
begin inherited create(AOwner) end;
procedure C. M;
var x: integer;
begin
writeln('Proc M from class C');
read(x)
end;
constructor C. create(AOwner:TComponent);
begin
inherited create(AOwner)
end;
var x: A;z: C;
begin
x:=A. create(nil);
x. M;
z:=C. create(nil);
z. M;
x:=z;
x. M
end.
от переменной x вызывается метод M класса А, затем от переменной z M класса С, а после присвоения x значения (объекта) переменной z вызывается M класса C.

Полиморфизм процедуры M обеспечивается директивой virtual в классе A и директивой override в классе C.
1.4. Свойства и события (методы объекта, делегаты)
1.5. Класс классов
УПРАЖНЕНИЯ
1. Составить и выполнить аналогичные примеры в среде оконного приложения Borland Delphi.
2. Составить и выполнить аналогичные примеры в среде оконного приложения Microsoft Visual Studio 2008.
2. ОРГАНИЗАЦИЯ ТИПОВЫХ ОКОННЫХ ПРИЛОЖЕНИЙ
2.1. Оконные приложения в IDE Delphi c библиотекой VCL
Пример 1. Создание заготовки проекта.
1) запустите IDE Delphi.
Вы увидите пустую форму

2) нажмите функциональную клавишу F12.
Вы увидите текст модуля:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
end.
Этот модуль содержит объявление класса TForm1 - наследника класса Tform и глобальную переменную Form1 этого класса. Объявление класс TForm можно найти в модуле Forms, который связан с данным модулем в операторе uses.
3) вернитесь к графическому представлению формы, вновь нажав функциональную клавишу F12, наведите на неё курсор мыши и вызовите всплывающее меню нажатием правой клавиши; в этом меню активируйтеView as Text. Вы увидите
object Form1: TForm1
Left = 192
Top = 107
Width = 591
Height = 483
Caption = 'Form1'
Color = clBtnFace
Font. Charset = DEFAULT_CHARSET
Font. Color = clWindowText
Font. Height = -11
Font. Name = 'MS Sans Serif'
Font. Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
end
Этот текст представляет свойства класса TForm1 и их значения, которые автоматически установлены в приложении. При сохранении проекта этот текст образует файл Unit1.dfm, в то время, как Unit1 образует файл Unit1.pas.
4) активируйте в главном меню Project – View Source.
Вы увидите текст корневого сегмента программы
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application. Initialize;
Application. CreateForm(TForm1, Form1);
*****n;
end.
Нетрудно заметить, что выполняются три метода класса TApplication, второй из которых создаёт экземпляр класса TForm1, определённый в модуле Unit1, и присваивает его там же определённой переменной Form1. Метод Run активирует окно, “скрывающееся ” в форме. Начало корневого сегмента служит точкой формы приложения. Поэтому рассмотренные предложения выполняются, если запустить приложение, например, нажатием функциональной клавиши F9. В результате будет создан экземпляр класса TForm1 и он будет показан на экране компьютера как форма.

То есть, заготовка, предоставляемая программисту при запуске IDE является корректным, работоспособным приложением (хотя практически бессодержательным), и пользователь приложения фактически работает с экземпляром определённого в приложении класса.
Пример 2. Добавление в форму кнопки и обработка события от её нажатия.
1) перенесите с помощью мыши кнопку из палитры компонентов на форму:

При этом в модуле Unit1 в определение класса TForm1 будет автоматически включено поле (включённое предложение подчёркнуто):
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
Button1: TButton;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
end.
А в тексте, скрытом за формой (файл Unit1.dfm) появятся предложения, определяющие кнопку как объект и его свойства:
object Form1: TForm1
Left = 192
Top = 107
Width = 287
Height = 211
Caption = 'Form1'
Color = clBtnFace
Font. Charset = DEFAULT_CHARSET
Font. Color = clWindowText
Font. Height = -11
Font. Name = 'MS Sans Serif'
Font. Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 64
Top = 72
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
end
end
2) дважды кликните по кнопке или по пустому полю строки Click в закладке “События” инспектора объектов (когда кнопка в фокусе!).
В результате в Unit1 в определение класса включается заголовок обработчика события
procedure Button1Click(Sender: TObject);
а в раздел implementation включается заготовка тела этого метода:
procedure TForm1.Button1Click(Sender: TObject);
begin
end;
end.
В текст файла Unit1.dfm, в описание кнопки добавляется строка
OnClick = Button1Click
После введения программистом в тело обработчика предложений, задающих требуемую обработку события, приложение может быть запущено. Например, после ввода предложения
ShowMessage(‘Привет!')
запуска приложения и нажатия на кнопку на форму выдаётся соответствующее сообщение:

УПРАЖНЕНИЯ
1. Добавьте в форму главное меню и обработайте события от активации его пунктов.
2.2. Приложение Windows Forms в Microsoft Visual Studio 2008 для среды CLR на языке C#
Пример 1. Создание заготовки проекта.
3) запустите IDE Visual Studio 2008,
4) активируйте в главном меню File – New – Application
При создании нового проекта этого типа Visual Studio 2008 автоматически создает заготовку проекта в виде директории с именем проекта, содержащей:
модуль имя_проекта.csproj
модуль Form1.cs
модуль Form1.Designer. cs
модуль Program. cs
директория bin
директория obj
директория Properties.
В директории Properties содержатся модули: AssemblyInfo. cs, Resources. Designer. cs, Resources. resx, Settings. Designer. cs, Settings. settings.
В главном окне среды проектирования отображаются исходные тексты на языке C# (с расширением cs). Они отображаются либо автоматически при открытии проекта, либо могут быть выведены на экран с помощью главного меню Файл - Открыть – Файл … . Кроме того, в главном окне автоматически или по команде главного меню Вид-Конструктор показывается закладка Form1.cs[Конструктор], на которой представлен прототип главного окна (формы) проектируемого приложения.

Модуль Program. cs, содержит статический класс Program с методом main(). Этот метод является первым, который начинает выполняться при запуске проектируемого приложения.
Метод main() вызывает методы класса Application, определённого в пространстве имён System. Windows. Forms и содержащего, в частности, метод Run, запускающий обработку сообщений к окну. Окно (форма) создаётся тут же оператором new как экземпляр класса Form1, который определён в модулях Form1.cs и Form1.Designer. cs проекта. Форма Form1 становится главной формой приложения.
Далее приведён текст модуля Program. cs для проекта CSprim
using System;
using System. Collections. Generic;
using System. Linq;
using System. Windows. Forms;
namespace CSprim
{
static class Program
{
/// <summary>
/// Главная точка входа для приложения.
/// </summary>
[STAThread]
static void Main()
{
Application. EnableVisualStyles();
Application. SetCompatibleTextRenderingDefault(false);
*****n(new Form1());
}
}}
Определение класса Form1 и содержащие его модули создаются автоматически при создании проекта. Класс разделён на две части, первая из которых, Form1.cs, содержит конструктор этого класса, вызывающий функцию InitializeComponent, которая определена в модуле Form1.Designer. cs.
Далее приведён текст модуля Form1.cs
using System;
using System. Collections. Generic;
using ponentModel;
using System. Data;
using System. Drawing;
using System. Linq;
using System. Text;
using System. Windows. Forms;
namespace CSprim
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}
Модуль Form1.Designer. cs содержит:
определение поля components для коллекции компонентов, сопоставляемых с формой; эта коллекция определяется как пустая; тип поля – интрефейс Icontainer из пространства имён ponentModel, объявляющий метод Dispose – расформирования коллекции и освобождение ресурсов, занятых её элементами;
определение функции Dispose, которая освобождает ресурсы компонентов, входящих в коллекцию поля components, и ресурсы самой формы; .
определение функции InitializeComponent, которая создает экземпляр класса Container (для компонентов) и присваивает его полю components, устанавливает шрифт для формы и её титульную надпись.
Модуль Модуль Form1.Designer. cs:
namespace CSprim
{
partial class Form1
{
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
private ponentModel. IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components!= null))
{
components. Dispose();
}
base. Dispose(disposing);
}
#region Код, автоматически созданный конструктором форм Windows
/// <summary>
/// Обязательный метод для поддержки конструктора - не изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
private void InitializeComponent()
{
ponents = new ponentModel. Container();
this. AutoScaleMode = System. Windows. Forms. AutoScaleMode. Font;
this. Text = "Form1";
}
#endregion
}
}
Все эти построения осуществляются автоматически, заготовка приложения является корректным приложением, которое может быть запущено в режиме отладки в среде проектирования или независмо от среды отладки как модуль имя-проекта.exe в директории Debug – поддиректории bin или obj директории проекта.
При запуске приложения метод main() создает экземпляр класса Form1, вызывая оператором new его конструктор, а тот вызывает функцию InitializeComponent(), которая заполняет форму, присваивает форме и попавшим на неё компонентам заданные параметры и выводит её на экран. Метод Run активизирует очередь сообщений к форме как окну.
Пример 2. Добавление в форму кнопки и обработка события от её нажатия.
При разработке приложения на форму могут устанавливаться компоненты и вписываться обработчики событий, связанных с этитми компонентами. При этом в модуле Form1.cs автоматически формируются заготовки обработчиков событий, а в модуле Form1.Designer. cs – объявления компонентов как полей класса. В текст объявления функции InitalizeComponent(), также автоматически, вводятся предложения, обеспечивающие создания экземпляров компонентов формы при создании формы и присвоения им заданных значений свойств.
Далее приведён текст модулей Form1.cs и Form1.Designer. cs после установки на форме экранной кнопки. При этом Form1.cs[Конструктор] приобретает следующий вид.

Модуль Form1.cs:
using System;
using System. Collections. Generic;
using ponentModel;
using System. Data;
using System. Drawing;
using System. Linq;
using System. Text;
using System. Windows. Forms;
namespace CSprim
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Привет");
}
}
}
Обработчик button_Click формируется автоматически, кроме подчёркнутой строки
MessageBox. Show("Привет");
которую вводит программист. В результате при нажатии на экранную кнопку на эуран выдаётся сообщение “Привет!”.
Модуль Form1.Designer. cs (в него автоматически введены подчёркнутые строки):
namespace CSprim
{
partial class Form1
{
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
private ponentModel. IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components!= null))
{
components. Dispose();
}
base. Dispose(disposing);
}
#region Код, автоматически созданный конструктором форм Windows
/// <summary>
/// Обязательный метод для поддержки конструктора - не изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
private void InitializeComponent()
{
this. button1 = new System. Windows. Forms. Button();
this. SuspendLayout();
//
// button1
//
this. button1.Location = new System. Drawing. Point(97, 94);
this. button1.Name = "button1";
this. button1.Size = new System. Drawing. Size(75, 23);
this. button1.TabIndex = 0;
this. button1.Text = "button1";
this. button1.UseVisualStyleBackColor = true;
this.button1.Click += new System. EventHandler(this. button1_Click);
//
// Form1
//
this. AutoScaleDimensions = new System. Drawing. SizeF(6F, 13F);
this. AutoScaleMode = System. Windows. Forms. AutoScaleMode. Font;
this. ClientSize = new System. Drawing. Size(292, 273);
this. Controls. Add(this. button1);
this. Name = "Form1";
this. Text = "Form1";
this. ResumeLayout(false);
}
#endregion
private System. Windows. Forms. Button button1;
}
}
УПРАЖНЕНИЯ
1. Добавьте в форму главное меню и обработайте события от активации его пунктов.
2.3. Приложение Windows Forms в Microsoft Visual Studio 2008 для среды CLR на языке C++
2.4. Приложение Windows Forms в Microsoft Visual Studio 2008 для среды Win32
// CppWin0101.cpp: определяет точку входа для приложения.
//
#include "stdafx. h"
#include "CppWin0101.h"
#define MAX_LOADSTRING 100
// Глобальные переменные:
HINSTANCE hInst; // текущий экземпляр
TCHAR szTitle[MAX_LOADSTRING]; // Текст строки заголовка
TCHAR szWindowClass[MAX_LOADSTRING]; // имя класса главного окна
// Отправить объявления функций, включенных в этот модуль кода:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: разместите код здесь.
MSG msg;
HACCEL hAccelTable;
// Инициализация глобальных строк
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_CPPWIN0101, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Выполнить инициализацию приложения:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CPPWIN0101));
// Цикл основного сообщения:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg. hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg. wParam;
}
//
// ФУНКЦИЯ: MyRegisterClass()
//
// НАЗНАЧЕНИЕ: регистрирует класс окна.
//
// КОММЕНТАРИИ:
//
// Эта функция и ее использование необходимы только в случае, если нужно, чтобы данный код
// был совместим с системами Win32, не имеющими функции RegisterClassEx'
// которая была добавлена в Windows 95. Вызов этой функции важен для того,
// чтобы приложение получило "качественные" мелкие значки и установило связь
// с ними.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex. cbSize = sizeof(WNDCLASSEX);
wcex. style = CS_HREDRAW | CS_VREDRAW;
wcex. lpfnWndProc = WndProc;
wcex. cbClsExtra = 0;
wcex. cbWndExtra = 0;
wcex. hInstance = hInstance;
wcex. hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CPPWIN0101));
wcex. hCursor = LoadCursor(NULL, IDC_ARROW);
wcex. hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex. lpszMenuName = MAKEINTRESOURCE(IDC_CPPWIN0101);
wcex. lpszClassName = szWindowClass;
wcex. hIconSm = LoadIcon(wcex. hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// ФУНКЦИЯ: InitInstance(HINSTANCE, int)
//
// НАЗНАЧЕНИЕ: сохраняет обработку экземпляра и создает главное окно.
//
// КОММЕНТАРИИ:
//
// В данной функции дескриптор экземпляра сохраняется в глобальной переменной, а также
// создается и выводится на экран главное окно программы.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Сохранить дескриптор экземпляра в глобальной переменной
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// ФУНКЦИЯ: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// НАЗНАЧЕНИЕ: обрабатывает сообщения в главном окне.
//
// WM_COMMAND - обработка меню приложения
// WM_PAINT - Закрасить главное окно
// WM_DESTROY - ввести сообщение о выходе и вернуться.
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Разобрать выбор в меню:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: добавьте любой код отрисовки...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Обработчик сообщений для окна "О программе".
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
УПРАЖНЕНИЯ
1. Добавьте в форму главное меню и обработайте события от активации его пунктов.
3. СПИСКИ И ТАБЛИЦЫ
3.1. Прото-СУБД на основе класса TStringList и TStringGrid (библиотека VCL Delphi)


unit Toy;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, Menus;
type
TFToy = class(TForm)
Grid: TStringGrid;
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
procedure FormCreate(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure ListToGrid(l, g: integer);
procedure GridToList(g, l: integer);
procedure ShiftUp;
procedure ShiftDown;
procedure LoadGrid;
procedure N4Click(Sender: TObject);
procedure GridKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
FToy: TFToy; sList1, sList2: TStringList; curl, curg: integer; vr:TGridRect;
implementation
{$R *.dfm}
uses math;
procedure TFToy. ShiftUp;
var i: integer;
begin
if Grid. RowCount>1then
for i:=2to Grid. RowCount-1 do
begin
Grid. cells[1,i-1]:=Grid. cells[1,i];
Grid. cells[2,i-1]:=Grid. cells[2,i]
end;
if sList1.Count-1=curl
then begin
Grid. cells[1,Grid. RowCount-1]:='';
Grid. cells[2,Grid. RowCount-1]:=''
end
else begin
Grid. cells[1,Grid. RowCount-1]:=sList1[curl+1];
Grid. cells[2,Grid. RowCount-1]:=sList2[curl+1]
end
end;
procedure TFToy. ShiftDown;
var i: integer;
begin
if Grid. RowCount>1
then begin
for i:=Grid. RowCount-2 downto 1 do
begin
Grid. cells[1,i+1]:=Grid. cells[1,i];
Grid. cells[2,i+1]:=Grid. cells[2,i]
end;
Grid. cells[1,i+1]:=sList1[curl-1];
Grid. cells[2,i+1]:=sList2[curl-1]
end
else begin
Grid. cells[1,1]:='';
Grid. cells[2,1]:=''
end
end;
procedure TFToy. GridToList(g, l: integer);
begin
if l>=sList1.Count
then begin
sList1.Add(Grid. cells[1,g]);
sList2.Add(Grid. cells[2,g])
end
else begin
sList1[l]:=Grid. cells[1,g];
sList2[l]:=Grid. cells[2,g]
end
end;
procedure TFToy. ListToGrid(l, g: integer);
begin
Grid. cells[1,g]:=sList1[l];
Grid. cells[2,g]:=sList2[l]
end;
procedure TFToy. LoadGrid;
var i: integer;
begin
if sList1.Count>0
then begin
for i:=1 to min(Grid. RowCount-1, sList1.Count)do
ListToGrid(sList1.Count-min(Grid. RowCount-1, sList1.Count)+i-1,i);
curl:=sList1.Count-1;
curg:=i-1
end
else begin
curl:=0;
curg:=1
end;
Grid. Cells[0,curg]:=' * ';
vr. left:=1;vr. right:=1; vr. Top:=curg; vr. bottom:=curg;
Grid. Selection:=vr
end;
procedure TFToy. FormCreate(Sender: TObject);
begin
sList1:=TStringList. Create;
sList2:=TStringList. Create;
OpenDialog1.Execute;
if not(OpenDialog1.FileName='')
then begin
sList1.LoadFromFile(OpenDialog1.FileName);
sList2.LoadFromFile(copy(OpenDialog1.FileName,1,length(OpenDialog1.FileName)-4)+'1.txt');;
LoadGrid
end
else begin
Grid. Cells[0,1]:=' * ';
curl:=0;
curg:=1
end
end;
procedure TFToy. N3Click(Sender: TObject);
begin
SaveDialog1.Execute;
if SaveDialog1.FileName=''
then showmessage('Имя файла не определено!')
else begin
sList1.SaveToFile(SaveDialog1.FileName);
sList2.SaveToFile(copy(SaveDialog1.FileName,1,length(SaveDialog1.FileName)-4)+'1.txt')
end
end;
procedure TFToy. N4Click(Sender: TObject);
begin
close
end;
procedure TFToy. GridKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if key=vk_Down
then begin
GridToList(curg, curl);
if curg=Grid. RowCount-1
then begin
ShiftUp;
curl:=curl+1
end
else begin
Grid. Cells[0,curg]:='';
curg:=curg+1;
Grid. Cells[0,curg]:=' * ';
curl:=curl+1
end;
vr. left:=1;vr. right:=1; vr. Top:=curg-1; vr. bottom:=curg-1;
Grid. Selection:=vr
end;
if key=vk_Up
then begin
GridToList(curg, curl);
if curg=1
then if curl>0
then begin
ShiftDown;
curl:=curl-1
end
else
else begin
Grid. Cells[0,curg]:='';
curg:=curg-1;
Grid. Cells[0,curg]:=' * ';
curl:=curl-1
end;
vr. left:=1;vr. right:=1; vr. Top:=curg+1; vr. bottom:=curg+1;
Grid. Selection:=vr
end
end;
end.
УПРАЖНЕНИЯ
1. Обеспечьте в прото-СУБД поиск путём явного перебора элементов базы данных.
2. Обеспечьте в прото-СУБД поиск путём использования метода IndexOf.
3. Экспериментально сравните быстродействие вариантов из упражнений 1 и 2.
4. РАЗРАБОТКИ И ВЕРИФИКАЦИЯ РАСЧЁТНЫХ ПРИЛОЖЕНИЙ
4.1. Спецификация программы uWert
Программа uWert является экранным приложением, обеспечивающим вычисле-ние заданного пользователем регулярного арифметического выражения.
Регулярное арифметическое выражение (РАВ) определяется в алфавите L десятичных цифр, знаков операций сложения +, вычитания - и умножения *, а также левой и правой круглой скобок по индукции:
1. Нумерал (здесь последовательность цифр без знака и без пробелов) является РАВ.
2. a) если строка X является РАВ, то строка (X) является РАВ;
b) если строки X и Y являются РАВ, то строки X+Y, X-Y, X*Y являются РАВ.
Нумералы представляют десятичные целые дчисла, результат вычисляется в соответствии с указанными знаками операций в соответствии с правилами обычной десятичной арифметики.
Это приложение имеет простой графический пользовательский интерфейс: окно ввода регулярного арифметического выражения, окно результата и кнопка, нажатие на которую вызывает вычисление.

4.2. Текст программы uWert
Программа отлажена на языке Object Pascal (Borland Delphi). В приведённом ниже тексте тела нескольких процедур перенумерованы для удобства дальнейших ссылок.
Unit uWert;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
eExpression: TEdit;
eValue: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 |


