Элементы технологии программирования

в примерах и упражнениях

Уче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)  активируйте в главном меню FileNewApplication

При создании нового проекта этого типа 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