Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Делфи _ Тестирование

Автор: Atreides 27.01.2006 22:36

Хочу написать программку, которая будет задать вопросы. На них нужно отвечать за определенное количество времени, а когда время заканчивается, она должна переходить к подсчету правильных ответов и выдаче оценки, как написать такой таймер? Как задать фоновой рисунок окошку программки и как сделать картинку ссылкой в инет? Эта прога обращается к вопросам в текстовом файле, который можно легко вскрыть и посмотреть ответы, можно ли сделать, так что бы это текст скрывался в коде проги или сделать его недоступным для чтения?

Код
unit test01;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
type
  TForm1 = class(TForm)
    Label1: TLabel;
    RadioButton1: TRadioButton;
    RadioButton2: TRadioButton;
    RadioButton3: TRadioButton;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure RadioButton1Click(Sender: TObject);
    procedure RadioButton2Click(Sender: TObject);
    procedure RadioButton3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
var
  f: TextFile;      // файл теста (вопросы и варианты ответов)
  nq: integer;      // количество вопросов в тесте
  right: integer;   // количество правильных ответов
  level: array[1..4] of integer;      // критерии оценок
  mes: array[1..4] of string;    // комментарии
  buf: string;
// читает вопрос из файла и выводит его
// на в поля формы
function NextQw : boolean;
begin
  if not EOF(f) then
  begin
    // прочитать и вывести вопрос
    Readln(f,buf);
    Form1.Label1.Caption := buf;
    // прочитать и вывести варианты ответов
    // 1-й вариант
    Readln(f,buf);  // прочитать 1-й вариант ответа
    Form1.Label2.Caption := buf;
    Readln(f,buf);  // оценка за выбор этого ответа (1 - правильно, 0 - нет)
    Form1.RadioButton1.Tag := StrToInt(buf);
    // 2-й вариант
    Readln(f,buf);
    Form1.Label3.Caption := buf;
    Readln(f,buf);
    Form1.RadioButton2.Tag := StrToInt(buf);
    // 3-й вариант
    Readln(f,buf);
    Form1.Label4.Caption := buf;
    Readln(f,buf);
    Form1.RadioButton3.Tag := StrToInt(buf);
    // счетчик общего количества вопросов
    nq:= nq + 1;
    // кнопка "Дальше" не доступна,
    // пока не выбран один из вариантов ответа
    Form1.Button1.Enabled := False;
    // ни одна из радиокнопок не выбрана
    Form1.RadioButton1.Checked := False;
    Form1.RadioButton2.Checked := False;
    Form1.RadioButton3.Checked := False;
    NextQw := TRUE;
  end
  else NextQw := FALSE;
end;
// событие FormCreate возникает в момент
// создания формы
procedure TForm1.FormCreate(Sender: TObject);
var
  i: integer;
  fname : string;
begin
  { Если программа запускается из Delphi,
    то имя файла теста надо ввести в
    поле Parameters диалогового окна
    Run Parameters, которое становится
    доступным в результате выбора в меню
    Run команды Parameters.}
  fname := ParamStr(1); // взять имя файла теста
                        // из командной строки
  if fname = '' then
  begin
    ShowMessage('В командной строке запуска программы' +#13+
                'надо указать имя файла теста.');
    Application.Terminate; // завершить программу
  end;
  AssignFile(f,fname);

  // в процессе открытия файла возможны
  // ошибки, поэтому ...
  try
    Reset(f); // эта инструкция может вызвать ошибку
  except
    on EInOutError do
        begin
            ShowMessage('Ошибка обращения к файлу теста: ' + fname);
            Application.Terminate; // завершить программу
        end;
  end;
  // здесь файл теста успешно открыт
  // прочитать название теста - первая строка файла
  Readln(f,buf);
  Form1.Caption := buf;
  // прочитать оценки и комментарии
  for i:=1 to 4 do
    begin
      Readln(f,buf);
      mes[i] := buf;
      Readln(f,buf);
      level[i] := StrToInt(buf);
    end;
   right := 0; // правильных ответов
   nq := 0;    // всего вопросов
   NextQW;     // прочитать и вывести первый вопрос
end;
// щелчок на кнопке "Дальше"
procedure TForm1.Button1Click(Sender: TObject);
var
    buf: string;
    i: integer;
begin
    if Button1.Caption = 'Завершить' then Close;
    // добавим оценку за выбранный вариант ответа
    // оценка находится в свойстве Button.Tag
    // Button.Tag = 1 - ответ правильный, 0 - нет
    if RadioButton1.Checked  then
        right := right + RadioButton1.Tag;
    if RadioButton2.Checked  then
       right := right + RadioButton2.Tag;
    if RadioButton3.Checked  then
       right := right + RadioButton3.Tag;
  // вывести следующий вопрос
  // NextQW читает и выводит вопрос
  // NextQw = FALSE если в файле теста
  // вопросов больше нет
  if not NextQW then
  begin
      // здесь значение NextQw = FALSE
      Button1.Caption := 'Завершить';

      // скрыть переключатели и поля меток
      RadioButton1.Visible := False;
      RadioButton2.Visible := False;
      RadioButton3.Visible := False;
      Label2.Visible := False;
      Label3.Visible := False;
      Label4.Visible := False;
      buf := 'Тестирование завершено.' + #13 +
             'Правильных ответов: ' + IntToStr(right) +
             ' из ' + IntToStr(nq) + '.' + #13;
      // выставить оценку
      // right - кол-во правильных ответов
      i:=1; // номер уровня
      while (right < level[i]) and (i < 4) do
            inc(i);
      buf := buf + mes[i];
      Label1.AutoSize := TRUE;
      Label1.Caption := buf;
    end;end;
// щелчок на переключателе выбора первого варианта ответа
procedure TForm1.RadioButton1Click(Sender: TObject);
begin
  Button1.Enabled := True; // кнопка Далее теперь доступна
end;
procedure TForm1.RadioButton2Click(Sender: TObject);
begin
  Button1.Enabled := True;
end;
procedure TForm1.RadioButton3Click(Sender: TObject);
begin
  Button1.Enabled := True;
end;end.

Автор: hardcase 28.01.2006 1:00

Таймер можно сделать с помощью TTimer компоненты - при срабатывании таймера ты поднимаешь какойнить флаг.
Ссылку в Инет - при событии OnClick соответствующего контрола вызываешь ShellExecute (объявлена в ShellAPI.pas):

ShellExecute(Handle,nil,'http://www.yandex.ru',nil,nil,0);
Если хочешь защитить файл с вопросами от просмотра. то можешь его зашифровать, модуль для симметричного шифрования я могу подкинуть (если конечнто неохота разбираться с CryptoAPI). В принципе ещё есть вариант пихнуть этот файл в экзешник как ресурс, а сам экзешник запаковать какимнить пакером - например upx"ом.

Думаю, твою программу стоит в корне изменить. Предлагаю разделить функции таким образом:

function TForm1.LoadTest(const FileName: string): boolean;
begin
//загружает файл с тестом в память
// если ОК --> true
end;

procedure TForm1.SetAnswer;
begin
//считывает с контролов на форме
// результат и запоминает его
end;

procedure TForm1.NextAnswer;
begin
//показывает пользователю новый вопрос
end;

procedure TForm1.TerminateTest;
begin
//делает контролы на форме недостыепными
// (disabled)
// и показывает пользователью сообщение
// в духе "Вемя вышло - тест окончен"
end;


Автор: Atreides 4.03.2006 1:16

Цитата
Ссылку в Инет - при событии OnClick соответствующего контрола вызываешь ShellExecute (объявлена в ShellAPI.pas):

ShellExecute(Handle,nil,'http://www.yandex.ru',nil,nil,0);


А, где и как прописывать процедуру смены действия курсора на активную ссылку. Где находиться этот ShellExecute?

Автор: Noof 10.03.2006 0:33

Советую использовать не TTimer а WinApi'вский SetTimer.

Текст советую зашифровать простым способом. (таблички значении и тд ... как на первом курсе учат)

файл с ответами и тд можно закинуть прямо в прогу RES файлом. А потом еще и ЕХЕшник запаковать aspack'ом.
Или UPX'ом(тогда еще нужно будет хекс редактором подправить файл, что б потом тем же UPX не разархивировать).

фоновый рисунок можно кинуть на HDC и при прорисовке делать BeginPaint EndPAint...

И считывать файл лучше стримом а потом его в памяти уже разбирать.

Автор: Atreides 21.04.2006 0:34

Цитата
Ссылку в Инет - при событии OnClick соответствующего контрола вызываешь ShellExecute (объявлена в ShellAPI.pas):

ShellExecute(Handle,nil,'http://www.yandex.ru',nil,nil,0);

А если в качестве ссылки сделать баннер - картинку gif, то, как заставить её двигаться?

Автор: hardcase 21.04.2006 1:08

Цитата(Atreides @ 20.04.2006 21:34) *

А если в качестве ссылки сделать баннер - картинку gif, то, как заставить её двигаться?
С этим справлялся специальный класс для Gif картинок.
Честно скажу - с этой библиотечкой не разбирался - не было прецедента, но развёрнутый хэлп-файл там есть.


Прикрепленные файлы
Прикрепленный файл  gifimaged7c.zip ( 201.81 килобайт ) Кол-во скачиваний: 231