TntTreeView problème sous Delphi 7
Salut la communauté,
Je suis en train de créer un outil de contrôle à distance sous Delphi 7, en utilisant les composants TNT pour gérer l'Unicode. J'ai un problème avec le composant TntTreeView : je n'arrive pas à obtenir le chemin complet lorsqu'un nœud est sélectionné.
Notez que j'utilise TntTreeView pour lister les clés du registre de l'ordinateur distant. Dans le FormCreate, j'ai utilisé le code suivant :
Code:
1 2 3
|
MasterNode := TntTreeView1.Items.AddChildFirst(nil, 'Ordinateur');
KeysNode := TntTreeView1.Items.AddChild(MasterNode, 'HKEY_LOCAL_MACHINE'); |
Ensuite, dans l'événement TntTreeView1Click, j'appelle la fonction suivante pour obtenir le chemin complet :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
function TUnitRegistryManager.WideGetPath(KeysTreeNode: TTntTreeNode): WideString;
begin
Result := '';
if Assigned(KeysTreeNode) then
begin
if KeysTreeNode.Text = 'Ordinateur' then Exit;
Result := KeysTreeNode.Text;
while Assigned(KeysTreeNode.Parent) do
begin
KeysTreeNode := KeysTreeNode.Parent;
if KeysTreeNode.Parent <> nil then
Result := KeysTreeNode.Text + '\' + Result;
Application.ProcessMessages;
end;
end;
end; |
Exemple d'utilisation :
Code:
1 2 3
|
if TntTreeView1.Selected <> nil then
TntEdit1.Text := WideGetPath(TntTreeView1.Selected); |
Je renvoie ensuite au serveur le résultat obtenu par WideGetPath.
Jusqu'ici, tout va bien, mais mon problème survient lorsqu'il s'agit des sous-clés. Par exemple, lorsque je liste les clés sous HKEY_LOCAL_MACHINE (par exemple, Software, Hardware, etc.), et que je clique sur Software, je reçois le chemin complet dans le TntEdit, qui est bien HKEY_LOCAL_MACHINE\SOFTWARE.
Cependant, lorsque je clique sur l'une des sous-clés de SOFTWARE (par exemple 7-Zip ou Avast), je ne reçois pas le chemin complet. Je reçois seulement HKEY_LOCAL_MACHINE\Software, sans ajouter la sous-clé sélectionnée.
Voici un extrait de mon code serveur, où je traite les données envoyées par le serveur au thread :
Code:
1 2 3 4 5 6 7 8 9
|
EXPLODE_REGISTRY_LIST : // get registry keys and values list
begin
if FUserItem <> nil then
begin
FCallBackProcedure := TUnitRegistryManager(FUserItem.SubItems.Objects[1]).ParceRegistryManagerData;
FCallBackProcedure(DecompMemory, DecompMemorySize, dwCommand, FUserItem.SubItems.Objects[1]);
end;
end; |
La fonction ParceRegistryManagerData est déclarée dans la forme UnitRegistry comme suit :
Code:
1 2 3 4
|
Public
procedure ParceRegistryManagerData(var pMemory: Pointer; dwMemorySize: Integer; CmdParce: Byte; objFormObjet: TObject);
end; |
J'ai utilisé FUserItem car c'est un système multitâche. Voici comment cela fonctionne dans la forme principale lorsque je clique sur le bouton Connecter cet utilisateur :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
var
UnitRegistryManager: TUnitRegistryManager;
begin
if lvConnections.Selected = nil then Exit;
if lvConnections.Selected.SubItems.Objects[1] = nil then
begin
UnitRegistryManager := TUnitRegistryManager.Create(self);
lvConnections.Selected.SubItems.Objects[1] := UnitRegistryManager;
UnitRegistryManager.objFormObjet := lvConnections.Selected.SubItems.Objects[1];
UnitRegistryManager.FSocket := TSocket(StrToInt(lvConnections.Selected.SubItems.Strings[12]));
UnitRegistryManager.FUniqueID := lvConnections.Selected.SubItems.Strings[11];
UnitRegistryManager.FUserID := lvConnections.Selected.SubItems.Strings[2];
UnitRegistryManager.SetCallBackProcess(THandleConnection(lvConnections.Selected.Data).BuildPaCket);
UnitRegistryManager.Show;
end
else
begin
TUnitRegistryManager(lvConnections.Selected.SubItems.Objects[1]).Show;
end;
end; |
Voici un aperçu de la fonction ParceRegistryManagerData :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
procedure TUnitRegistryManager.ParceRegistryManagerData(var pMemory: Pointer; dwMemorySize: Integer; CmdParce: Byte; objFormObjet: TObject);
var
ParceStream: TMemoryStream;
dwParseType, dwKeyLen, dwValueType: Integer;
wszKeyName, wszValueName, wszSubValueName: WideString;
_KeysNode: TTntTreeNode;
RegistryItemValue: TTntListItem;
begin
if dwMemorySize = 0 then
begin
FEnableReply := True;
Exit;
end;
ParceStream := TMemoryStream.Create;
ParceStream.Write(pMemory^, dwMemorySize);
ParceStream.Position := 0;
FreeMem(pMemory, dwMemorySize);
ParceStream.Read(dwParseType, SizeOf(Integer));
case dwParseType of
1:
begin
TntTreeView1.Enabled := False;
TntTreeView1.Items.BeginUpdate;
if SelectedTreeNode.HasChildren then
SelectedTreeNode.DeleteChildren;
while ParceStream.Position < ParceStream.Size do
begin
ParceStream.Read(dwKeyLen, SizeOf(Integer));
SetLength(wszKeyName, dwKeyLen);
ParceStream.Read(Pointer(wszKeyName)^, dwKeyLen * 2);
_KeysNode := Self.TntTreeView1.Items.AddChild(SelectedTreeNode, wszKeyName);
_KeysNode.Data := Pointer(wszKeyName);
_KeysNode.ImageIndex := 1;
_KeysNode.SelectedIndex := 0;
end;
TntTreeView1.Items.EndUpdate;
SelectedTreeNode.Expand(False);
TntTreeView1.Enabled := True;
TntTreeView1.Update;
SelectedTreeNode := nil;
end;
end;
end; |
J'ai utilisé SelectedTreeNode comme référence au nœud sélectionné dans TntTreeView, qui est attribuée lors du clic sur l'arbre avec :
Code:
1 2
|
SelectedTreeNode := TntTreeView1.Selected; |
Si quelqu'un a une idée ou une solution à ce problème, je suis preneur. Merci d'avance !