Я предполагаю, что моя проблема вызвана концепцией реализации UnicodeStrings, но я не могу решить эту проблему.
Я пытаюсь рекурсивно сканировать дерево каталогов на диске и создавать древовидное представление, которое должно отображать все файлы и подпапки. Кроме того, я хочу хранить дополнительную информацию для каждого узла дерева. Объект TTreeNode имеет для этой цели только свойство «Данные» (тип Pointer), поэтому я выделяю память вручную, сохраняю информацию и назначаю выделенный указатель своему свойству данных. Кажется, все работает нормально, если я не включу использование поля UnicodeString в свою запись данных.
Итак, вот мое определение пользовательской записи данных:
type
TFileInformation = record
AbsoluteFileName: UnicodeString;
FileSize: Int64;
FileAttributes: LongInt;
CreationTime, ModificationTime: TDateTime;
end;
И вот мой код для отказа от каталога:
const NO_ERROR = 0;
procedure ScanDirectory(Folder: UnicodeString; Node: TTreeNode);
var
Details: Pointer;
NewNode: TTreeNode;
SearchAttributes: LongInt;
SearchMask: UnicodeString;
SearchRecord: TUnicodeSearchRec;
begin
if (Folder <> '') and (Folder[Length(Folder)] <> DirectorySeparator) then begin
Folder += DirectorySeparator;
end;
SearchMask := Folder + '*'{$IFDEF WINDOWS} + '.*'{$ENDIF};
SearchAttributes := faReadOnly or faHidden or faSysFile or faDirectory or faArchive or faSymLink;
if FindFirst(SearchMask, SearchAttributes, SearchRecord) = NO_ERROR then begin
repeat
if ((SearchRecord.Attr and faDirectory) <> faDirectory) or
((SearchRecord.Name <> '.') and (SearchRecord.Name <> '..')) then begin
Details := MemAlloc(SizeOf(TFileInformation));
//TFileInformation(Details^).AbsoluteFileName := Folder + SearchRecord.Name;
TFileInformation(Details^).FileAttributes := SearchRecord.Attr;
TFileInformation(Details^).FileSize := SearchRecord.Size;
TFileInformation(Details^).CreationTime := SearchRecord.Time;
//TFileInformation(Details^).ModificationTime := -1;
if Node = nil then begin
NewNode := self.trvOrigin.Items.AddNode(nil, nil, ansistring(SearchRecord.Name), Details, naAdd);
end else begin
NewNode := self.trvOrigin.Items.AddNode(nil, Node, ansistring(SearchRecord.Name), Details, naAddChild);
end;
if (SearchRecord.Attr and (faDirectory or faSymLink)) = faDirectory then begin
// only recurse folders which are NOT SymLink:
ScanDirectory(Folder + SearchRecord.Name, NewNode);
end;
end;
until FindNext(SearchRecord) <> NO_ERROR;
end;
FindClose(SearchRecord);
end;
Когда я раскомментирую строку, содержащую .AbsoluteFileName :=
, я получаю нарушение прав доступа (исключение SIGSEGV в Unix). В настоящее время я использую Lazarus в режиме objfpc
в Debian Linux, но я думаю, что то же самое и с Delphi в Windows. Значение свойства Treeview.Data хранится в переменной «Подробности» в моем примере кода, self.trvOrigin — это мой элемент управления древовидной структурой.
MemAlloc
? Насколько я помню, это специфическая функция Windows. Нашел только вMemory
отрядеFreeVision
(помимоWindows
отряда)... - person Abelisto   schedule 02.07.2016