---- 1. Советы по использованию элементов управления деревом в Delphi
---- Мы все знаем, что разработчики в основном используют Delphi для разработки программного обеспечения для управления базами данных. Поэтому использование элементов управления деревом лучше всего связано с базой данных. Delphi предоставляет элемент управления деревом TTreeView, который можно использовать для описания сложных иерархических отношений.
---- 1. Хранение и загрузка информации об узлах дерева.
---- Обычно используемые методы — использовать методы LoadFromFile и SavetoFile элемента управления «дерево» для реализации взаимодействия между элементом управления «дерево» и файлом или использовать метод Assign для реализации взаимодействия между элементом управления «дерево» и DBMemo; , взаимодействие с базой данных. Преимущество этого метода в относительной простоте программирования. Недостаток в том, что фактическое количество узлов управления деревом может быть очень большим. Для «больших деревьев» каждый раз будет увеличиваться объем загружаемых и сохраняемых данных. снизить скорость, увеличить нагрузку на систему и вызвать избыточность данных. Другой метод заключается в создании только «видимых» узлов в дереве. Не существует поля файла или базы данных, предназначенного для записи всей структуры узлов дерева, и структура узлов дерева рассредоточена в каждой записи базы данных.
---- Конкретный метод: создать базу данных, поля определяются в соответствии с фактическим бизнесом, должно быть одно поле, информация о котором будет отображаться в узле элемента управления деревом, а также есть поле для сохранения уникальный идентификационный номер узла.Идентификационный номер состоит из двух частей одинаковой длины.Первая часть представляет номер родительского узла текущего узла, а вторая часть представляет собой номер текущего узла. «связанный список», в котором записана структура узлов дерева. Преимущества этого метода: Когда пользователи управляют «большим деревом», они, как правило, не расширяют все узлы, а используют только ограниченную часть. При этом они могут расширять только слой за слоем от корня дерева. Метод генерирует только "" на дереве. "Видимые" узлы, поэтому скорость хранения и загрузки "больших деревьев" высокая, объем данных невелик, а накладные расходы системы и избыточность данных невелики. Недостатки: программирование более сложное, но этот метод можно объединить для формирования нового элемента управления деревом, что значительно повысит эффективность программирования. Стоит отметить, что идентификационный номер должен быть уникальным, поэтому особенно важно правильно сгенерировать идентификатор в программировании.
---- 2. Пример структуры базы данных
----Создание базы данных. Чтобы упростить процедуру, я создаю только два поля базы данных, определенные следующим образом:
Длина типа имени поля
ТекстC10
ЛонгИДК6
----Поле LongID фактически состоит из двух сегментов, каждый из которых состоит из 3 цифр. LongID может представлять только 1000 записей. Определите LongID как поле индекса и сохраните его как c: esttree ree.dbf. Отредактируйте файл DBF, создайте новую запись, установите для поля «Текст» значение TOP и установите для поля LongID значение «000» (три пробела перед тремя «0»).
---- 3. Создайте демонстрационную программу
---- Поместите TreeView1, Table1, PopupMenu1, Edit1 и Edit2 в Form1. Атрибуту PopupMenu элемента TreeView1 присвоено значение PopupMenu1; атрибуту DataBaseName объекта Table1 присвоено значение c:esttree, атрибуту TableName присвоено значение Tree.dbf, а атрибуту IndexFieldNames присвоено значение LongID; добавьте отдельные элементы Add1 и Del1 в PopupMenu1, и Caption — это Add и Del соответственно; Edit1 использует для ввода значения атрибута Text нового узла Edit2 используется для ввода трехзначного идентификационного номера нового узла. Сохраните как c:esttree reeunit.pas и c:esttree esttree.dPR. Добавьте строку после ключевого слова Type в Treeunit.pas: Pstr:^string;{Pstr — указатель на строку} Добавьте код для события OnCreate формы Form1:
процедура TForm1.FormCreate(Отправитель: TObject);
вар р: Pstr; Узел: TTreeNode;
начинать
с Table1, Treeview1 сделать
начинать
открыть;
первый;
new(p);{Выделить память для указателя p}
p^:=FieldByName('LongID').AsString;
Узел:=Items.AddChildObject(nil,FieldByName
('Текст').AsString,p);
если HasSubInDbf(Node), то элементы
.AddChildObject(Node,′ ′,nil);{Если есть дочерний узел, добавьте пустой дочерний узел}
конец;
конец;
---- HasSubInDbf — это пользовательская функция, независимая переменная — Node, проверьте, есть ли у узла Node дочерние узлы, верните True, если они есть, в противном случае верните False и добавьте объявление прототипа в определение класса TForm1 (прототипы другие пользовательские функции также объявлены в определении класса TForm1 без дальнейших пояснений), код функции следующий:
функция TForm1.HasSubInDbf(Node:TTreeNode):Boolean;
начинать
с Таблицей1 сделать
начинать
Table1.FindNearest([copy(Pstr(Node.Data)^,4,3)+’000’]);
результат:=copy(FieldByName('LongID').
AsString,1,3)=copy(Pstr(Node.Data)^,4,3);
{Например, сумма первых трех цифр содержимого поля LongID текущей записи в базе данных.
Если последние три цифры Данных узла Node совпадают, то у узла должны быть дочерние узлы}
конец;
конец;
Добавьте код для события OnDeletion элемента управления TreeView1. Следует отметить, что:
Событие OnDeletion может быть вызвано не только вызовом метода Delete, но и до освобождения самого элемента управления деревом.
Событие OnDeletion также запускается, поэтому «безопасно» добавить сюда Release(node.data):
процедура TForm1.TreeView1Deletion
(Отправитель: TObject; Узел: TTreeNode);
начинать
Dispose(Node.Data);{Освободить память данных узла}
конец;
Добавьте следующий код в событие OnClick пункта меню Add1:
процедура TForm1.Add1Click(Отправитель: TObject);
вар р: pstr; Tmpstr: строка; я: целое число;
начинать
пытаться
StrToInt(Редактировать2.Текст);
Tmpstr:=Edit2.Text;{Примечание: на практике для генерации идентификатора необходимо использовать лучший метод}
кроме;
ShowMessage('Повторно введите содержимое Edit2');
прерывание;
конец;
с TreeView1 сделать
начинать
новый (р);
p^:=copy(Pstr(Selected.Data)^,4,3)+TmpStr;
Items.AddChildObject(Selected,Edit1.Text,p);
конец;
с Таблицей 1 делаем {Добавить запись в базу данных}
начинать
Добавить;
FieldByName('Text').AsString:=Edit1.text;
FieldByName('LongID').AsString:=p^;
Почта;
конец;
TmpStr:=inttostr(strtoint(TmpStr)+1);
для i:=length(TmpStr) до 2 do TmpStr:='0'+TmpStr;
Edit2.Text:=TmpStr;
конец;
Добавьте следующий код в событие OnClick пункта меню Del1:
процедура TForm1.Del1Click(Отправитель: TObject);
вар DelList: TStringList; LongID, NSubLongID: строка;
начинать
DelList:=TStringList.create;
DelList.Sorted:=Истина;
DelList.Add(Pstr(TreeView1.Selected.Data)^);
в то время как DelList.Count>0 делать
начинать
LongID:=DelList.Strings[0];
ДелЛист.Удалить(0);
Таблица1.SetKey;
Table1.FieldByName('LongID').AsString:=LongID;
если Table1.GotoKey, то Table1.Delete;
если HasSubInDbf(TreeView1.Selected), то
начинать
NSubLongID:=Table1.FieldByName('LongID').AsString;
в то время как (копия(NSubLongID,1,3)=копировать
(LongID,4,3)) и (не Table1.Eof) делают
начинать
dellist.Add(NSubLongId);
Таблица1.Следующая;
NSubLongId:=Table1.FieldByName('LongID').AsString;
конец;
конец;
конец;
ДелЛист.Бесплатно;
TreeView1.Items.Delete(TreeView1.Selected);
конец;
Добавьте код для события OnExpanding TreeView1:
процедура TForm1.TreeView1Expanding
(Отправитель: TObject; Узел: TTreeNode;
var AllowExpansion: Boolean);
вар TmpNode:TTreeNode;NSubLongID:
Строка;p:Pstr;bm:TBookMark;
начинать
с Table1, TreeView1 сделать
начинать
Items.BeginUpdate;
УстановитьКей;
FieldByName('LongID').AsString:=Pstr(Node.Data)^;
если не GotoKey, то Items.Delete(Node)
еще
начинать
TmpNode:=Node.GetFirstChild;
если (TmpNode.Text=′ ′) и (TmpNode.Data=nil), то
начинать
ТмпНоде.Удалить;
если HasSubInDbf(Узел), то
начинать
NSubLongID:=FieldByName('LongID').AsString;
while (copy(NSubLongID,1,3)=copy(Pstr
(Node.Data)^,4,3)) и (не Eof) делают
начинать
новый (р);
p^:=FieldByName('LongID').AsString;
бм: = GetBookMark;
TmpNode:=Items.AddChildObject(Node,
FieldByName('Текст').AsString,p);
если HasSubInDbf(TmpNode), то Items.
AddChildObject(TmpNode, '', ноль);
GotoBookMark(бм);
FreeBookMark(бм);
Следующий;
NSubLongId:=FieldByName('LongID').AsString;
конец; конец;
конец;
Предметы.EndUpdate;
конец;
конец;
---- Выше кратко рассказывается об основном методе отображения дерева базы данных. Кроме того, при редактировании атрибута «Текст» узла в дереве база данных одновременно модифицируется, когда одна и та же база данных используется. несколько пользователей одновременно, согласованность базы данных и дерева, а также дерева. Копирование и репликация верхнего узла не будут подробно описываться, и читатели могут улучшить его самостоятельно.
---- 2. Использование IP-контроля
---- В сетевых программах мы часто сталкиваемся с ситуациями, когда от пользователей требуется ввод IP-адресов. Однако Delphi не предоставляет нам элемента управления, который можно использовать для ввода строки IP, поэтому нам приходится использовать элемент управления Tedit (однострочное текстовое поле), чтобы принять строку IP, введенную пользователем. Однако использовать Tedit для ввода строки IP — не очень хорошая идея, поскольку с ней очень неудобно обращаться. На самом деле рядом с нами есть элемент управления Windows специально для ввода IP-строк. Элемент управления IP будет отклонять недопустимые строки IP (в каждую часть можно вводить только числа от 0 до 255). Это позволяет легко получить значение IP (32-битное целое число), соответствующее строке IP в элементе управления This This. избавляет вас от необходимости конвертировать строки IP в значения IP, кроме того, вы также можете ограничить диапазон IP-адресов, которые можно ввести в элемент управления IP; В этом разделе рассказывается, как использовать элементы управления Windows IP в нашей программе Delphi.
---- В Windows есть две очень важные библиотеки динамической компоновки: commctrl.dll и comctl32.dll, которые являются пользовательскими библиотеками элементов управления Windows (общие элементы управления Windows). Библиотека настраиваемых элементов управления содержит множество часто используемых элементов управления Windows, таких как Statusbar, Coolbar, HotKey и т. д. в Delphi, большинство этих элементов управления упакованы как визуальные элементы управления. После того, как Microsoft выпустила Internet Explorer 3, в библиотеку настраиваемых элементов управления были добавлены некоторые новые элементы управления, включая элемент управления Windows IP (элемент управления редактированием IP-адреса).
---- 1. Инициализируйте библиотеку пользовательского управления Windows.
---- Windows предоставляет две функции API, InitCommonControls и InitCommonControlsEx, для инициализации пользовательских библиотек элементов управления. Из названий нетрудно увидеть связь между этими двумя функциями API: последняя является развитием первой. Если вы хотите использовать элементы управления IP в своей программе, вы должны использовать InitCommonControlsEx для завершения инициализации пользовательских библиотек и классов элементов управления. Прототип функции InitCommonControlsEx следующий (синтаксис Pascal):
... ...
Создать IP-контроль
... ...
Используйте IP-управление. В программе мы общаемся с IP-контролем, отправляя ему сообщения.
IP-управление может реагировать на следующие шесть сообщений. Эти сообщения и их значения показаны в таблице ниже:
... ...
Если вы хотите получить значение IP, соответствующее строке IP в элементе управления IP, вам следует отправить
сообщение IPM_GETADDRESS и требует 32-битного целочисленного адреса в качестве
Последний параметр SendMessage.
... ...
---- 2. Уведомление об IP-контроле
---- При изменении строки IP или переносе фокуса ввода элемент управления IP отправит сообщение уведомления IPN_FIELDCHANGED в свое родительское окно. В большинстве случаев мы можем игнорировать это уведомление. Ниже приведен пример обработки сообщения уведомления IPN_FIELDCHANGED:
процедура Tform1.WndProc(var Msg: TMessage);
вар п:PNMHDR;
начинать
унаследованный;
если Msg.Msg=WM_NOTIFY
тогда начни
р:=Указатель(Msg.lParam);
если p^.code=IPN_FIELDCHANGED
тогда начни
{…
Обработка сообщения уведомления IPN_FIELDCHANGED элемента управления IP
…}
конец;
конец;
конец;
---- 3. Методы и приложения динамически формирующихся управлений.
---- 1.Два метода создания элементов управления в Delphi.
---- (1). Создание элементов управления в дизайне формы.
---- При разработке формы обычно необходимо напрямую выбирать необходимый элемент управления на панели инструментов управления, затем задавать его свойства и реагировать на события.
---- (2) Динамическое создание элементов управления в программе.
---- Иногда нам необходимо динамически генерировать элементы управления во время работы программы. Это имеет два основных преимущества: во-первых, это может повысить гибкость программы, во-вторых, если количество сгенерированных элементов управления связано с промежуточными результатами запуска; программы, очевидно, первый метод не может быть реализован, и необходимо использовать метод динамической генерации в программе.
---- Метод динамического создания элементов управления в программе разделен на три этапа: сначала определите тип сгенерированного элемента управления, затем используйте функцию Create для создания элемента управления и, наконец, присвойте значения соответствующим свойствам элемента управления. контроль. Если взять в качестве примера элемент управления TButton, то шаги будут следующими:
---- а. Определите тип управления.
вар
Кнопка1:TButton;
---- б. Создание элементов управления.
Button1:=TButton.Create(self);
Button1.Parent:=Self;
//Обычно установите для родительского элемента управления значение Self. Если значение Parent не установлено,
тогда управления не будет на экране
//отображаем это
---- c. Установите другие свойства и определите соответствующие функции реагирования на события, такие как функции ответа на событие «Заголовок», «Слева», «Сверху», «Высота», «Ширина», «Видимый», «Включено», «Подсказка» и «onClick» и т. д.
---- 2. Применение динамически генерируемого метода управления.
---- При разработке систем планирования и управления производством необходимо динамически генерировать диаграммы планирования производства, представленные диаграммами Ганта, и очень полезно использовать элементы управления формой для отображения состояния обработки деталей (время начала обработки и время окончания каждого процесса). С помощью элемента управления «Диаграмма» загрузка технологического оборудования отображается в виде трехмерной гистограммы, которая очень интуитивно понятна. Теперь мы объясним процесс динамического создания элементов управления Shape и Chart в программе.
---- (1) Динамическое создание элемента управления формой для отображения диаграммы плана планирования производства (диаграмма Ганта).
процедура TCreateMultiCharts.ProcCreateCharts;
вар
я, j, строки, столбцы, RowSpace, ChartsHeight: Integer;
ShapeChart: массив массива TShape;
начинать
Rows:=16; //Количество строк в массиве управления формой
Columns:=8; //Номер столбца массива управления формой
RowSpace:=20 // Расстояние между строками управления формой
ChartsHeight:=20 // Высота элемента управления формой
SetLength(ShapeChart,строки,столбцы);
//Установим размер массива ShapeChart
для i:=0 для строк делать
для j:=0 в столбцах сделать
начинать
ShapeChart[i][j]:=TShape.Create(self);
с помощью ShapeChart[i,j] делаю
начинать
Parent:=Self; //Эта строка важна,
В противном случае элемент управления «Форма» не будет отображаться на экране.
Shape:=stRectangle; // Форма элемента управления — прямоугольник.
Верх:=45+i*(RowSpace+ChartsHeight);
Слева:=Раунд(180+Q[i,j].StartTime);
//Поскольку Q[i,j].StartTime — действительное число, его необходимо округлить.
Ширина:=Круглый(Q[i,j].Значение)
Высота:=ChartsHeight;
Кисть.Цвет:=СлучайныйЦвет;
//Пользовательская функция, инструкция прилагается
Brush.Style:=bsSolid //Установим метод заливки;
Включено:=Истина;
конец;
конец;
конец;
---- Примечание: aQ — это двумерный массив типа записи, определяемый следующим образом:
тип
TempData=Запись
Значение: Реальное;
Время начала: Реальное;
конец;
Вопрос: массив массива TempData.
А компонентам Q были присвоены значения в другом процессе.
---- b. Чтобы различать разные части, форма отображается разными цветами. В это время вызывается функция RandomColor. Функция:
функция TCreateMultiCharts.RandomColor;
вар
красный, зеленый, синий: байт;
начинать
красный:=случайный(255);
зеленый:=случайный(255);
синий:=случайный(255);
результат:=красный или (зеленый шл 8) или (синий шл 16);
конец;
---- (2) Динамическое создание компонента ChartSeries элемента управления Charts для отображения использования устройства.
процедура TFormMultiMachinesBurthen.
ПоказатьMachineBurthenCharts;
вар
я: целое число;
Бертен: Реальный;
SeriesClass:TChartSeriesClass;
NewSeries: массив TChartSeries;
начинать
SetLength(NewSeries,CreateMultiCharts.Rows);
MachinesBurthenCharts.height:=200;
MachinesBurthenCharts.Width:=550;
для i:=0 для CreateMultiCharts.Rows сделайте
начинать
SeriesClass:=TBarSeries; //Установим форму трехмерной гистограммы;
NewSeries[i]:=SeriesClass.Create(Self);
NewSeries[i].ParentChart:=MachinesBurthenCharts;
Новая серия[i].Очистить;
Burthen:=MachineBurthen[i];
Burthen:=Round(Burthen*100)/100 // Берем только две цифры после десятичной точки
NewSeries[i].add(Burthen,',NewSeries[i].SeriesColor);
конец;
конец;
---- Примечание: (a).MachineBurthen[i] — это реальный массив, его значение — это использование соответствующего устройства, рассчитанное в другой функции;
---- (b). MachinesBurthenCharts — это элемент управления TChart, описанный в разделе о типах.
---- 3. Отображение результатов выполнения программы.
---- (1) Динамическое создание элемента управления «Форма» для отображения плана планирования поставок деталей (опущено).
---- (2) Динамически генерировать компонент ChartSeries элемента управления Chart и отображать использование устройства (опущено).