Лекция: PQuestion(QuestionList[QuestionTreeView.Selected.Index]).Name
Здесь я использую контейнер QuestionList. В квадратных скобках у него я указываю индекс элемента из контейнера, который мне нужен. Здесь я указываю индекс выделенного в дереве элемента QuestionTreeView.Selected.Index.
По нажатию кнопки «Удалить» ты должен написать следующий код:
procedure TQuestionResultForm.DeleteButtonClick(Sender: TObject); var index, i:Integer; begin if QuestionTreeView.Selected=nil then exit;
//Подтверждение удаления if Application.MessageBox(PChar('Вы действительно хотите удалить — '+ QuestionTreeView.Selected.Text), 'Внимание!!!', MB_OKCANCEL+MB_ICONINFORMATION)<>idOk then Exit;
//Сохраняю индекс выделенного элемента
index:=QuestionTreeView.Selected.Index;
//Удаляю выделенный элемент из дерева QuestionTreeView.Items.Delete(QuestionTreeView.Selected);
//Удаляю из контейнера QuestionList.Delete(Index); end;
На компакт диске, в директории\Примеры\Глава 25\Test2\Редакторты можешь увидеть исходник уже написанного примера.
25.4. Сохранение и загрузка теста.
воя программа уже умеет создавать тесты, пора бы её научить и сохранять их и тем более загружать потом созданные проекты для редактирования. Я вынес кнопки открытия и сохранения проекта из дочернего окна в основное. Если
честно, то сохранение легче сделать внутри дочернего окна, а открытие в главном. Но я не пошёл простым путём, потому что хочу тебе показать, как работать с дочерними окнами. Итак, по нажатию кнопки «Сохранить» проект пишем следующий код:
procedure TTestEditorForm.SaveButtonClick(Sender: TObject);
begin //Если актиыное дочернее окно равно нулю //(нет активных окон), то выход if ActiveMDIChild=nil then exit; //Если окно имеет имя QuestionResultForm, то это //вопрос-варианты ответов и вызываем для сохранения //процедуру SaveTest1. if ActiveMDIChild.Name='QuestionResultForm' then
SaveTest1; end;
Свойство ActiveMDIChild всегда указывает на активное в данный момент дочернее окно. Прежде чем использовать это свойство, его желательно сравнивать со значением nil, потому что в данный момент может вообще не быть ни одного дочернего окна. В этом случае, при обращении к свойству может произойти критическая ошибка.
Процедура SaveTest1 должна выглядеть следующим образом:
procedure TTestEditorForm.SaveTest1;
var fs:TFileStream; i:Integer; Str:String[5];
begin //Если у активного окна в свойстве FileName пусто, //то нет имени файла и нужно вызвать обработчик события //меню «Сохранить как...», чтобы появилось окно ввода //имени файла if TQuestionResultForm(ActiveMDIChild).FileName='' then
begin
SaveAsMenuClick(nil);
exit;
end;
//Создаю новый файл. Если он уже существовал, то его
//содержимое будет уничтожено
fs:=TFileStream.Create(TQuestionResultForm(ActiveMDIChild).FileName, fmCreate);
//Сохраняю в начале файла текст «Тест», чтобы по нему потом
//определить к чему относиться данный файл.
Str:='Тест';
fs.Write(Str, SizeOf(Str));
//Сохранить имя проекта fs.Write(TQuestionResultForm(ActiveMDIChild).ProjectName, sizeof(TQuestionResultForm(ActiveMDIChild).ProjectName));
try
//Сохранить количество вопросов
fs.Write(TQuestionResultForm(ActiveMDIChild).QuestionList.Count,
sizeof(TQuestionResultForm(ActiveMDIChild).QuestionList.Count));
//Запускаю цикл, в котором сохраняються все вопросы. for i:=0 to TQuestionResultForm(ActiveMDIChild).QuestionList.Count-1 do fs.Write(PQuestion(TQuestionResultForm(ActiveMDIChild).QuestionList[i])^, sizeof(TQuestion));
finally
//Закрыть файл
fs.Free;
end; end;
Здесь всё очень просто и с кодом можно разобраться по комментариям. Единственное, на что я хочу обратить внимание – наша структура PQuestion находится в динамической памяти, поэтому при сохранении нужно указывать знак разыменования ^. Если этого знака не указать, то в файл сохраниться адрес структуры, а не сама структура. В этом случае при чтении данных из файла мы прочитаем адрес, но по этому адресу ничего хорошего не будет, потому что после первой же перезагрузки программы память очиститься и сама структура уничтожиться. Поэтому, для сохранения данных по адресу, а не самого адресу нужно указывать знак ^.
Обработчик события для пункта меню «Сохранить как…» ещё проще: