![]() |
Problem mit CustomCheckShellTreeView
hallo,
auf die gefahr hin dass ich keine antworten bekomme frage ich trotzdem nach. ich verwende folgende komponente um dateien und ordner in einer TShellTreeView mit CheckBoxen anzeigen zu lassen: ![]() vorher wurden keine dateien sondern nur ordner anzeigt. folgendes habe ich geändert und nun funktionierts:
Delphi-Quellcode:
CanAdd ist jetzt immer True. vorher war es bei dateien egal welchem typs immer false (AFolder.isFolder and..).
procedure TGtroCustomCheckShellTreeView.AddFolder(Sender: TObject; AFolder: TShellFolder; var CanAdd: Boolean);
// Handler for the OnAddFolder event of TShellTreeView // var // FileExt: string; begin // FileExt := ExtractFileExt(AFolder.DisplayName); // CanAdd := AFolder.IsFolder and (CompareText('.zip', FileExt) <> 0) and (CompareText('.cab', FileExt) <> 0) CanAdd := True; end;
Delphi-Quellcode:
beim ankreuzen eines ParentNodes (ist das der erste knotenpunkt eines ordners?) wurden alle unterordner/dateien mitangekreutzt. durch auskommentieren von dem code aus CheckIt() passiert das jetzt nicht mehr.
function TGtroCustomCheckShellTreeView.GetNodePath(Node: TTreeNode): string;
// return the path of the folder associated with a node // Called by CheckIt() and EnumFiles() begin Result := TShellFolder(Node.Data).PathName; end; procedure TGtroCustomCheckShellTreeView.CheckIt(const Node: TTreeNode; IncludeSubs: Boolean; State: Boolean); // called by WMLButtonDown() and LoadFromFile() var Pattern: string; ANode: TTreeNode; Level: Integer; begin Items.BeginUpdate; try SetNodeChecked(Node, State); // Check/uncheck the node EnumFiles(Node, State, FList); // Pattern := GetNodePath(Node) + '\'; // Get the path of the node (pattern) // if IncludeSubs then // begin // FPatterns.Add(Pattern + '/s'); // Load the pattern in the FPatterns list // Level := Node.Level; // // Node.Expand(True); // absolutely necessary as GetNext sees only visible nodes // try // ANode := Node.getFirstChild; // while (ANode <> nil) and (Level < ANode.Level) do // begin // if State <> IsNodeChecked(ANode) then // begin // SetNodeChecked(ANode, State); // EnumFiles(ANode, State, FList); // end; // ANode := ANode.GetNext; // end; // finally // Node.Collapse(True); // end; // end // else // FPatterns.Add(Pattern); // Load the pattern in the FPatterns list finally Items.EndUpdate; end; // try...finally if Assigned(FOnCheckChanged) then FOnCheckChanged(Self, Node, State, FList); end; procedure TGtroCustomCheckShellTreeView.EnumFiles(ANode: TTreeNode; State: Boolean; var List: TStringList); // Called by CheckIt() // var // Path: string; // Data: TSearchRec; // ds: longint; begin if State then List.Add(GetNodePath(ANode)) else List.Delete(List.IndexOf(GetNodePath(ANode))); // Path := GetNodePath(ANode); // ds := FindFirst(Path + '\*.*', faAnyFile, Data); // Fetch the first file // while ds = 0 do // continue as long as the result is successfull // begin // if (Data.Attr and faDirectory <> faDirectory) then // don't bother with directories // if State then // List.Add(Path + '\' + Data.Name) // add to the list // else // List.Delete(List.IndexOf(Path + '\' + Data.Name)); // delete from the list // ds := FindNext(Data); // end; // FindClose(Data); end; bei EnumFiles() habe ich alles auskommentiert weil wenn ich einen ordner ankreuze der VIEL inhalt hat das laden minuten dauert. alles andere ist original. meine frage bezieht sich jetzt auf die methode LoadFromFile(). eine datei mit zeilenweise enthaltenen pfaden zu dateien und ordnern wird korrekt eingelesen. aber hier krachts: IsNodeChecked()
Delphi-Quellcode:
ANode ist ja so wie es aussieht ungleich nil und trotzdem kracht es beim prüfen ob die CheckBox des Knotenpunkt checked oder nicht checked ist.
function TGtroCustomCheckShellTreeView.IsNodeChecked(Node: TTreeNode): Boolean;
// Verifies if the node is checked // Called by CheckIt(), UncheckAll(), WMLButtonDown() and LoadFromFile() const TVIS_CHECKED = $2000; var TvItem: TTVItem; begin TvItem.Mask := TVIF_STATE; TvItem.hItem := Node.ItemId; TreeView_GetItem(Node.TreeView.Handle, TvItem); Result := (TvItem.State and TVIS_CHECKED) = TVIS_CHECKED; end; // . . . // ein teil der LoadFromFile()-Procedure if ANode <> nil then // Node has been found begin if not IncludeSubs then ANode.Collapse(False); OldState := IsNodeChecked(ANode); { GENAU hier kracht es mit einer AV } // Check status of node // Produce the list of files CheckIt(ANode, IncludeSubs, not OldState); end; ich entschuldige mich noch einmal ausdrücklich für meine dumme aufmüpfige art und weise. aber wenn etwas nicht klappt werde ich blöderweise schnell ungeduldig. ich werde es ändern! |
AW: Problem mit CustomCheckShellTreeView
Wie sieht denn "IsNodeChecked()" aus? Wahrscheinlich ist der Fehler dort drin...
|
AW: Problem mit CustomCheckShellTreeView
ich möchte nicht spammen, aber kopiere ich es aus dem oberen post noch einmal:
Delphi-Quellcode:
durchdebuggt habe ich bereits und ANode hat immer den zugewiesenen wert "()" ohne anführungszeichen. ANode ist also nicht nil aber trotzdem in irgendeiner art und weise leer.
function TGtroCustomCheckShellTreeView.IsNodeChecked(Node: TTreeNode): Boolean;
// Verifies if the node is checked // Called by CheckIt(), UncheckAll(), WMLButtonDown() and LoadFromFile() const TVIS_CHECKED = $2000; var TvItem: TTVItem; begin TvItem.Mask := TVIF_STATE; TvItem.hItem := Node.ItemId; TreeView_GetItem(Node.TreeView.Handle, TvItem); Result := (TvItem.State and TVIS_CHECKED) = TVIS_CHECKED; end; |
AW: Problem mit CustomCheckShellTreeView
UPS - hatte ich übersehen. Weist Node.Treeview.Handle auf den korrekten Treeview? Was liefert Treeview_GetItem zurück? Und ist TvItem am Ende <> NIL?
|
AW: Problem mit CustomCheckShellTreeView
ich kenne die Zusammenhänge nicht,
aber
Delphi-Quellcode:
wenn TTVItem kein Record sondern eine Klasse ist greift man hier ins Nirvana
var
TvItem: TTVItem; begin TvItem.Mask := TVIF_STATE; |
AW: Problem mit CustomCheckShellTreeView
ich habe noch einmal durchdebuggt.
Delphi-Quellcode:
das hier ist fehlerfrei und wird sehr oft problemlos ausgeführt.
var
TvItem: TTVItem; begin TvItem.Mask := TVIF_STATE; bei folgender zeile ist ANode nicht nil aber hat auch keinen wert:
Delphi-Quellcode:
das ist das seltsame.
if ANode <> nil then // Node has been found
ich glaube die procedure LoadFromFile() ist fehlerhaft. das wäre nicht der erste fehler den ich bei dieser komponente gefunden hätte. wenn ich Oldstate := IsNodeChecked() aber auskommentiere tritt der fehler woanders auf:
Delphi-Quellcode:
das ist ja glaube ich auch logisch da ANode einfach keinen inhalt hat und das verstehe ich nicht.
procedure TGtroCustomCheckShellTreeView.SetNodeChecked(Node: TTreeNode; Checked: Boolean);
// Toggle the status of a node // Called by CheckIt() and UncheckAll(), const TVIS_CHECKED = $2000; var TvItem: TTVItem; begin FillChar(TvItem, SizeOf(TvItem), 0); with TvItem do begin hItem := Node.ItemId; Mask := TVIF_STATE; StateMask := TVIS_STATEIMAGEMASK; if Checked then TvItem.State := TVIS_CHECKED else TvItem.State := TVIS_CHECKED shr 1; TreeView_SetItem(Node.TreeView.Handle, TvItem); // HIER tritt der fehler dann mit einer AV auf end; end; das wäre also ein folgefehler aufgrund dessen dass ANode = '' ist. folgende procedure ist dafür verantwortlich dass ANode eigentlich einen inhalt haben sollte.
Delphi-Quellcode:
ich vermute den fehler sehr wahrscheinlich hier. beim durchdebuggen habe ich aber keinen gefunden.
function TGtroCustomCheckShellTreeView.GetNodeFromPath(const Path: string): TTreeNode;
// called by LoadFromFile() var FoundNode: TTreeNode; function AppendSlash(ANode: TTreeNode): string; begin Result := TShellFolder(ANode.Data).PathName; if IsDirectory(Result) then if '\' <> Copy(Result, Length(Result), 1) then Result := Result + '\'; end; procedure ScanNodes(Path: string; Segment: string; ANode: TTreeNode); var P: Integer; Slash: string; begin P := Pos('\', Path); if P > 0 then begin // Split the path into segments (segments are separated by "\") Segment := Segment + Copy(Path, 0, P); // First segment of the path Path := Copy(Path, P + 1, Length(Path)); // Remaining segments of the path ANode.Expand(False); // Expand the node ANode := ANode.getFirstChild; // Move to the first child node Slash := AppendSlash(ANode); // Append "\" if not already there while Segment <> Slash do // Iterate on each child nodes begin ANode := ANode.getNextSibling; if ANode <> nil then Slash := AppendSlash(ANode) else // Iterated beyond last child node Break; // No correspondence => out! end; if Path <> '' then // Path is not exhausted begin if ANode <> nil then begin ANode.Expand(False); ScanNodes(Path, Segment, ANode); // called recursively end; end else // Path is exhausted FoundNode := ANode; // Node found end; end; begin ScanNodes(Path, '', Items[0]); Result := FoundNode; // Reference to the node if found; nil otherwise end; gibt es keine andere möglichkeit bestimmte CheckBoxen bei einem Node Checked zu bekommen? die oben liegenden Nodex bekomme ich alle Checked. aber wenn ich die Nodex mit
Delphi-Quellcode:
durchgehe werden nur wie gesagt die ersten Nodes bearbeitet und nicht die SubNodes. alle nodes auf verdacht expandieren kann ich auch nicht.
for i := 0 to meinTreeView.Items.Count - 1
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz