내 문제는 UnicodeString이 어떻게 구현되는지 개념으로 인해 발생하지만이 문제를 해결할 수 없다.Lazarus/Delphi : 자체 할당 된 레코드 데이터 형식의 UnicodeString이 액세스 위반을 야기한다.
디스크의 디렉터리 트리를 반복적으로 검사하고 모든 파일과 하위 폴더를 표시해야하는 트리 뷰를 작성하려고합니다. 또한 각 트리 노드에 대한 추가 정보를 저장하려고합니다. TTreeNode 객체에는이 목적을위한 "데이터"속성 (포인터 유형) 만 있으므로 수동으로 메모리를 할당하고 정보를 저장하며 할당 된 포인터를 데이터 속성에 할당합니다. 내 데이터 레코드 내에 UnicodeString 필드를 사용하지 않으면 모든 것이 잘 작동하는 것처럼 보입니다.
그래서, 여기 내 사용자 정의 데이터 레코드 정의입니다 :
type
TFileInformation = record
AbsoluteFileName: UnicodeString;
FileSize: Int64;
FileAttributes: LongInt;
CreationTime, ModificationTime: TDateTime;
end;
그리고 여기 디렉토리 recusion 내 코드입니다 : 내가 .AbsoluteFileName :=
을 포함하는 행의 주석을 해제하면
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;
, 나는 액세스 위반을 얻을 (유닉스에서의 SIGSEGV- 예외). 현재 데비안 리눅스에서 objfpc
모드의 Lazarus를 사용하고 있습니다.하지만 Windows의 경우 델파이와 동일합니다. Treeview.Data 속성 값은 내 예제 코드의 "Details"변수에 저장됩니다. self.trvOrigin은 내 treeview 컨트롤입니다.
어디에서'MemAlloc' 함수를 사용할 수 있습니까? Windows 특유의 기능이라는 것을 기억합니다. 'FreeVision'의'Memory' 단위 ('Windows' 단위 외에)에서만 찾을 수 있습니다 ... – Abelisto
나사로에 포함 된 메모리 유닛을 사용합니다. –
TTreeNode에서 필요로하는 추가 필드가 포함 된 파생 클래스를 만드는 것이 더 좋지 않을까요? 그렇게하면 혼자서 추가 정보를 위해 메모리를 할당하고 해제하는 것에 대해 걱정할 필요가 없습니다. 데이터 등록 정보를 사용하는 것이 더 좋은 경우는 여러 트리 노드가 동일한 추가 정보를 포함하거나이 추가 정보가 별도로 유지되는 경우입니다. – SilverWarior