Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Virtual TreeView настройка


Автор: Norfonzor 14.5.2010, 07:23
вопросы:
1) как назначить на node иконки папок, пример "от квадро" открывает с ошибкой.

2) глюк с выделением:
в моей программе существуют 2 вида файлов: папки и файлы, в файлах нельзя создавать под каталоги. Редактирования осуществляется при нажатии на правую кнопку мыши появляется PopupMenu, в котором, при нажатии на файлы пункт "Добавить в текущем" становится в .disable

проблема:
выделяю папку, далее правой кнопкой жму на файл, он не выделяется, открывается PopupMenu с enabled и добавляется подкаталог в файл:
user posted image

когда я левой кнопкой выделяю файл то все работает нормально
user posted image

Как исправить эту проблему?
надо как то осуществить выделение.
код обработчиков:

на VT правой кнопкой:
Код

procedure TfrmMain.VTMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  NewPhone: PPhoneNode;
begin
if ((Button = mbRight)and(VTBxod.Caption='Выход')) then
begin
  NewPhone := VT.GetNodeData(VT.FocusedNode);
  if Assigned(NewPhone) then
   if NewPhone^.doc<>'' then add.Enabled:=false else //add это строка в PopupMenu
   add.Enabled:=true;
 PM_add.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
end;
end;


3) В VT могут добавляться файлы (MS office) при нажатии на них в VT они загружаются в  Webbrowser:
user posted image 

при удалении каталога, надо удалить все файлы которые в нем содержаться, т.е. надо перечислить все Node
далее я удалю их

Код

... ?
if Assigned(NewPhone) then
  begin
  z:=NewPhone^.doc;
  if z<>'' then удалить файл из каталога.
  end;


Спасибо!

Автор: kami 14.5.2010, 07:56
1. Должен быть ImageList, назначенный VT, в VT нужно назначить обработчик OnGetImageIndex, в котором возвращать индекс нужной иконки из ImageList. Кроме примеров от Quadro есть примеры на сайте разработчика.
2. Для начала, выставить TreeOptions>SelectionOptions>toRightClickSelect в True.
3. Не нужно перечислять все ноды. Они сами перечислятся в vt.OnFreeNode. Правда, тут нужно обработать освобождение нодов по завершению работы программы.
Например, так:
Код

procedure TForm1.vtFreeNode(..);
begin
  if not (csDestroying in vt.ComponentState) then
    begin
       удаляем файл/папку
    end;

  // и в любом случае - освобождаем Node.Data.
end;

Автор: Norfonzor 14.5.2010, 09:47
1)  smile для обработчика OnGetImageIndex,
Код

procedure TfrmMain.VTGetImageIndexEx(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
  var Ghosted: Boolean; var ImageIndex: Integer;
  var ImageList: TCustomImageList);
var
  PhoneNode: PPhoneNode  ;
begin
  PhoneNode := VT.GetNodeData(Node);
  if Assigned(PhoneNode) then
  begin
    ImageList :=ImageList1; 
    ImageIndex := 0;
  end;
end;

в ImageList1 иконки с номера 0 и 1. но иконки не отображаются. Текс придумал сам   smile 

ГГЫЫ!!! выбрал Imagelist1 в ObjectInspector (слева) в пункте Images. иконки появились!


2) стоит в true, я заметил что она выделяется когда пропадает PopMenu.
3) все работает отлично! Не думал что так просто будет.
Код

procedure TfrmMain.VTFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var z:string;
NewPhone: PPhoneNode;
begin
  if not (csDestroying in vt.ComponentState) then
    begin
    NewPhone := VT.GetNodeData(Node);
    if Assigned(NewPhone) then
    begin
     z:=NewPhone^.doc;
     if z<>'' then
      begin
       z:=ExtractFilePath(Application.Exename)+'LIB\'+z;
       //showmessage('удаляю'+z);
       if not DeleteFile(pchar(z)) then ShowMessage('Ошибка удаления');
       VTsave.Click;
      end;
    end;

    end;
  // и в любом случае - освобождаем Node.Data.
end;


Добавьте kami репу+++ у меня постов не хватает

Автор: kami 14.5.2010, 10:07
Цитата(Norfonzor @  14.5.2010,  09:47 Найти цитируемый пост)
2) стоит в true, я заметил что она выделяется когда пропадает PopMenu.

Переделаем обработчики:
1. vt.OnMouseDown убрать. С концами.
2. Назначаем обработчик vt.OnContextPopup (не забыв при этом прописать PopupMenu в инспекторе объектов в vt.PopupMenu
  В нем пишем:

Код

procedure T....vtContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
...
begin
  if not Assigned(vt.FocusedNode) then
    exit;
  NewPhone := VT.GetNodeData(VT.FocusedNode);
  if Assigned(NewPhone) then
    if NewPhone^.doc<>'' then 
      add.Enabled:=false
    else 
      add.Enabled:=true;
end;

// кстати, в этом коде непонятно, что будет с пунктом меню add, если Assigned(NewPhone)=False

Автор: Norfonzor 14.5.2010, 11:34
Все отлично работает!
По поводу "что будет с пунктом меню add, если Assigned(NewPhone)=False", когда "Assigned(NewPhone)" может быть false?

а еще вопрос как заблокировать PopupMenu чтобы оно не появлялось. (если не в режиме редактирования то появляться не должно)
Сделал так:
Код

  if VTBxod.Caption='Вход' then
  begin
  add.Visible:=false;
  add_top.Visible:=false;
  add_botton.Visible:=false;
  add_R_verh.Visible:=false;
  add_R_niz.Visible:=false;
  Edit.Visible:=false;
  Del_all.Visible:=false;
  Dell_doch.Visible:=false;
  add_doc.Visible:=false;
  end else

  begin
  add.Visible:=true;
  add_top.Visible:=true;
  add_botton.Visible:=true;
  add_R_verh.Visible:=true;
  add_R_niz.Visible:=true;
  Edit.Visible:=true;
  Del_all.Visible:=true;
  Dell_doch.Visible:=true;
  add_doc.Visible:=true;
  end;


не знаю на сколько это красиво и можно ли так делать

Автор: kami 14.5.2010, 23:32
Цитата(Norfonzor @  14.5.2010,  11:34 Найти цитируемый пост)
когда "Assigned(NewPhone)" может быть false?

ХЗ. Не заморачивался подобным. Но вообще - может, когда нод не инициализирован.
Если у тебя такое невозможно - зачем тогда вообще проверка на Assigned? А если возможно - нужно предусмотреть все варианты ветвления алгоритма.

Цитата(Norfonzor @  14.5.2010,  11:34 Найти цитируемый пост)
не знаю на сколько это красиво и можно ли так делать

работает? Значит можно. smile
Но вообще - если можно отследить явный признак перехода в режим редактирования и обратно, я бы сделал так:

// в событии входа/выхода в/из режим редактирования
Код

if не_в_режиме_редактирования then
  vt.PopupMenu:=nil
else
  vt.PopupMenu:=мое_контекстное_меню;

Вот и все - когда входим в режим редактирования у vt "появляется" PopupMenu, а когда выходим - исчезает...
Единственное - нужно определиться с начальным состоянием - если при запуске программы режим редактирования включен, то нужно прописать в инспекторе объектов vt.PopupMenu, иначе - оставить пустым.

Автор: Norfonzor 15.5.2010, 07:19
PopupMenu, работает ))

Да и наверное последний вопрос:
разворачиваю каталог выделяю документ, далее нажимаю на "+" или "-" чтобы свернуть VT а он распознает нажатие на "+/-" как нажатие на документ и он повторно перезагружает документ. 
user posted image

Как можно сделать чтобы VT не распознавала нажатие на "+/-" как нажатие на документ?

Автор: kami 17.5.2010, 13:01
Цитата(Norfonzor @  15.5.2010,  07:19 Найти цитируемый пост)
Как можно сделать чтобы VT не распознавала нажатие на "+/-" как нажатие на документ?

Если еще актуально:
код OnClick и/или OnMouseDown (что от него осталось) - в студию.
Навскидку:
перенести код, отвечающий за загрузку/перезагрузку документа в событие onChange (возникает при смене фокуса с нода на нод). Типа так:

Код

procedure TFrom1.vtChange(...);
begin
  if Assigned(vt.FocusedNode) then
    // перезагружаем документ
  else
    // ничего не выбрано.

// кстати, можно задействовать и параметр Node этого события - по описанию это нод,
// состояние которого было изменено последним. Хотя - это на усмотрение.
end;


Автор: Norfonzor 17.5.2010, 18:38
kami, Актуально! еще раз спасибо за помощь, ждал твоего ответа. Как всегда все отлично работает!!! smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)