Условие - Reshaem.Net

advertisement
Разработать локальную справочную информационную систему «МУЗЫКА» на основе БД jet
и исполнимого файла созданного в СИ ШАРП.
пользовательский интерфейс должен содержать:
1. оглавление справочной системы в виде дерева с раскрывающимися пунктами
2. контейнер с форматирующим текстом открывающихся по двойному щелчку на пункте
оглавления
3. контейнеры для изображений открывающиеся вместе с текстом
4. средства поиска :
 по оглавлению
 по тексту
 по ключевым словам
пользовательский режим должен переключаться в 2-х режимах
 режим редактирования(должна быть реализована возможность
добавления, удаления, изменения пунктов оглавления;
редактирование, форматирование текстов; вставка, удаление
изображений;)
 режим пользователя(доступ к пунктам оглавления, доступен только
просмотр)
КОММЕНТАРИИ К КОДУ!!
ПРИМЕР РАБОТЫ НА Delphi
Структура базы данных «Музыка»- основана на пяти связанных между собой таблицах.
Каждая таблица имеет определённое количество полей, в которых хранятся данные определённого
типа и определённой сущности. Таблицы нужны для того, чтобы хранить в них данные. Они
являются основным источником информации. Схема данных показана на рис.1.
Рисунок 1 – Схема данных
Как видно из рисунка я создал отдельную таблицу музыка, где будет храниться вся
информация о музыке, отдельную таблицу для стран и жанров.
Далее необходимо спроектировать данные таблицы
Таблица 1 – Таблица «Countries»
Название поля
key
country
Countries
Тип данных
счетчик
текстовый
Правило целостности
Primary key not null
Not null
Directors
Тип данных
счетчик
текстовый
Правило целостности
Primary key not null
Not null
Genres
Тип данных
счетчик
текстовый
Правило целостности
Primarykeynotnull
Not null
Таблица 2 – Таблица «Directors»
Название поля
key
director
Таблица 3 – Таблица «Genres»
Название поля
key
genre
Таблица 4 – Таблица «music»
Название поля
key
tree_node
name
country
director
genre
annotation
image
music
Тип данных
счетчик
числовой
текстовый
числовой
числовой
числовой
Поле объекта OLE
Поле объекта OLE
Правило целостности
Primary key not null
Factory key not null
Not null
Factory key not null
Factory key not null
Factory key not null
Not null
Not null
Structure
Тип данных
счетчик
числовой
текстовый
Правило целостности
Primarykeynotnull
Factory key not null
Not null
Таблица 5 – Таблица «Structure»
Название поля
key
parent_node
name
2 Разработка клиентской части
2.1 Установка соединения с Базой данных
В данном проекте клиентская часть разрабатывается в среде Delphi. При создании нового
проекта необходимо создать новый DataModule. На который первым делом помещается компонент
ADOConnection, который служит для связи с базой данных. В разрабатываемом клиенте
используется один компонент ADOConnection с именем ADOConnection1. Далее производим его
настройку и соединение с базой данных: Дважды щелкаем по компоненту ADOConnection1, в
появившемся окне (рисунок 1) нажимаем “Build”.
Рисунок - Окно создания подключения к базе
Далее во вкладке “Поставщик данных”, выбрать подключаемые данные: Microsoft Jet 4.0
OLE DB Provider (рисунок 2), затем на вкладке “Подключение” указываем путь к базе данных в
формате “.mdb”, при необходимости ввести имя пользователя и пароль (рисунок 3). И не забудьте
проверить соединение с базой данных для корректной работы программы.
Рисунок - Окно создания строки подключения
Рисунок - Закладка подключение
Далее располагаем девять, по числу таблиц нашей базы данных, компонентов ADOTable.
Каждому из компонентов в свойстве Connection присваиваем соединение с компонентом
ADOConnection1, в свойстве TableName выбираем соответствующую таблицу и базы данных, в
свойстве Name присваиваем значение имя таблицы. Далее для каждого компонента ADOTable
добавляем компонент TDataSource (компонент нужный для установления связи между
компонентами доступа к данным и визуальными компонентами для представления данных
пользователю), которые в сою очередь через свойство DataSet связываем с компонентами
ADOTable. После проделанных операций необходимо добавить компонент ADOQuery, который
реализует данные, источником которых является одна или несколько таблиц базы данных. Состав
и структура получаемых данных определяется запросом SQL (SELECT). Кроме формирования
набора данных, используется для выполнения любых действий, предусмотренных реализацией
SQL для той СУБД, с которой работает ADOQuery. Свойству Connection данного компонента
присваиваем так же значение ADOConnectin1, а в свойстве SQL задаем запрос. После чего для
данного компонента добавляем еще один компонент TDataSource, для которого свойству DataSet
присваиваем значение соответствующего запроса.
На данном этапе так же необходимо определить какие таблицы можно будет изменять, а
какие нет. Для этого свойству ReadOnly необходимо задать значение True если таблицу
редактировать нельзя, и False если редактировать можно.
Таким образом, созданный нами DataModule1 будет выглядеть следующим образом:
Рисунок - DataModule1
2.2 Создание клиентской части
2.2.1 Разработка форм
Главная форма предназначена для основной работы со справочно-информационной
системой «Музыка» (рисунок 5)
Рисунок - Главная форма
На данной форме можно просматривать список музыки, который есть в базе данных,
осуществлять поиск (рисунок 6), редактировать информацию о музыких (рисунок 7),
осуществлять сортировку по категориям, жанру, режиссеру, стране (рисунок 8), добавлять новый
альбом (рисунок 9), удалять его (рисунок 10).
Рисунок – Поиск музыки
Рисунок – Редактирование музыки
Рисунок – Сортировка
музыки
Рисунок – Создание музыки
Рисунок – Удаление музыки
Приложение А листинг программы
unit MainUnit;
private
{ Private declarations }
public
{ Public declarations }
procedure FillNodes; //Построение TreeView
procedure EditKeyWords; //Редактирование ключквых слов
procedure Editing(Param: Boolean); //Набор переключаемых параметров
end;
var
MainForm: TMainForm;
SPos: Integer; //Позиция курсора при поиске
vCurrentTable: TADOTable; //Текущая таблица
vCurrentSource: TDataSource; //Текущий источник данных
vParentNode: TTreeNode; //Родительский узел
vFindFlag: Boolean; //Флаг поиска (активен/неактивен)
vSearchStr: String; //Поисковая строка
vKey: Integer; //Значение ключевого поля для сортировки
implementation
uses DataUnit, ViewUnit, EditUnit;
{$R *.dfm}
//Жирный шрифт
procedure TMainForm.aBoldExecute(Sender: TObject);
begin
if aBold.Checked then RichEdit1.SelAttributes.Style :=
RichEdit1.SelAttributes.Style + [fsBold]
else RichEdit1.SelAttributes.Style :=
RichEdit1.SelAttributes.Style - [fsBold];
end;
//Отмена редактирования/создания
procedure TMainForm.aCancelExecute(Sender: TObject);
begin
DataModule1.musicTable.Cancel;
Editing(false);
RichEdit1.Lines.Assign(DataModule1.musicTable.FieldByName('annotation'));
Image1.Picture.Assign(DataModule1.musicTable.FieldByName('image'));
end;
//Очистить RichEdit
procedure TMainForm.aClearExecute(Sender: TObject);
begin
RichEdit1.Lines.Clear;
end;
//Очистить строку поиска и сбросить флаг
procedure TMainForm.aClearSearchExecute(Sender: TObject);
begin
FindEdit.Clear;
vFindFlag := false;
FillNodes;
end;
//Копировать в буфер обмена
procedure TMainForm.aCopyExecute(Sender: TObject);
begin
RichEdit1.CopyToClipboard;
end;
//Вырезать
procedure TMainForm.aCutExecute(Sender: TObject);
begin
RichEdit1.CutToClipboard;
end;
//Удаление пункта
procedure TMainForm.aDeleteNodeExecute(Sender: TObject);
var
i, vBuf: Integer;
begin
//Если пунктов нет, то выходим из процедуры
if DataModule1.StructureTable.RecordCount = 0 then exit;
//Если есть потомки, то выводим сообщение и выходим
if TreeView1.Selected.HasChildren then begin
MessageBox(Handle, PChar('Сначала удалите дочерние узлы'),
PChar('Внимание!'), MB_ICONINFORMATION + MB_OK) + IDOK;
exit;
end;
//Если выбрали отмену удаления, то выходим
if (MessageBox(Handle, PChar('Удалить выбранный пункт?'),
PChar('Удаление пункта'), MB_ICONINFORMATION +
MB_OKCANCEL + MB_DEFBUTTON2) = IDCANCEL)
then exit
//иначе находим в таблице строку, соответствующую выбранному
//пункту, удаляем ее и обновляем дерево
else begin
with DataModule1.StructureTable do begin
Locate('key', Integer(TreeView1.Selected.Data), [loCaseInsensitive]);
vBuf := FieldByName('parent_node').AsInteger;
Delete;
end;
FillNodes;
end;
//После удаления ищем родителя удаленного пункта, выделяем его и
//раскрываем список оставшихся потомков этого родителя
for i := 0 to TreeView1.Items.Count - 1 do
if Integer(TreeView1.Items[i].Data) = vBuf then begin
TreeView1.Selected := TreeView1.Items[i];
TreeView1.Items[i].MakeVisible;
TreeView1.Items[i].Expand(false);
end;
//Очищаем RichEdit и Image
RichEdit1.Lines.Clear;
aDelImageExecute(Sender);
ImagePanel.Visible := false;
end;
//Удалить изображение
procedure TMainForm.aDelImageExecute(Sender: TObject);
begin
Image1.Picture.Bitmap.Assign(nil);
end;
//Редактировать
procedure TMainForm.aEditExecute(Sender: TObject);
begin
//Находим в таблице строку, соответствующую выбранному
//пункту, и включаем режим редактирования
with DataModule1.musicTable do begin
Locate('tree_node', Integer(TreeView1.Selected.Data), [loCaseInsensitive]);
Edit;
end;
Editing(true);
end;
//Закрыть программу
procedure TMainForm.aExitExecute(Sender: TObject);
begin
MainForm.Close;
end;
//Поиск по тексту
procedure TMainForm.aFindTextExecute(Sender: TObject);
begin
//Запоминаем позицию курсора
SPos := RichEdit1.SelStart;
with FindDialog1 do
begin
//Начальное значение - выделенный текст
FindText := RichEdit1.SelText;
Execute;
end;
end;
//Выбор шрифта
procedure TMainForm.aFontExecute(Sender: TObject);
begin
if FontDialog1.Execute then
RichEdit1.SelAttributes.Assign(FontDialog1.Font);
RichEdit1.SetFocus;
end;
//Курсив
procedure TMainForm.aItalicExecute(Sender: TObject);
begin
if aItalic.Checked then RichEdit1.SelAttributes.Style :=
RichEdit1.SelAttributes.Style + [fsItalic]
else RichEdit1.SelAttributes.Style :=
RichEdit1.SelAttributes.Style - [fsItalic];
end;
//Загрузка картинки
procedure TMainForm.aLoadImageExecute(Sender: TObject);
var
JpegIm: TJpegImage;
BmpIm: TBitMap;
begin
OpenDialog1.Filter:='*.bmp, *.jpg, *. jpeg|*.bmp; *.jpg; *.jpeg';
if not OpenDialog1.Execute then exit;
BmpIm := TBitMap.Create;
//Если открываемая картинка имеет расширение *.bmp,
//то загружаем ее в Image
if ExtractFileExt(OpenDialog1.FileName) = '.bmp' then
Image1.Picture.LoadFromFile(OpenDialog1.FileName)
//Если картинка формата jpeg, то сначала преобразуем ее в bmp,
//а потом загружаем в Image
else begin
JpegIm := TJpegImage.Create;
JpegIm.LoadFromFile(OpenDialog1.FileName);
BmpIm.Assign(JpegIm);
Image1.Picture.Assign(BmpIm);
JpegIm.Destroy;
end;
BmpIm.Destroy;
end;
//Создать
procedure TMainForm.aNewExecute(Sender: TObject);
begin
//Если TreeView не содержит пунктов или имя пункта - пустая строка,
//то напоминаем о необходимости создать/переименовать пункт перед
//созданием записи в БД
if TreeView1.Selected.Text = '' then begin
MessageBox(Handle, PChar('Необходимо создать новый пункт'),
PChar('Внимание!'), MB_ICONINFORMATION + MB_OK) + IDOK;
exit;
end;
DataModule1.musicTable.Insert;
Editing(true);
aDelImageExecute(Sender);
end;
//Создание нового пункта
procedure TMainForm.aNewNodeExecute(Sender: TObject);
var
nnName: String;
i: Integer;
begin
//Если нажали отмену, то выходим
if not InputQuery('Создание пункта', 'Введите заголовок', nnName) then
exit
//иначе заносим пункт в БД и обновляем дерево
else begin
with DataModule1.StructureTable do begin
Insert;
FieldByName('parent_node').AsInteger := Integer(TreeView1.Selected.Data);
FieldByName('name').AsString := nnName;
Post;
end;
FillNodes;
end;
//Разворачиваем дерево до созданного пункта и делаем выделяем этот пункт
for i := 0 to TreeView1.Items.Count - 1 do
if TreeView1.Items[i].Text = nnName then begin
TreeView1.Selected := TreeView1.Items[i];
TreeView1.Items[i].MakeVisible;
end;
end;
//Загрузка текста из файла
procedure TMainForm.aOpenFileExecute(Sender: TObject);
begin
OpenDialog1.Filter:='Текстовые файлы|*.rtf; *.doc; *.txt';
if OpenDialog1.Execute then begin
RichEdit1.Lines.LoadFromFile(OpenDialog1.FileName);
end;
end;
//Вставить
procedure TMainForm.aPasteExecute(Sender: TObject);
begin
RichEdit1.PasteFromClipboard;
end;
//Переименование пункта
procedure TMainForm.aRenameNodeExecute(Sender: TObject);
var
rnName: String;
begin
//Если нажали отмену, то выходим
if not InputQuery('Переименование', 'Введите новое имя', rnName) then
exit
//иначе ищем пункт в БД, переименовываем его и обновляем дерево
else begin
with DataModule1.StructureTable do begin
Locate('key', Integer(TreeView1.Selected.Data), [loCaseInsensitive]);
Edit;
FieldByName('name').AsString := rnName;
Post;
end;
FillNodes;
end;
end;
//Сохранение в таблице music
procedure TMainForm.aSaveExecute(Sender: TObject);
var
i, vBuf: Integer;
begin
if (CountryList.Text = '') or (GenreList.Text = '') or
(DirectorList.Text = '') then begin
MessageBox(Handle, PChar('Необходимо заполнить все поля'),
PChar('Внимание!'), MB_ICONINFORMATION + MB_OK) ;
exit;
end;
with DataModule1.musicTable do begin
if Modified or RichEdit1.Modified then begin
FieldByName('name').AsString := TreeView1.Selected.Text;
FieldByName('tree_node').AsInteger := Integer(TreeView1.Selected.Data);
FieldByName('annotation').Assign(RichEdit1.Lines);
FieldByName('image').Assign(Image1.Picture);
vBuf := FieldByName('tree_node').AsInteger;
end;
Post;
end;
aCancelExecute(Sender);
ImagePanel.Visible := true;
for i := 0 to TreeView1.Items.Count - 1 do
if Integer(TreeView1.Items[i].Data) = vBuf then begin
TreeView1.Items[i].Selected := true;
TreeView1.Items[i].MakeVisible;
end;
end;
//Выделить все
procedure TMainForm.aSelectAllExecute(Sender: TObject);
begin
RichEdit1.SetFocus;
RichEdit1.SelectAll;
end;
//Включение сортировки
procedure TMainForm.aSortExecute(Sender: TObject);
begin
//Используем ту же форму, что и для редактирования ключевых слов
with EditForm do begin
DBGrid1.DataSource := vCurrentSource;
Caption := vCurrentTable.Fields.Fields[1].DisplayLabel;
//Отключая ненужные кнопки
InsertBtn.Visible := false;
DeleteBtn.Visible := false;
ShowModal;
end;
end;
//Подчеркнутый
procedure TMainForm.aUnderlineExecute(Sender: TObject);
begin
if aUnderline.Checked then RichEdit1.SelAttributes.Style :=
RichEdit1.SelAttributes.Style + [fsUnderline]
else RichEdit1.SelAttributes.Style :=
RichEdit1.SelAttributes.Style - [fsUnderline];
end;
//Применение параметров при редактировании/просмотре
procedure TMainForm.Editing(Param: Boolean);
begin
aOpenFile.Enabled := Param;
aSave.Enabled := Param;
aLoadImage.Enabled := Param;
RichEdit1.ReadOnly := not Param;
ImagePanel.Visible := Param;
aCut.Enabled := Param;
aPaste.Enabled := Param;
aClear.Enabled := Param;
aFindText.Enabled := Param;
EditPanel.Visible := Param;
aDelImage.Enabled := Param;
end;
//Вызов окна ключевых слов
procedure TMainForm.EditKeyWords;
begin
with EditForm do begin
DBGrid1.DataSource := vCurrentSource;
Caption := vCurrentTable.Fields.Fields[1].DisplayLabel;
ShowModal;
end;
end;
//Строим TreeView при появлении главной формы
procedure TMainForm.FormShow(Sender: TObject);
begin
FillNodes;
RichEdit1.SelAttributes.Assign(RichEdit1.DefAttributes);
end;
//Открытие изображение для просмотра в оригинальном разрешении
procedure TMainForm.Image1DblClick(Sender: TObject);
begin
//Если Image пуст, то выходим
if Image1.Picture.Bitmap.Empty then exit;
//иначе создаем форму для просмотра и загружаем в нее изображение
//в натуральную величину
ViewForm := TViewForm.Create(MainForm);
with ViewForm do begin
ViewImage.Picture.Assign(Image1.Picture);
Position := poMainFormCenter;
ShowModal;
end;
end;
//Панель "Правка"
procedure TMainForm.N16Click(Sender: TObject);
begin
if N16.Checked then ToolBar2.Visible := true
else ToolBar1.Visible := false;
end;
//Панель "Формат"
procedure TMainForm.N17Click(Sender: TObject);
begin
if N17.Checked then ToolBar3.Visible := true
else ToolBar1.Visible := false;
end;
procedure TMainForm.N31Click(Sender: TObject);
begin
end;
//Режим сортировки по категориям (полное дерево)
procedure TMainForm.MMCategorySortClick(Sender: TObject);
begin
//Отмечаем пункт меню галкой
MMCategorySort.Checked := true;
//Очищаем строку поиска и сбрасываем флаг
FindEdit.Clear;
vFindFlag := false;
FillNodes;
aNewNode.Enabled := true;
end;
//Выбор источника данных и таблицы (страны)
procedure TMainForm.MMCountryClick(Sender: TObject);
begin
vCurrentTable := DataModule1.CountryTable;
vCurrentSource := DataModule1.CountrySource;
EditKeyWords;
end;
//Сортировка по стране
procedure TMainForm.MMCountrySortClick(Sender: TObject);
begin
MMCountrySort.Checked := true;
FindEdit.Clear;
vFindFlag := false;
vCurrentTable := DataModule1.CountryTable;
vCurrentSource := DataModule1.CountrySource;
aSortExecute(Sender);
FillNodes;
aNewNode.Enabled := false;
end;
//Выбор источника данных и таблицы (режиссеры)
procedure TMainForm.MMDirectorsClick(Sender: TObject);
begin
vCurrentTable := DataModule1.DirectorTable;
vCurrentSource := DataModule1.DirectorSource;
EditKeyWords;
end;
//Сортировка по режиссеру
procedure TMainForm.MMDirectorSortClick(Sender: TObject);
begin
MMDirectorSort.Checked := true;
FindEdit.Clear;
vFindFlag := false;
vCurrentTable := DataModule1.DirectorTable;
vCurrentSource := DataModule1.DirectorSource;
aSortExecute(Sender);
FillNodes;
aNewNode.Enabled := false;
end;
//Выбор источника данных и таблицы (жанры)
procedure TMainForm.MMGenreClick(Sender: TObject);
begin
vCurrentTable := DataModule1.GenreTable;
vCurrentSource := DataModule1.GenreSource;
EditKeyWords;
end;
//Сортировка по жанру
procedure TMainForm.MMGenreSortClick(Sender: TObject);
begin
MMGenreSort.Checked := true;
FindEdit.Clear;
vFindFlag := false;
vCurrentTable := DataModule1.GenreTable;
vCurrentSource := DataModule1.GenreSource;
aSortExecute(Sender);
FillNodes;
aNewNode.Enabled := false;
end;
//Панель "Стандартная"
procedure TMainForm.N5Click(Sender: TObject);
begin
if N5.Checked then ToolBar1.Visible := true
else ToolBar1.Visible := false;
end;
//Процедура построения структуры дерева
procedure TMainForm.FillNodes;
var
i: integer;
vTable: TADOTable;
vQuery: TADOQuery;
vQueryString: String;
begin
vTable := DataModule1.StructureTable;
vQuery := DataModule1.SortQuery;
vTable.First;
TreeView1.Items.Clear;
//Создаем корневой пункт
vParentNode := TreeView1.Items.AddObject(nil,
vTable.FieldByName('name').AsString,
Pointer(vTable.FieldByName('key').asInteger));
vTable.Next;
//Если выбран режим сортировки "по категориям", то
//строим полное дерево
if (MMCategorySort.Checked) and (not vFindFlag) then begin
//Проходим по всей таблице
while not vTable.Eof do begin
i := 0;
//Пока i меньше числа пунктов TreeView
while i < TreeView1.Items.Count do
//ищем потомка i-го узла
if TreeView1.Items.Item[i].Data =
Pointer(vTable.FieldByName('parent_node').asInteger)
then
//и, найдя его, добавляем в TreeView
begin
TreeView1.Items.AddChildObject(TreeView1.Items.Item[i],
vTable.FieldByName('name').AsString,
Pointer(vTable.FieldByName('key').asInteger));
//Если потомков больше нет, то прерываем цикл и переходим
//к следующему узлу
break;
end
else
Inc(i);
vTable.Next;
end;
//Если выбран другой режим сортировки, то:
end
else begin
//Смотрим какой пункт меню выбран (и активен ли поиск по строке)
//и в соответствии с ним присваиваем значение переменной vQueryString
if MMCountrySort.Checked and not vFindFlag then vQueryString :=
'SELECT *' +
'FROM music ' +
'WHERE country=' + IntToStr(vKey);
if MMGenreSort.Checked then vQueryString :=
'SELECT *' +
'FROM music ' +
'WHERE genre=' + IntToStr(vKey);
if MMDirectorSort.Checked then vQueryString :=
'SELECT *' +
'FROM music ' +
'WHERE director=' + IntToStr(vKey);
if vFindFlag and MMCategorySort.Checked then vQueryString :=
'SELECT *' +
'FROM music ' +
'WHERE name LIKE ' + '''' + vSearchStr + '''';
if vFindFlag and MMCountrySort.Checked then vQueryString :=
'SELECT *' +
'FROM music ' +
'WHERE name LIKE ' + '''' + vSearchStr + '''' + 'AND country=' +
IntToStr(vKey);
if vFindFlag and MMGenreSort.Checked then vQueryString :=
'SELECT *' +
'FROM music ' +
'WHERE name LIKE ' + '''' + vSearchStr + '''' + 'AND genre=' +
IntToStr(vKey);
if vFindFlag and MMDirectorSort.Checked then vQueryString :=
'SELECT *' +
'FROM music ' +
'WHERE name LIKE ' + '''' + vSearchStr + '''' + 'AND director=' +
IntToStr(vKey);
//Выполняем запрос
vQuery.Active := false;
vQuery.SQL.Text := vQueryString;
vQuery.Active := true;
vQuery.First;
//и строим дерево, удовлетворяющее условиям
while not vQuery.Eof do begin
TreeView1.Items.AddChildObject(vParentNode,
vQuery.FieldByName('name').AsString,
Pointer(vQuery.FieldByName('tree_node').asInteger));
vQuery.Next;
end;
end;
//Корневой пункт всегда развернут
TreeView1.Items.Item[0].Expand(false);
end;
//Поиск по тексту
procedure TMainForm.FindDialog1Find(Sender: TObject);
begin
with FindDialog1 do
begin
if frMatchCase in Options
//Поиск с учетом регистра
then RichEdit1.SelStart := Pos(FindText,
Copy(RichEdit1.Lines.Text, SPos + 1,
Length(RichEdit1.Lines.Text))) + SPos - 1
//Поиск без учета регистра
else RichEdit1.SelStart := Pos(AnsiLowerCase(FindText),
AnsiLowerCase(Copy(RichEdit1.Lines.Text, SPos + 1,
Length(RichEdit1.Lines.Text)))) + SPos - 1;
if RichEdit1.SelStart >= SPos then begin
//Выделение найденного текста
RichEdit1.SelLength := Length(FindText);
//Изменение начальной позиции поиска
SPos := RichEdit1.SelStart + RichEdit1.SelLength + 1;
end
else
MessageBox(Handle, PChar('Текст "' + FindText + '" не найден.'),
PChar('Внимание!'), MB_ICONINFORMATION );
end;
RichEdit1.SetFocus;
end;
//Строка поиска
procedure TMainForm.FindEditChange(Sender: TObject);
begin
vSearchStr := '%' + FindEdit.Text + '%';
if FindEdit.Text <> '' then vFindFlag := true
else vFindFlag := false;
FillNodes;
end;
//Выбор пункта TreeView
procedure TMainForm.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
aCancelExecute(Sender);
with DataModule1.musicTable do begin
//При выделении пункта ицем связанную с ним запись в БД и,
//если она существует, загружаем ее
if Locate('tree_node', Integer(TreeView1.Selected.Data),
[loCaseInsensitive])
then begin
aEdit.Enabled := true;
RichEdit1.Lines.Assign(FieldByName('annotation'));
Image1.Picture.Assign(FieldByName('image'));
ImagePanel.Visible := true;
aFindText.Enabled := true;
end
//иначе очищаем RichEdit и Image от результатов предыдущего запроса
else begin
aEdit.Enabled := false;
RichEdit1.Lines.Clear;
aDelImageExecute(Sender);
ImagePanel.Visible := false;
end;
end;
end;
//Редактирование по двойному клику
procedure TMainForm.TreeView1DblClick(Sender: TObject);
begin
if TreeView1.Selected.HasChildren then exit;
if DataModule1.musicTable.Locate('tree_node',
Integer(TreeView1.Selected.Data), [loCaseInsensitive]) then
aEditExecute(Sender)
else aNewExecute(Sender);
end;
end.
Download