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 :
Ensuite, dans l'événement TntTreeView1Click, j'appelle la fonction suivante pour obtenir le chemin complet :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 MasterNode := TntTreeView1.Items.AddChildFirst(nil, 'Ordinateur'); KeysNode := TntTreeView1.Items.AddChild(MasterNode, 'HKEY_LOCAL_MACHINE');
Exemple d'utilisation :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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;
Je renvoie ensuite au serveur le résultat obtenu par WideGetPath.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 if TntTreeView1.Selected <> nil then TntEdit1.Text := WideGetPath(TntTreeView1.Selected);
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 :
La fonction ParceRegistryManagerData est déclarée dans la forme UnitRegistry comme suit :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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;
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 : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Public procedure ParceRegistryManagerData(var pMemory: Pointer; dwMemorySize: Integer; CmdParce: Byte; objFormObjet: TObject); end;
Voici un aperçu de la fonction ParceRegistryManagerData :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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;
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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;
Si quelqu'un a une idée ou une solution à ce problème, je suis preneur. Merci d'avance !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 SelectedTreeNode := TntTreeView1.Selected;
Partager