Открытие нужного ключа в TreeView

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Открытие нужного ключа в TreeView

Сообщение mrkaban » 04.05.2017 17:26:06

Здравствуйте Уважаемые Форумчане! Сразу прошу прощения за глупые вопросы, так как я новичок!

Хочу сделать для программы модуль, который будет при его запуске открывать переданный ключ реестра. Условно, в основном окне человек выбрал ключ и нажал открыть, и тут открывает средство просмотра реестра с открытым нужным ключом.

Нашел алгоритм поиска в TreeView определенного текста с выделением

Код: Выделить всё
for i := 0 to keys.Items.Count - 1 do
if keys.Items[i].Text = 'HKEY_LOCAL_MACHINE' then
  begin
   keys.Selected:= keys.Items[i];
   keys.Items[i].Expand(true);
   break;
  end;


но ведь для открытия, например, "HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Aspia\" придется мудрить с отдельным открытием каждого элемента.

Может как то можно сделать открытие нужного элемента в TreeView проще? Прикреплю код средства просмотра реестра. Либо подскажите пожалуйста, как лучше организовать поиск с последующем выделением. Заранее спасибо!

Код: Выделить всё
//Функция путь ключа реестра, соответствующего заданному элементу (item)
//дерева. В путь не включается название корневого ключа
function GetKeyPath(item: TTreeNode): String;
var
  temp:TTreeNode;
  path: String;
begin
  temp := item;
  while temp.Parent <> nil do
  begin
    path := temp.Text + '\' + path;
    temp := temp.Parent;
  end;
  GetKeyPath := path;
end;

//Функция возвращает дексриптор корневого ключа реестра для ветки,
//который принадлежит элемент дерева item
function GetRootkey(item: TTreeNode): HKEY;
var
  temp: TTreeNode;
begin
  temp := item;
  while temp.Parent <> nil do
    temp := temp.Parent;
  GetRootKey :=HKEY(temp.Data);
end;

procedure TForm1.CheckSubKeys(item: TTreeNode);
var
  reg: TRegistry;
begin
  reg:= TRegistry.Create();
  //Проверка, есть ли в разделе реестра вложенные подразделы
  reg.RootKey := GetRootKey(item);
  if reg.OpenKeyReadOnly(GetKeyPath(item)) then
  begin
    if reg.HasSubKeys() then
    begin
      //добавляем фиктивный элемент (чтобы показывался "+" для
      //разворачивания раздела). Одновременно помечаем фиктивный элемент
      keys.Items.AddChild(item, '').Data := Pointer(-1);
    end;
    reg.CloseKey();
  end;
  reg.Free();
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  item: TTreeNode;
  //нужно для открытия нужного ключа
  reg: TRegistry;
  valueItem: TListItem;
  valueNames: TStringListUTF8;        //TStrings
  i: Integer;
begin
  //Формирование списка корневых разделов реестра
  item := keys.Items.AddChild(nil, 'HKEY_CLASSES_ROOT');
  item.Data := Pointer(HKEY_CLASSES_ROOT);
  CheckSubKeys(item);
  item := keys.Items.AddChild(nil, 'HKEY_CURRENT_USER');
  item.Data := Pointer(HKEY_CURRENT_USER);
  CheckSubKeys(item);
  item := keys.Items.AddChild(nil, 'HKEY_LOCAL_MACHINE');
  item.Data := Pointer(HKEY_LOCAL_MACHINE);
  CheckSubKeys(item);
  item := keys.Items.AddChild(nil, 'HKEY_USERS');
  item.Data := Pointer(HKEY_USERS);
  CheckSubKeys(item);
  item := keys.Items.AddChild(nil, 'HKEY_CURRENT_CONFIG');
  item.Data := Pointer(HKEY_CURRENT_CONFIG);
  CheckSubkeys(item);

  //Пробую сделать открытие нужного ключа

for i := 0 to keys.Items.Count - 1 do
if keys.Items[i].Text = 'HKEY_LOCAL_MACHINE' then
  begin
   item:=keys.Items[i];
   keys.Selected:= keys.Items[i];
   keys.Items[i].Expand(true);
   break;
  end;
end;

procedure TForm1.keysChange(Sender: TObject; Node: TTreeNode);
var
  reg: TRegistry;
  valueItem: TListItem;
  item: TTreenode;
  valueNames: TStringListUTF8;        //TStrings
  i: Integer;
begin
  item := keys.Selected;
  if item <> nil then
  begin
    //зачитаем содержимое выбранного раздела в ListView (values)
    values.Clear;
    reg:=TRegistry.Create();
    reg.RootKey := GetRootKey(item);
    if reg.OpenKeyReadOnly(GetKeyPath(item)) then
    begin
      valueNames := TStringListUTF8.Create();
      //получение списка названий параметров
      reg.GetValueNames(valueNames);
      //добавление каждого параметра в список
      for i := 0 to valueNames.Count - 1 do
      begin
        valueItem := values.Items.Add();
        if valueNames[i] = '' then
          valueItem.Caption := '<По умолчанию>'
          else
            valueItem.Caption := valueNames[i];
        //Получение типа и значения параметра
        case reg.GetDataType(valueNames[i]) of
        rdUnknown:
          valueItem.SubItems.Add('Неизвестно');
        rdString, rdExpandString:
          begin
            valueItem.SubItems.Add('Строка');
            valueItem.SubItems.Add(reg.ReadString(valueNames[i]));
          end;
        rdBinary:
          valueItem.SubItems.Add('Двоичные данные');
        end;
      end;
      valueNames.Free();
      reg.CloseKey();
    end;
    reg.Free();
  end;
end;

procedure TForm1.keysExpanding(Sender: TObject; Node: TTreeNode;
  var AllowExpansion: Boolean);
var
  reg: TRegistry;
  subkeys: TStringListUTF8;
  i: Integer;
begin
  if Integer(Node.getFirstChild.Data) <> -1 then
    //список подразделов был зачитан ранее
    Exit;
  Node.DeleteChildren(); //удаление фиктивного элемента дерева
  reg:=Tregistry.Create();
  //загрузка списка подразделов выбранного раздела
  reg.Rootkey := GetRootKey(Node);
  if reg.OpenKey(GetKeyPath(Node), False) then
  begin
    //получение списка подразделов
    subkeys := TStringListUTF8.Create();
    reg.GetKeyNames(subkeys);
    for i := 0 to subkeys.Count - 1 do
    begin
      //добавление элемента для дочернего раздела (не забываем
      //проверять подразделы у каждого дочернего раздела)
      CheckSubKeys(keys.Items.AddChild(Node, subkeys[i]));
    end;
    subkeys.Free();
    reg.CloseKey();
  end;
  reg.Free();
end;


Заранее благодарен за любую помощь!
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Открытие нужного ключа в TreeView

Сообщение serbod » 04.05.2017 17:55:25

Замени
Код: Выделить всё
if keys.Items[i].Text = 'HKEY_LOCAL_MACHINE' then
на
Код: Выделить всё
if GetKeyPath(keys.Items[i]) = 'HKEY_LOCAL_MACHINE' then
Аватара пользователя
serbod
постоялец
 
Сообщения: 449
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Открытие нужного ключа в TreeView

Сообщение mrkaban » 04.05.2017 18:17:08

Может я неправильно понял? сделал
Код: Выделить всё
for i := 0 to keys.Items.Count - 1 do
if GetKeyPath(keys.Items[i]) = 'HKEY_LOCAL_MACHINE' then
  begin
   //item:=keys.Items[i];
   keys.Selected:= keys.Items[i];
   keys.Items[i].Expand(true);
   break;
  end;


но не работает =(
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 24

Рейтинг@Mail.ru