Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 10.01.2007, 18:53
Error Error вне форума
Прохожий
 
Регистрация: 10.01.2007
Сообщения: 33
Репутация: 10
По умолчанию Как сделать тест?

Хочу написать тест:

procedure TForm1.Button1Click(Sender: TObject);
var k:????????;
begin
k:=??????ToStr(Edit1.Text);
if k=a
then Label1.Caption:='Правильно!'
Else Label1.Caption:='Не правильно'
end;

Что нужно?
Ответить с цитированием
  #2  
Старый 10.01.2007, 19:17
Аватар для CAHbKA
CAHbKA CAHbKA вне форума
Новичок
 
Регистрация: 10.01.2007
Сообщения: 66
Репутация: 10
По умолчанию

Файл теста


Тест представляет собой последовательность вопросов, на которые испытуемый должен ответить путем выбора правильного ответа из нескольких предложенных вариантов.


Файл теста состоит из трех разделов:

раздел заголовка;
раздел оценок;
раздел вопросов.

Заголовок содержит общую информацию о тесте, например, о его назначении. Заголовок может состоять из нескольких строк. Признаком конца заголовка является точка, стоящая в начале строки.


Вот пример заголовка файла теста:


Сейчас Вам будут предложены вопросы о знаменитых памятниках и архитектурных сооружениях Санкт-Петербурга.


Вы должны из предложенных нескольких вариантов ответа выбрать правильный.


За заголовком следует раздел оценок, в котором приводятся названия оценочных уровней и количество баллов, необходимое для достижения этих уровней. Название уровня должно располагаться в одной строке. Вот пример раздела оценок:


Отлично


100


Хорошо


85


Удовлетворительно


60


Плохо


50


Форма приложения
Эта форма будет использоваться как для вывода вопросов теста и ввода ответов пользователя, так и для вывода начальной информации о тесте и результатов тестирования.


Поле метки Label3 предназначено для вывода текста вопроса, начальной информации о тесте и результатов тестирования.


Поля Label 1, Label2, Label3 и Label 4 предназначены для вывода текста альтернативных ответов, а переключатели RadioButtoni, RadioButton2, RadioButton3 и RadioButton4 — для выбора ответа.


Командная кнопка Buttonl предназначена для подтверждения выбора альтернативного ответа и перехода к следующему вопросу теста.


Следует обратить внимание на недоступный (невидимый) во время работы переключатель RadioButton5. Перед выводом очередного вопроса он программно устанавливается в выбранное положение, что обеспечивает сброс (установку в невыбранное состояние) переключателей выбора ответа (RadioButton1i, RadioButton2, RadioButton3 И RadioButton4).


Следует обратить внимание, что несмотря на то, что свойства Border-icons. biMinimize И Borderlcons.biMaximize имеют значение False, кнопки свернуть окно и Развернуть окно отображены в форме. Реальное воздей-


ствие значения этих свойств на вид окна проявляется только во время работы программы. Значение свойства Borderstyle также проявляет себя только во время работы программы.


Вывод иллюстрации


Для вывода иллюстрации в форму добавлен компонент image, значок которого (рис. 15.3) находится на вкладке Additional палитры компонентов. В табл. 15.7 приведены свойства компонента image.


Картинку, отображаемую в области image, можно задать во время создания формы или во время работы программы. Во время создания формы картинка задается установкой значения свойства Picture. Во время работы программы — Применением Метода LoadFromFile.


Например, для разрабатываемого приложения инструкция вывода иллюстрации, находящейся в файле Isaak.bmp (изображение Исаакиевского собора), может быть такой:


Image1.Picture.LoadFromFile('isaak.bmp');


Очевидно, что размер области формы, которая может использоваться для вывода иллюстрации, зависит от длины (количества слов) вопроса, длины и количества альтернативных ответов. Чем длиннее вопрос и ответы, тем больше места в поле формы они занимают, и тем меньше места остается для иллюстрации.


При проектировании формы можно задать жесткие ограничения на размер областей, предназначенных для вопроса и альтернативных ответов, и жестко задать предельный размер иллюстрации. Однако можно поступить иначе. После прочтения из файла очередного вопроса вычислить, сколько места займут тексты вопроса и ответов и сколько места можно выделить для вывода иллюстрации
Если реальный размер иллюстрации превышает размер области, выделенной для ее вывода, то необходимо вычислить коэффициент масштабирования и установить максимально возможные, пропорциональные ширине и высоте иллюстрации, значения свойств width и Height области вывода иллюстрации.


Реальные размеры иллюстрации, загруженной в область image 1, можно получить из свойств Image1.Picture.Bitmap.Width И Image1.Picture.Bitmap.Height.


Загрузка файла теста


Передать имя файла теста программе тестирования можно через параметр командной строки путем настройки свойств значка, изображающего программу тестирования на рабочем столе или в папке.


Например, для настройки программы тестирования, значок запуска которой находится на рабочем столе, на работу с файлом теста Peterb.txt необходимо щелкнуть правой кнопкой мыши на значке программы, из появившегося контекстного меню выбрать команду Свойства и в поле Объект, после имени файла программы (Testl.exe), ввести имя файла теста (Peterb.txt), заключив его в двойные кавычки
Примечание


Текст, находящийся в поле Объект вкладки Ярлык диалогового окна Свойства, называется командной строкой.


Программа может получить параметр, указанный в командной строке запуска программы, как значение функции ParamStr^), где л — номер параметра. Количество параметров командной строки находится в глобальной переменной ParamCount. Для приведенного выше примера командной строки запуска программы тестирования значение переменной ParamCount равно 1, а функции ParamStr (1) — peterb.txt.


Ниже приведен фрагмент программы, обеспечивающий прием параметра из командной строки:


if ParamCount = 0 then begin


ShowMessage('Ошибка! Не задан файл вопросов теста.');

goto bye; // аварийное завершение программы

end;


FileName := ParamStr(1); // имя файла — параметр командной строки


При запуске программы, использующей параметры командной строки, из среды разработки параметры нужно ввести в поле Parameters диалогового окна Run Parameters (рис. 15.6), которое открывается в результате выбора из меню Run команды Parameters
Ответить с цитированием
  #3  
Старый 10.01.2007, 19:19
Аватар для CAHbKA
CAHbKA CAHbKA вне форума
Новичок
 
Регистрация: 10.01.2007
Сообщения: 66
Репутация: 10
По умолчанию

Текст программы


После создания формы в окно редактора кода, в секцию implementation следует поместить описание глобальных констант (раздел const) и переменных (раздел var). Затем можно приступить к созданию процедур обработки событий.


Их в программе три: обработка события onActivate для стартовой формы, обработка события Onclick для командной кнопки Buttoni и процедура обработки события onclick — одна, общая для переключателей выбора ответа.


В листинге 15.1 приведен полный текст программы.


Листинг 15.1. Программа тестирования


unit test1_;


interface


uses


SysUtils, WinTypes, WinProcs, Messages,

Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, ExtCtrls;


type


TForm1 = class(TForm) // вопрос

Label3: TLabel; // альтернативные ответы

Label1: TLabel; Label2: TLabel;

Label3: TLabel; Label4: TLabel;


// переключатели выбора ответа

RadioButton1: TRadioButton;

RadioButton2: TRadioButton;

RadioButton3: TRadioButton;

RadioButton4: TRadioButton;


Image1: TImage; // область вывода иллюстрации

Button1: TButton; // кнопка Ok, Дальше


RadioButtonS: TRadioButton; // "служебная" кнопка


Panel1: ТPanel;


procedure FormActivate(Sender: TObject);


procedure ButtonlClick(Sender: TObject};


procedure RadioButtonClick(Sender: TObject);

private


{ Private declarations }

public


{ Public declarations }

end;


var


Form1: TForm1; // форма


implementation


const


N_LEV=4; // четыре уровня оценки

N_ANS=4; // четыре варианта ответов


var


f:TextFile;


fn:string; // имя файла вопросов


1evel:array[1..N_LEV] of integer;

// сумма, соответствующая уровню

mes:array[1.,N_LEV] of string;

// сообщение, соответствующее уровню


score:array[1..N_ANS] of integer;

// балл за выбор ответа


summa:integer; // набрано очков


vopros:integer; // номер текущего вопроса


n_otv:integer; // число вариантов ответа


otv:integer; // номер выбранного ответа


// вывод начальной информации о тесте

procedure info(var f:TextFile;l:TLabel);

var


s,buf:string; begin


buf:='';


repeat


readln(f,s); if s[l] <> '.'


then buf := buf + s+ ' ';

until s[l] ='.'; l.caption:=buf;

end;


// прочитать информацию об оценках за тест


Procedure GetLevel(var f:TextFile);


var


i:integer; buf:string;


begin // заполняем значения глобальных массивов

i:=l;

repeat


readln(f,buf); if buf[1] <> '.' then begin

mes[i]:=buf; readln(f,level[i]);

i:=i+1;

end;


until buf[1]='.';

end;


// масштабирование иллюстрации


Procedure ScaleImage(Imagel:TImage);


var


w,h:integer; // максимально допустимые размеры картинки

scaleX:real; // коэф. масштабирования по X

scaleY:real; // коэф. масштабирования по Y

scale:real; // общий коэф. масштабирования


begin


// вычислить максимально допустимые размеры картинки

w:=Form1.ClientWidth-10;

h:=Form1.ClientHeight


- Form1.Panel1.Height -5


- Form1.Label5.Top


- Form1.Label5.Height - 5;

if Form1.Label1.Caption <> ''


then h:=h-Form1.Label1.Height-5;

if Form1.Label2.Caption <> ''


then h:=h-Form1.Label2.Height-5;

if Forml.Label3.Caption <> ''


then h:=h-Form1.Label3.Height-5;

if Forml.Label4.Caption <> "


then h:=h-Form1.Label4.Height-5; // определить масштаб

if w>Imagel.Picture.Bitmap.Width

then scaleX:=l


else scaleX:=w/Imagel.Picture.Bitmap.Width;

if h>Imagel.Picture.Bitmap.Height

then scaleY:=l


else scaleY:=h/Image1.Picture.Bitmap.Height;

if ScaleY<ScaleX


then scale:=scaleY

else scale:=scaleX; // здесь масштаб определен


Image1.Top:=Form1.Label5.Top+Form1.Labels.Height+5 ;

Image1.Width:=Round(Image1.Picture.Bitmap.Width* scale);

Image1.Height:=Round(Image1.Picture.Bitmap.Height* scale);

end;


// вывод вопроса на экран


Procedure VoprosToScr(var f:TextFile;frm:TForm1;var vopros:integer)

var


i:integer;

code:integer;

s,buf:string;


ifn:string; // файл иллюстрации

begin


vopros:=vopros+l ;


str(vopros:3,s) ;


frm. caption: = 'Вопрос' + s;


//выведем текст вопроса


buf:='';


repeat


readln(f, s) ;


if (s[l] <> '.') and (s[l] <>'\')


then buf:=buf+s+' ';

until (s[l] ='.') or (s[l] = '\');

frm. labels.caption:=buf;


if s[1] <> '\'


then Form1.Image1.Tag:=0 else

// к вопросу есть иллюстрация

begin


Form1.Image1.Tag:=1;


if n:=copy(s,2,length(s));


try


Form1.Image1.Picture.LoadFromFile(ifn)

except


on E:EFOpenError do


frm.tag:=0; end; // try end;


// читаем варианты ответов


i:=l;


repeat


buf: = ";


repeat // читаем текст варианта ответа

readln(f,s);

if (s[1]<>'. ') and (s[l] о ', ')


then buf:=buf+s+' ';

until (s[l]=',')or(s[1]='.'); // прочитан альтернативный ответ

val(s[2],score[i],code);

case i of


1: frm.Label1.caption:=buf;

2: frm.Label2.caption:=buf;

3: frm.Label3.caption:=buf;

4: frm.Label4.caption:=buf;

end;


until s[l]='.';


// здесь прочитана иллюстрация и альтернативные ответы

// текст вопроса уже выведен


if Forml.Image1.Tag =1 // есть иллюстрация к вопросу then

begin


Scalelmage(Form1.Image1); Form1.Image1.Visible:=TRUE;

end;


// вывод альтернативных ответов

if Form1.Label1.Caption <> " then begin


if Forml.Image1.Tag =1


then

frm.Label1.top:=frm.Imagel.Top+frm.Image1.Height+5

else

frm.Label1.top:=frm.Label5.Top+frm.Labels.Height+5 ;

frm.RadioButton1.top:=frm.Label1.top;

frm.Labell.visible:=TRUE;

frm.RadioButton1.visible:=TRUE;

end;


if Forml.Label2.Caption <> " then begin


frm.Label2.top:=frm.Label1.top+ frm.Label1.height+5;

frm.RadioButton2.top:=frm.Label2.top;

frm.Label2.visible:=TRUE;

frm.RadioButton2.visible:=TRUE;

end;


if Forml.Label3.Caption <> '' then begin


frm.Label3.top:=frm.Label2.top+ frm.Label2.height+5;

frm.RadioButtonS.top:=frm.Label3.top;

frm.Label3.visible:=TRUE;

frm.RadioButtonS.visible:=TRUE;

end;


if Forml.Label4.Caption <> '' then begin


frm.Label4.top:=frm.Label3.top+ frm.Label3.height+5;

frm.RadioButton4. top:=frm.Label4.top;


frm.Label4.visible:=TRUE;

fm.Rad±o8utton4.vis:tble:=TRUE]

end;

end;


Procedure ResetForm(frm:TForml);

begin


// сделать невидимыми все метки и переключатели


frm.Label1.Visible:=FALSE;


f rm.Label1.caption: ='';


frm.Label1.width:=frm.ClientWidth-frm.Label1.left-5;


frm.RadioButtonl.Visible:=FALSE;


frm.Label2.Visible:=FALSE;


frm.Label2.caption:='';


frm.Label2.width:=frm.ClientWidth-frm.Label2.left-5;


frm.RadioButton2.Visible:=FALSE;


frm.Label3.Visible:=FALSE;


frm.Label3.caption:='';


frm.Label3.width:=frm.ClientWidth-frm.Label3.left-5;


frm.RadioButton3.Visible:=FALSE;


frm.Label4.Visible:=FALSE;


frm.Label4.caption:='';


frm.Label4.width:=frm.ClientWidth-frm.Label4.left-5;


f rm.RadioButton4.Visible:=FALSE;


frm.Label5.width:=frm.ClientWidth-frm.Labels.left-5;


frm. Image1.Visible:=FALSE;

end;


// определение достигнутого уровня

procedure Itog(summa:integer;frmrTForml);

var


i:integer; buf:string;

begin


buf: = ";


str(summa:5,buf);


buf:='Результаты тестирования'+chr(13)


+'Всего баллов: '+buf; i:=1;

while (summa < level[i]) and (i<N_LEV) do


i:=i+l;


buf:=buf+chr(13)+mes[ i ] ; frm.Labels.caption:=buf;

end;


{$R *.DFM}


procedure TForm1.FormActivate(Sender: TObject);

begin


ResetForm(Form1);

if ParamCount = 0 then

begin


Labels.caption:= 'He задан файл вопросов теста.';

Button1.caption: ='Ok' ;

Button1.tag:=2; Button1.Enabled:=TRUE

end

else begin


fn := ParamStr(1); assignfile(f,fn); {$I-} reset(f);


{I+}


if IOResult=0 then begin


Info(f,Label5);

// прочитать и вывести информацию о тесте

GetLevel(f); // прочитать информацию об уровнях оценок

end;

end;

end;


procedure TForml.ButtonlClick(Sender: TObject); begin


case Button1.tag of 0: begin


Buttonl.caption:='Дальше';

Buttonl.tag:=1;

RadioButtonS.Checked:=TRUE; // вывод первого вопроса

Buttonl.Enabled:=False; ResetForm(Form1);

VoprosToScr(f,Forml,vopros}

end;


1: begin // вывод остальных вопросов

summa:=summa+score[otv];

RadioButtonS.Checked:=TRUE;

Button1.Enabled:=False;

ResetForm(Form1);

if not eof(f)


then VoprosToScr(f,Forml,vopros) else


begin


suima: =summa+score [otv] ;

closefile(f);

Buttonl.caption:='Ok';

Form1.caption: ='Результат';

Button1.tag:=2;

Button1.Enabled:=TRUE;

Itog(summa,Forml);

end;

end;

2: begin // завершение работы


Forml.Close;

end;

end;

end;


procedure TForm1.RadioButtonClick(Sender: TObject);

begin


if sender = RadioButtonl

then otv:=l


else if sender = RadioButtonl

then otv:=2


else if sender = RadioButton3

then otv:=3 else otv:=4;

Buttonl.enabled:=TRUE;

end;


end.
Ответить с цитированием
  #4  
Старый 10.01.2007, 19:21
ART ART вне форума
Продвинутый
 
Регистрация: 13.02.2006
Адрес: Магнитогорск
Сообщения: 669
Репутация: 14745
По умолчанию

Смотря чаво в Edit, если
число, то
k:integer и StrtoInt(Edit1.Text)
строка, то
k:string и Edit1.Text
Ответить с цитированием
  #5  
Старый 10.01.2007, 19:24
Error Error вне форума
Прохожий
 
Регистрация: 10.01.2007
Сообщения: 33
Репутация: 10
По умолчанию

Спасибо огромное, теперь придется разбираться:d
Ответить с цитированием
  #6  
Старый 10.01.2007, 19:26
ART ART вне форума
Продвинутый
 
Регистрация: 13.02.2006
Адрес: Магнитогорск
Сообщения: 669
Репутация: 14745
По умолчанию

А лучше возьми и движок тестов напиши!
Ответить с цитированием
  #7  
Старый 10.01.2007, 19:26
Аватар для CAHbKA
CAHbKA CAHbKA вне форума
Новичок
 
Регистрация: 10.01.2007
Сообщения: 66
Репутация: 10
По умолчанию

После запуска программы и вывода на экран стартовой формы происходит событие onActivate. Процедура FormActivate сначала вызывает процедуру ResetForm, которая, присваивая значение False свойству visible, делает невидимыми поля вывода альтернативных ответов и переключатели. Аналогично делается невидимой область иллюстрации. Кроме того, процедура устанавливает максимально возможную ширину полей меток альтернативных ответов.


После очистки формы проверяется, указан ли при запуске программы параметр — имя тестового файла.


Если параметр не указан (значение paramCount в этом случае равно нулю), то присвоением значения свойству caption метки Label5 выводится сообщение: Не задан файл вопросов теста И свойству Tag кнопки Button1 присваивается значение 2(Button1.Tag:=2


Если параметр задан, то открывается файл теста.


Программа тестирования получает имя файла теста как результат функции Paramstr(l). Реализация программы предполагает, что если имя файла теста задано без указания пути доступа к нему, то файл теста и файлы с иллюстрациями находятся в том же каталоге, что и программа тестирования. Если путь доступа указан, то файлы с иллюстрациями должны находиться в том же каталоге, что и файл теста. Такой подход позволяет сгруппировать все файлы одного теста в одном каталоге.


Открывается файл теста обычным образом. Сначала обращением к процедуре AssignFile имя файла связывается с файловой переменной, а затем вызывается инструкция открытия файла для чтения.


После успешного открытия файла вызывается процедура info, которая считывает из файла информацию о тесте и выводит ее присваиванием прочитанного текста свойству Caption поля метки Labels.


Затем вызывается процедура GetLevei, которая считывает из файла теста информацию об уровнях оценки. Эта процедура заполняет массивы level И mes.


После вывода информационного сообщения программа ждет, когда пользователь нажмет кнопку OK (Button1).


Командная кнопка Buttoni используется для:


аварийного завершения работы приложения (в случае, если не задано имя файла теста);

начала тестирования (после прочтения информационного сообщения);
перехода к следующему вопросу (после выбора одного из ответов);

завершения работы программы (после прочтения результатов тестирования).

Свойство Tag кнопки Buttoni используется для идентификации текущего состояния формы и выбора действия при щелчке на кнопке Buttoni.


После вывода информации о тесте значение свойства Tag кнопки Button: равно нулю. Поэтому в результате первого щелчка на кнопке Buttoni выполняется та часть программы, которая обеспечивает вывод первого вопроса, замену находящегося на кнопке текста ОК на текст Дальше, и устанавливает в выбранное состояние переключатель RadioButton5, который закрыт панелью и поэтому не виден пользователю. Кроме того, присваиванием значения False свойству Enabled кнопка Buttoni делается недоступной, тем самым блокируется переход к следующему вопросу до тех пор, пока не будет выбран один из ответов. Значению свойства Button1.Tag присваивается единица, тем самым выполняется подготовка к обработке следующего щелчка кнопки Button1.


После выбора ответа и нажатия кнопки Дальше (Buttoni) (в этом случае значение свойства Button1.Tag равно единице) к набранной сумме баллов добавляется количество баллов за выбранный ответ. Затем, если не достигнут конец файла, вызывается процедура вывода очередного вопроса. Если достигнут конец файла, то сначала закрывается файл теста, изменяется текст на кнопке Buttoni и значение Button1. Tag, а затем посредством процедуры Itog выводятся результаты тестирования.


Если значение Button1.Tag равно двум, то применением метода close к форме Form1 закрывается окно программы, в результате чего программа завершает работу.


Вывод вопроса и альтернативных ответов выполняет процедура VoprosToScr. Сначала процедура увеличивает счетчик вопросов vopros и присвоением значения свойству Caption формы выводит номер текущего вопроса в заголовок окна. Затем процедура читает строки из файла теста до тех пор, пока первым символом очередной прочитанной строки не будет точка или "обратная наклонная черта".


После вывода текста вопроса делается проверка: какой символ используется в качестве признака конца вопроса. Если обратная наклонная черта, что свидетельствует о том, что к вопросу есть иллюстрация, то свойству Form1.image1.Tag присваивается единица и из прочитанной строки выделяется имя файла иллюстрации.


Загрузка иллюстрации осуществляется применением метода LoadFromFile к свойству image1. Picture. Однако после загрузки иллюстрация на экране не появляется, так как значение свойства Image1. visible равно False.


После считывания иллюстрации процедура считывает вопросы. После обработки последнего вопроса, если была загружена иллюстрация, вызовом процедуры ScaleImage вычисляется и устанавливается размер области иллюстрации. После этого установкой значения свойства Imagel.Top задается положение верхней границы области иллюстрации, а присваиванием значения True свойству image1. visible иллюстрация делается видимой.


Так как количество символов в тексте вопроса и число альтернативных ответов от вопроса к вопросу могут меняться, и, следовательно, на экране они могут занимать разное количество строк, то каждый раз перед выводом текста очередного ответа устанавливается значение свойства тор как расстояние от нижней границы предыдущего альтернативного ответа. Для поля вывода первого альтернативного ответа (Label) значение тор вычисляется от нижней границы поля вопроса (Labels) или, если к вопросу есть иллюстрация, от нижней границы поля иллюстрации (imagei).


Выбор ответа пользователь осуществляет щелчком одного из переключателей. После вывода вопроса ни один из переключателей, соответствующих альтернативному ответу, не является выбранным. Выбран только переключатель RadioButtonS, который находится за панелью Panel1 и поэтому не виден пользователю.


Для обработки события onclick переключателей RadioButton1,


RadioButton2, RadioButton3 и RadioButton4

В Программе используется общая процедура— TForm1.RadioButtonciick. Эта процедура получает в качестве параметра объект, на котором произошло событие. Сравнивая полученное значение с именами объектов-кнопок выбора, процедура присваивает значение глобальной переменной otv, которая используется процедурой VoprosToScr для увеличения набранной суммы баллов. Кроме того, процедура TForm1.RadioButtonClick делает доступной кнопку перехода к следующему вопросу (Buttonl), которая после вывода очередного вопроса недоступна.


Процедура Itog, сравнивая набранную сумму баллов summa со значением элементов массива level, определяет, какого уровня достиг испытуемый, и выводит соответствующее сообщение присвоением значения свойству


Label5.Caption.
Ответить с цитированием
  #8  
Старый 10.01.2007, 19:27
Error Error вне форума
Прохожий
 
Регистрация: 10.01.2007
Сообщения: 33
Репутация: 10
По умолчанию

Сколько много текста, мне не прочитать его за всю жизнь:d
А придется

Последний раз редактировалось Error, 10.01.2007 в 19:31.
Ответить с цитированием
  #9  
Старый 10.01.2007, 19:29
Аватар для CAHbKA
CAHbKA CAHbKA вне форума
Новичок
 
Регистрация: 10.01.2007
Сообщения: 66
Репутация: 10
По умолчанию

Усовершенствование программы


Очевидно, что приведенный выше текст программы был бы намного проше и изящней, если бы поля вывода альтернативных ответов и переключатели выбора ответов были бы объединены в массивы. Тогда программа могла бы обращаться к полям и переключателям не по имени, а по индексу.


Delphi позволяет объединить компоненты в массив, однако создаваться такие компоненты должны не во время создания формы приложения, а динамически — во время работы программы.





На форме отсутствуют поля вывода альтернативных ответов и переключатели выбора правильного ответа. Они будут созданы во время работы программы.


Объявление массива компонентов ничем не отличается от объявления обычного массива — указывается имя массива, диапазон изменения индекса и тип элементов массива. Ниже приведено объявление массивов компонентов формы разрабатываемой программы:

answer: array[1..N_ANSWERS] of TLabel;

// альтернативные ответы selector:

array[1..N_ANSWERS+1] of TRadioButton;

// кнопки выбора ответа


Однако, для того чтобы компонент появился в форме, одного объявления недостаточно. Компонент — это объект Delphi, и его объявление — это только указатель на область памяти, который без наличия объекта ни на что не указывает. Создается компонент применением метода Create к указателю на компонент, в нашем случае — к элементу массива.


Например, инструкции


answer[1] := TLabel.Create(self) ;


answer[1].Parent := Form1;


создают компонент Label и помещают его в форму.


После создания компонента программа должна выполнить его настройку, т. е. ту работу, которую во время создания формы приложения выполняет программист при помощи Object Inspector. Под настройкой понимается присваивание начальных значений тем свойствам компонента, предопределенные значения которых не отвечают предъявляемым требованиям.


Если компонент должен реагировать на некоторое событие, то. нужно написать процедуру обработки этого события и поместить объявление созданной процедуры в объявление типа формы. Например, объявление типа формы разрабатываемой программы должно выглядеть так:


type


TForm1 = class(TForm)


Label5: TLabel; // поле вывода вопроса


Image1: TImage; // область вывода иллюстрации


Panel1: TPanel;


Button1: TButton; // кнопка Ok, Дальше, Завершить


procedure FormActivate(Sender: TObject);


procedure FormCreate(Sender: TObject);


procedure ButtonlClick(Sender: TObject);


procedure SelectorClick(Sender: TObject);

private


{ Private declarations } public


{ Public declarations } end;


В отличие от других, сгенерированных Delphi, строк объявления типа, строка procedure SelectorClick(Sender: TObject) вставлена В объявление вручную.


Примечание


При создании процедуры обработки события для обычного компонента (компонента, который добавлен в форму во время разработки формы программы) Delphi автоматически генерирует заготовку процедуры обработки события и ее объявление. Программист должен написать только инструкции процедуры.


В случае создания процедуры обработки события для компонента, который создается динамически, программист должен полностью написать текст процедуры и поместить ее объявление в объявление формы.


После того как будет написана процедура обработки события, нужно связать эту процедуру с конкретным компонентом. Делается это путем присвоения имени процедуры обработки свойству, имя которого совпадает с именем обрабатываемого события. Например, инструкция


selector[1].OnClick : = SelectorClick;


задает процедуру обработки события Onclick для компонента selector [i]. В листинге 15.2 приведен полный текст программы Тест, версия 2.
Ответить с цитированием
  #10  
Старый 10.01.2007, 19:30
Аватар для CAHbKA
CAHbKA CAHbKA вне форума
Новичок
 
Регистрация: 10.01.2007
Сообщения: 66
Репутация: 10
По умолчанию

Листинг 15.2. Программа тестирования, версия 2


unit test2_;


interface


uses


SysUtils, WinTypes, WinProcs,

Messages, Classes, Graphics,

Controls, Forms, Dialogs,

StdCtrls, ExtCtrls;


type


TForm1 = class(TForm)


Label5: TLabel; // поле вывода вопроса

Image1: TImage; // область вывода иллюстрации

Panel1: ТPanel; Button1: TButton;

// кнопка Ok, Дальше, Завершить


procedure FormActivate(Sender: TObject);


procedure FormCreate(Sender: TObject);


procedure ButtonlClick(Sender: TObject);


procedure SelectorClick(Sender: TObject);

private


{ Private declarations } public


{ Public declarations } end;


var


Form1: TForm1; // форма

implementation


const


N_ANSWERS=4; // четыре варианта ответов

N_LEVEL=4; // четыре уровня оценки


var


// динамически создаваемые компоненты


answer: array[1..N_ANSWERS] of TLabel;

// альтернативные ответы


selector: array[1..N_ANSWERS+1] of TRadioButton;

// кнопки выбора ответа


f:TextFile;


fn:string; // имя файла вопросов


level:array[1..N_LEVEL] of integer;

// сумма, соответствующая уровню


mes:array[1..N_LEVEL] of string;

// сообщение, соответствующее уровню


score:array[1..N_ANSWERS] of integer;

// очки за выбор ответа


summa:integer; // набрано очков


vopros:integer; // номер текущего вопроса


n_otv:integer; // число вариантов ответа


otv:integer; // номер выбранного ответа


// установка формы в исходное состояние

Procedure ResetForm(frm:TForm1);

var


i:integer; begin


for i:=1 to N_ANSWERS do begin


answer[i].width:=frm.ClientWidth-answer[i].left-5;

answer[i].Visible:=FALSE; Selector[i].Visible:=FALSE;

end;


frm. Label5.width:=frm.ClientWidth-frm.Label5.left-5;

frm. Image1.Visible:=False;

end;


// определение достигнутого уровня

procedure Itog(suirana:integer;frm:TForm1);

var


i:integer; buf:string;

begin buf: = ";


str(summa:5,buf); buf:='Результаты тестирования'+chr(13)


+'Всего баллов: '+buf; i:=1;

while (summa < level[i]) and (i<N_LEVEL) do


i:=i+l;


buf:=buf+chr(13)+mes[i];

frm.Labels.caption:=buf;

end;


procedure TForm1.FormCreate(Sender: TObject);

var


i: integer; begin


// создадим пять меток для вывода вопроса и альтернативных ответов


for i:=l to N_ANSWERS do


begin


answer[i]:=TLabel.Create(self);

answer[i].Parent:=Forml;

answer[i].Left:=36;

answer[i].Wordwrap:=True;

end;


// создадим переключатели для выбора ответа


for i:=l to N_ANSWERS+1 do


begin


selector[i]:=TRadioButton.Create(self);


selector[i].Parent:=self;


selector[i].Caption:='';


selector[i].Width:=17;


selector[i].Left:=16;


selector[i].Visible:=False;


selector[i].Enabled:=True;


selector[i].OnClick:=SelectorClick;

end;


ResetForm(Forml); end;


// вывод начальной информации о тесте

procedure info(var f:TextFile;l:TLabel);

var


s,buf:string; begin


buf:=''; repeat


readln(f,s); if s[l]<>'.'


then buf:=buf+s+' ';

until s[l] ='.';

Form1.Labels.caption:=buf;

end;


// прочитать информацию об оценках за тест


Procedure GetLevel(var f:TextFile);


var


i:integer; buf:string;


begin // заполняем значения глобальных массивов i:=1;

repeat


readln(f,buf); if buf[1] <> '.' then

begin mes[i]:=buf; readln(f,level[i]); i:=i+1;

end;

until buf[1]='.';


end;


// масштабирование иллюстрации


Procedure ScalePicture;


var


w,h:integer; // максимально допустимые размеры картинки


scaleX:real; // коэф. масштабирования по X


scaleY:real; // коэф. масштабирования по Y


scale:real; // общий коэф. масштабирования


i:integer; begin


// вычислить максимально допустимые размеры картинки


w:=Form1.ClientWidth-Form1.Labels.Left;


h:=Form1.ClientHeight


- Form1.Panel1.Height -5


- Form1.Label5.Top


- Forml.Label5.Height - 5;

for i:=1 to N_ANSWERS do


if answer[i].Caption <> ''


then h:=h-answer[i].Height-5;


// здесь определена максимально допустимая величина иллюстрации


// определить масштаб

if w>Form1.Image1.Picture.Width


then scaleX:=1


else scaleX:=w/Forml.Image1.Picture.Width;

if h>Forml.Image1.Picture.Height


then scaleY:=1


else scaleY:=h/Form1.Image1.Picture.Height;

if ScaleYOcaleX


then scale:=scaleY


else scale:=scaleX; // здесь масштаб определен


Form1.Image1.Top:=

Form1.Label5.Top+Forml.LabelS.Height+5;

Form1.Image1.Left:=Form1.Label5.Left;


Form1.Image1.Width:=

Round(Form1.Image1.Picture.Width*scale);

Form1.Image1.Height:=

Round(Form1.Image1.Picture.Height*scale)

Form1.Label5.Visible:=TRUE;


end;


// вывод вопроса на экран


Procedure VoprosToScr(var f:TextFile;

frm:TForm1;var vopros:integer),

var


i:integer; code:integer; s,buf:string;


ifn:string; // файл иллюстрации

begin


vopros:=vopros+1 ;


str(vopros:3,s);


frm. caption: ='Вопрос' + s;


// выведем текст вопроса


buf: = ";


repeat


readln(f, s) ;


if (s[l] <> '.') and (s[l] <> '\')


then buf:=buf+s+' ';

until (s[l] ='.'} or (s[l] = '\');

frm.Labels.caption:=buf;


if s[l] = '\'


then // к вопросу есть иллюстрация

begin


frm.Image1.Tag:=1; ifn:=copy(s,2,length(s));

try


frm.Image1.Picture.LoadFromFile(ifn); except


on E:EFOpenError do


frm.tag:=0; end //

try

end

else frm. Image1.Tag: =0;


// читаем варианты, ответов


for i:=1 to N_ANSWERS do begin


answer[i].caption:='';


answer[i].Width:=frm.ClientWidth-Form1.Label5.Left-5;

end; i:=l;

repeat


buf: = " ;


repeat // читаем текст варианта ответа

readln(f,s);

if (s[l]<>'.') and (s[1] <> ',')


then buf:=buf+s+' ';

until (s[1]=',')or(s[l]='.');


// прочитан альтернативный ответ


val (s[2],score[i],code);


answer[i].caption:=buf;


i:=i+l;


until s [1] = '.'; // здесь прочитана иллюстрация и альтернативные ответы


if Form1.Image1.Tag =1 // есть иллюстрация к вопросу?

then begin ScalePicture;


Forml.Image1.Visible:=TRUE;

end;


// вывод альтернативных ответов


i:=1;


while (answer[i].caption <> ") and (i <= N_ANSWERS) do


begin


if i = 1 then


if frm.Image1.Tag =1


then answer[1].top:=frm.Image1.Top+frm.Image1.Height+5

else answer[i].top:=frm.Label5.Top+frm.Label5.Height+5

else


answer [i] . top:=answer [i-1] .

top+ answer [i-1] . height+5;

selector[i] . top:=answer [i] .

top; selectorfi] ,visible:=TRUE;

answer [i] . visible : =TRUE; i:=i+l;

end;

end;


{$R *.DFM}


procedure TForml . FormActivate ( Sender : TOb j ect ) ;

begin


ResetForm ( Forml ) ;

if ParamCount = 0 then begin


Label3 . font . color : =clRed;


Label5. caption: = 'He задан файл вопросов теста.1;

Buttonl . caption : = ' Ok ' ; Buttonl.tag:=2;

Buttonl . Enabled : =TRUE

end else

begin


fn:=ParamStr (1) ;

assignf ile ( f , fn) ;

{$!-} reset (f) ;


if IOResult=0 then

begin


Inf <> (f, Label3) ;

GetLevel(f) ;

end;


summa:=0;

end;

end;


procedure TForm1. ButtonlClick (Sender: TObject)

begin


case Button1.tag of

0: begin


Button1.caption:='Дальше';

Buttonl.tag:=1;


Selector[N_ANSWERS+1].Checked:=TRUE; // вывод первого вопроса

Buttonl.Enabled:=False;

ResetForm(Forml);

VoprosToScr(f,Forml,vopros)

end;


1: begin // вывод остальных вопросов

summa:=summa+score[otv];

Selector[N_ANSWERS+1].Checked:=TRUE;

Button1.Enabled:=False; ResetForm(Form1);

if not eof(f)


then VoprosToScr(f,Forml,vopros) else


begin


closefile(f); Button1.caption:='Ok';

Forml.сарtiоn:='Результат';

Buttonl.tag:=2; Buttonl.Enabled:=TRUE;

Itog(summa,Form1);

end;

end;

2: begin // завершение работы


Form1.Close;

end;

end;

end;


// щелчок на кнопке выбора ответа


procedure TForml.SelectorClick(Sender: TObject);


var


i: integer;


begin


while selector[i].Checked = FALSE do


i:=i+l;

otv:=i;


Buttonl.enabled:=TRUE;

end;


end.


По сравнению с первым вариантом программа Тест, версия 2 обладает существенным преимуществом. Для ее модернизации, например для увеличения количества альтернативных ответов, достаточно изменить только описание именованной константы N_ANSWERS.
Ответить с цитированием
  #11  
Старый 10.01.2007, 19:32
Аватар для CAHbKA
CAHbKA CAHbKA вне форума
Новичок
 
Регистрация: 10.01.2007
Сообщения: 66
Репутация: 10
По умолчанию

Я надеюсь ты все поймешь и разберешся это полный код программы + усовершенствования используй его как пример
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 18:46.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter