Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.07.2010, 07:02   #21
Korben5E
Форумчанин
 
Аватар для Korben5E
 
Регистрация: 13.07.2010
Сообщений: 346
По умолчанию

Цитата:
Сообщение от AnTe Посмотреть сообщение
В паскале нужно вызвать obj2 := TMyObject.create явно, т.о. переменная ВСЕГДА будет ссылкой, если я правильно понимаю, но мне это никогда не мешало...
вот и появился момент когда стало мешать

вот простой пример - я объявил ссылку или переменную?
xyz : TMyHren;

надо для использования xyz вызывать конструктор? или он уже отработал ?
вот в таких моментах и скрывается использование

Цитата:
Сообщение от AnTe Посмотреть сообщение
У меня была проблема с передачей в VT объекта, а после решения проблемы, я задумался над тем, ЗАЧЕМ в VT с полем DATA придуманы такие сложности.
Если вопрос только по полю Data в VirtualTreeview то это структура

Код:
PVirtualNode = ^TVirtualNode;

TVirtualNode = packed record
  ChildCount: Cardinal;
  Index: Cardinal;
  NodeHeight: Word;
  States: TVirtualNodeStates;
  Align: Byte;
  CheckState: TCheckState;
  CheckType: TCheckType;
  Dummy: Byte;
  TotalCount: Cardinal;
  TotalHeight: Cardinal;
  FirstChild: PVirtualNode;
  LastChild: PVirtualNode;
  NextSibling: PVirtualNode;
  Parent: PVirtualNode;
  PrevSibling: PVirtualNode;
  Data: record;
  end;
а в простом TreeView - это Pointer

Код:
property Data: Pointer read FData write SetData;
с этим и связаны различия в обращении к переменным
Non est culpa vin, sed culpa bibentis
Korben5E вне форума Ответить с цитированием
Старый 15.07.2010, 09:17   #22
AnTe
Форумчанин
 
Регистрация: 25.09.2008
Сообщений: 209
По умолчанию

Цитата:
Сообщение от Korben5E Посмотреть сообщение
вот и появился момент когда стало мешать
эммм... лично мне помешала только реализация стороннего компонента, метод которого выдавал не ссылку на объект, а ссылку на ссылку. Вот и задался вопросом, так ли это надо? Почему так сделано?

Цитата:
вот простой пример - я объявил ссылку или переменную?
xyz : TMyHren;

надо для использования xyz вызывать конструктор? или он уже отработал ?
вот в таких моментах и скрывается использование
Мне кажется самым правильным, когда конструктор, для объектов, каждый раз вызывается явно, а не в блоке объявления.

Цитата:
Если вопрос только по полю Data в VirtualTreeview то это структура
К данным, привязанным к узлу обращаются, вызывая метод GetNodeData, а он имеет тип Pointer.

Цитата:
а в простом TreeView - это Pointer
Тоже Pointer, кстати, значение рассчитывается методом SetData, только вот при он выдаст настоящий указатель, на связанный объект, а не мудрёный указатель на указатель

Цитата:
с этим и связаны различия в обращении к переменным
Для меня загадка, ЗАЧЕМ так сделано. Абсолютно никаких плюсов в такой реализации я не вижу.

Зачем вообще использовать record? Для ускорения скорости работы?
AnTe вне форума Ответить с цитированием
Старый 15.07.2010, 12:20   #23
Korben5E
Форумчанин
 
Аватар для Korben5E
 
Регистрация: 13.07.2010
Сообщений: 346
По умолчанию

Цитата:
Сообщение от AnTe Посмотреть сообщение
Мне кажется самым правильным, когда конструктор, для объектов, каждый раз вызывается явно, а не в блоке объявления.
при неявном вызове нет необходимости заботится об удалении объекта

к примеру Integer - тоже объект и скрыто вызывается конструктор который выделит память для данной переменной...


Цитата:
Сообщение от AnTe Посмотреть сообщение
Зачем вообще использовать record? Для ускорения скорости работы?
ну вот смотри - если это будет работать - то не пойму о чем ты вообще говоришь

Код:
procedure TfmTest.btnTreeViewClick(Sender: TObject);
var 
xx : TLabel;
begin
  xx:=TLabel.Create(self);
  TreeView1.Items.AddFirstObject(nil, 'First', xx);
  ShowMessage(TObject(xx).ClassName);
end;


procedure TfmTest.btnVirtualTreeViewClick(Sender: TObject);
var 
xx : TLabel;
begin
  xx:=TLabel.Create(self);
  VT.AddChild(nil, xx);
  ShowMessage(Tobject(xx).ClassName);
end;
может дело в том что ты не обратил внимание что Node в TreeView - это объект, а в VirtualTreeView - структура и именно по этому разница в обработке.
Non est culpa vin, sed culpa bibentis
Korben5E вне форума Ответить с цитированием
Старый 15.07.2010, 13:08   #24
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

начнем с того что в C++ можно размещать объекты в стеке(как локальные переменные)
и тогда они сами удалятся если что, и утечки не будет.
в Делфи только в куче, что требует явного Free;
в принципе я трактую подобный подход и в С++, ибо мне обычно не подходят стековые объекты+я предпочитаю сам контролировать.
Цитата:
сразу скажу что VCL это не поддерживают
это не поддерживает Делфи.
VCL=Visual Component Library
но это не сама Делфи.

вообще о чем тема, не вижу смысла как то...
с помощью приведений типов можно вполне хранить иные типы данных.
если обязателен класс, то можно и в класс завернуть, если нужна структура, то в чем трабл?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 15.07.2010, 15:19   #25
Korben5E
Форумчанин
 
Аватар для Korben5E
 
Регистрация: 13.07.2010
Сообщений: 346
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
это не поддерживает Делфи.
VCL=Visual Component Library
но это не сама Делфи.
т.е в Bulder-e следующая конструкция будет работать?

TLabel label(this);

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
вообще о чем тема, не вижу смысла как то...
с помощью приведений типов можно вполне хранить иные типы данных.
если обязателен класс, то можно и в класс завернуть, если нужна структура, то в чем трабл?
тут человек не понимает зачем в VirtualTreeView используют указатели при обращении к Node.
Non est culpa vin, sed culpa bibentis
Korben5E вне форума Ответить с цитированием
Старый 19.07.2010, 07:51   #26
AnTe
Форумчанин
 
Регистрация: 25.09.2008
Сообщений: 209
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
Вообще о чем тема, не вижу смысла как то...
с помощью приведений типов можно вполне хранить иные типы данных.
ННууу.. я не понял смысла хранения присоединённых данных таким мудрёным способом
Почему GetNodeData хранит указатель на указатель, а не просто указатель, как, например, в TTreeView?

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
если обязателен класс, то можно и в класс завернуть, если нужна структура, то в чем трабл?
Ну вот, кстати, тоже интересно. И это для меня реальная проблема. Я писал об этом здесь, повторю, покороче:

Положим, хочу присоединить структуру.
Код:
  TRec = record
    name: string;
    num: integer;
    obj: TObject;
  end;
Заполняю её:
Код:
procedure TfmTest.btnGoClick(Sender: TObject);
var
  NewNode: PVirtualNode;
  Rec: PRec;
begin
  VT.NodeDataSize := SizeOf(TRec);
  NewNode := VT.AddChild(VT.FocusedNode);
  Rec := VT.GetNodeData(NewNode);
  if Assigned(Rec) then
    with Rec^ do
    begin
      Name := 'Test';
      num := 0;
      Obj := TObject.Create;
      showmess(obj.ClassName); // Выводит "TObject"
    end;
end;
Пытаюсь получить данные:
Код:
procedure TfmTest.VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
 Data: PRec;
begin
 Data := Sender.GetNodeData(Node);
 if Assigned(Data) then
 begin
  CellText := Data^.Name; // работает
  CellText := Data^.Obj.ClassName; // не работает! в Obj лежит nil!
  end;
end;
Куда пропал объект? Почему он пропал?

Последний раз редактировалось AnTe; 19.07.2010 в 07:53.
AnTe вне форума Ответить с цитированием
Старый 19.07.2010, 08:23   #27
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

Никуда он не пропал. Все прекрасно работает.

Код:
procedure TForm1.VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var
 Data: PRec;
begin
 Data := Sender.GetNodeData(Node);
 if Assigned(Data) then
 begin
 case Column of
       0: CellText := Data^.Name;
       1: CellText := Data^.Obj.ClassName; 
     end;
 end;
end;
Баламут вне форума Ответить с цитированием
Старый 19.07.2010, 10:55   #28
AnTe
Форумчанин
 
Регистрация: 25.09.2008
Сообщений: 209
По умолчанию

Цитата:
Сообщение от Баламут Посмотреть сообщение
Никуда он не пропал. Все прекрасно работает.

Код:
...
case Column of
А в чём разница? Я специально убрал, чтобы не мешалось лишнее.

Ну тогда так:

Код:
procedure TfmTest.VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  Data: PRec;
begin
  Data := Sender.GetNodeData(Node);
  if Assigned(Data) then
    CellText := Data^.Obj.ClassName;
end;
Access violation at address 004D1A52 in module 'rfmTest.exe'. Read of address 00000000.

Хотя этот код работает превосходно:

Код:
procedure TfmTest.VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  Data: PRec;
begin
  Data := Sender.GetNodeData(Node);
  if Assigned(Data) then
    CellText := Data^.Name; 
end;
Куда пропал объект, ссылка на который хранится в поле записи? (его значение nil)
Изображения
Тип файла: jpg Безымянный.JPG (69.4 Кб, 147 просмотров)

Последний раз редактировалось AnTe; 19.07.2010 в 11:05.
AnTe вне форума Ответить с цитированием
Старый 20.07.2010, 01:41   #29
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

Выложи сюда архивом весь тестовый проект. Я своими силами не в состоянии смоделировать ситуацию, а потому буду до хрипоты утверждать, что все работает. И на всякий случай скажи версию VT и Делфи.
Баламут вне форума Ответить с цитированием
Старый 20.07.2010, 09:02   #30
AnTe
Форумчанин
 
Регистрация: 25.09.2008
Сообщений: 209
По умолчанию

Версия делфей 7.0 Build 4.453

Версия VT самая последняя, скачивал на позапрошлой неделе. Где посмотреть, не знаю, но на сайте, прошлогодняя новость звучит так:
Virtual Treeview update to version 4.8.5
навероне, оно


Выкладываю проект.

Если коротко - на форму кинул кнопку, назвал btnTest
обработчик
Код:
procedure TfmTest.btnTestClick(Sender: TObject);
var
  NewNode: PVirtualNode;
  Rec: PRec;
  i: integer;
begin
  VT.NodeDataSize := SizeOf(TRec);
  for i:=0 to 1000 do
  begin
  NewNode := VT.AddChild(VT.FocusedNode);
  Rec := VT.GetNodeData(NewNode);
  if Assigned(Rec) then
    with Rec^ do
    begin
      Name := 'Test_' + inttostr(i);
      num := 0;
      Obj := TObject.Create;
//      showmess(obj.ClassName); // Выводит "TObject"
    end;
  end;
end;
Кинул VirtualStringTree, назвал VT
Обработчик события OnGetText
Код:
procedure TfmTest.VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  Data: PRec;
begin
  Data := Sender.GetNodeData(Node);
  if Assigned(Data) then
//    CellText := Data^.Obj.ClassName;
    CellText := Data^.Name;
end;
В этом варианте всё работает. Моментально создаётся тысяча узлов.
Как только раскомментирую строку
CellText := Data^.Obj.ClassName; и комментирую ту, что была, получаю:

Access violation at address 004975A6 in module 'rfmTest.exe'. Read of address 00000000.
Вложения
Тип файла: rar VTW1.rar (1.6 Кб, 48 просмотров)
AnTe вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос по компаненту VirtualTreeView gyvenor Компоненты Delphi 13 28.02.2007 11:34