Jun 03

Конкурс

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

Суть конкурса очень проста: написать статью, возможно не большую, по использованию данного компонента. В статье может быть описаны как основы, так и профессиональное использование. Как описание свойств, так и какие-то баги.

Учитывая, что я пока один организовываю данный конкурс (хотя, возможно кто-то еще захочет поучавствовать в спонсорстве), призовой фонд не большой - 50$. Возможно, он будет увеличен в дальнейшем.

Есть еще одно условие, чтобы принять участие в конкурсе. Вы можете разместить статью где угодно (хотя, я буду рад, если она будет размещена в этом блоге), но в статье обязательно должно быть указано, что она создана для участия в данном конкурсе и должна стоять ссылка на данный блог. Может это и не красиво выглядит, но мне так хочется ;) .

Желаю всем удачи.

P.S.: чуть не забыл. Конкурс продлиться до конца июня.


  1. Waik
     Add karma Subtract karma  +0
    Цитировать.

    Компонент интересный. С удовольствием почитаю статьи участников. Ссылка на уже существующую статью не открывается. Это только у меня vingrad не отвечает? Где-нибудь ещё эта статья выложена?

    1
  2. aktuba
     Add karma Subtract karma  +0
    Цитировать.
    Комментарий автора

    Только что проверил – ссылка открывается.

    2
  3. Nikitos
     Add karma Subtract karma  +0
    Цитировать.

    Мне удалось открыть эту ссылку только в FairFox`е, IE 7 повесился на ней.

    3
  4. AlexR
     Add karma Subtract karma  +0
    Цитировать.

    цитата:
    ==============
    Исходные коды примеров и полную версию самой статьи в формате Microsoft Word можно скачать по адресу:
    http://quadr0.pochta.ru/VirtualTreeview/virtualtreeview.zip

    Скомпилированные примеры можно взять отсюда:
    http://quadr0.pochta.ru/VirtualTreeview/figures.zip

    4
  5. aktuba
     Add karma Subtract karma  +0
    Цитировать.
    Комментарий автора

    AlexR: я в курсе. Ради интереса – попробуй скачай примеры ;)
    Если нужны – забирай.

    5
  6. AlexR
     Add karma Subtract karma  +1
    Цитировать.

    aktuba, не воспринимай в штыки,
    я ссылки скопировал для тех у кого статья не открывается :)

    Компонент конечно же мировой, использую его давно

    6
  7. Nikitos
     Add karma Subtract karma  +0
    Цитировать.

    AlexR, ссылки не работают.

    7
  8. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Честно говоря – учитывая существования упомянутой статьи – смысл написания еще одной как-то не очень просматривается. Потому как все, что нужно для работы с этим замечательным компонентом – в статье описано, и описано хорошо.

    …Лучше обратить внимание на EasyListview (http://mustangpeak.net) – построенном на аналогичном (виртуальном) подходе компоненте для реализации различных listview. Написан на чистом VCL, не наследует от контролов Windows, поддерживает Unicode (можно откомпилировать с поддержкой TntUnicode), возможности просмотра – как бы не больше, чем у listview, используемого в “Проводнике” у Vista’ы. Вот по нему статья была бы полезней – потому как, вроде, русской документации на него вообще не существует в природе..

    8
  9. aktuba
     Add karma Subtract karma  +2
    Цитировать.
    Комментарий автора

    Насколько я помню, EasyListView построен именно на VirtualTreeView, хотя, возможно, ошибаюсь. Но, как бы там ни было, VirtualTreeView мне более по душе, учитывая, что на нем я могу реализовать весь тот функционал, который есть в EasyListView.

    А упомянутая статья – лишь “верхушка айсберга”. Например, метод IterateSubTree там вообще не описан, хотя иногда он очень удобен и необходим.

    На будущее, для себя, отмечу. Возможно следующий конкурс и будет про EasyListView.

    9
  10. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Насколько я помню, EasyListView построен именно на VirtualTreeView, хотя, возможно, ошибаюсь.

    Нет, это совершенно отдельная разработка (изначально, если мне память не изменяет, проект назывался CoolBreeze). Хотя их SVN сейчас и хостится на том же самом http://www.soft-gems.net:8080/browse/ (проект MustangPeak).

    Но, как бы там ни было, VirtualTreeView мне более по душе, учитывая, что на нем я могу реализовать весь тот функционал, который есть в EasyListView.

    Хм… Что – действительно, прям вот весь функционал, как на вот этих скриншотах:

    DetailsView
    FilmStripView
    GridView
    IconView
    ListView
    SmallIconView
    ThumbNailView
    TileView

    ? :) (Прошу прощения за ехидство.)

    На мой взгляд, ни один из них не лучше другого – просто потому, что они для разного сделаны, и прекрасно друг друга дополняют. Если нужная иерархия, да еще и с колонками – тогда VirtualTreeview, если нужны список/таблица/превьюшки – причем, “на лету” переключаемые – то EasyListview.

    А упомянутая статья – лишь “верхушка айсберга”. Например, метод IterateSubTree там вообще не описан, хотя иногда он очень удобен и необходим.

    Ну-у-у, знаете!.. :) Этак можно сказать, что и базовый VCL не описан – потому как едва ли есть книги, которые скрупулезно описывают у каждого компонента буквально все свойства, методы, и особенности оных. Такой всеобъемлющий источник существует только один – Help. (Для продвинутых, понятно, есть и второй – исходники.) И писать его заменитель на русском – на мой, опять же, взгляд, особого смысла не имеет.

    10
  11. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Но, как бы там ни было, VirtualTreeView мне более по душе, учитывая, что на нем я могу реализовать весь тот функционал, который есть в EasyListView.

    Хм… Что – действительно, прям вот весь функционал, как на вот этих скриншотах:

    DetailsView
    FilmStripView
    GridView
    IconView
    ListView
    SmallIconView
    ThumbNailView
    TileView

    ? :) (Прошу прощения за ехидство.)

    На мой взгляд, ни один из них не лучше другого – просто потому, что они для разного сделаны, и прекрасно друг друга дополняют. Если нужная иерархия, да еще и с колонками – тогда VirtualTreeview, если нужны список/таблица/превьюшки – причем, “на лету” переключаемые – то EasyListview.

    11
  12. Nikitos
     Add karma Subtract karma  +0
    Цитировать.

    У меня вот такой вопрос. В чем главные различия, какие преимущества и недостатки Grid-ов и TreeView?
    Я всегда использовал разные Grid и на TreeView как-то не обращал внимание. Недавно понадобились “плюсики” – группировка строк (nodes), я нашёл TMS AdvStringGrid, который позволяет многоуровневые ноды. Вообще, корректно ли такое сравнение?

    12
  13. aktuba
     Add karma Subtract karma  +1
    Цитировать.
    Комментарий автора

    Отображение данных, в VirtualTreeView, легко сделать как в виде дерева, так и в виде таблицы. Но сами данные будут храниться в древовидной форме. В этом и есть главное отличие.

    Кроме того, в VirtualTreeView можно делать любой вывод + подключать любые редакторы полей. Например, такой.

    13
  14. aktuba
     Add karma Subtract karma  +0
    Цитировать.
    Комментарий автора

    Odysseos: да, весь этот функционал можно сделать на основе VT ;)

    Насчет-же документации – статьи для того и пишут, что по ним легче и проще изучать что-то новое, а не для того, чтобы создать еще один справочник.

    14
  15. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    aktuba: вот прям действительно – можно сделать FilmStrip и ThumbNail? :) Лукавите.

    15
  16. aktuba
     Add karma Subtract karma  +0
    Цитировать.
    Комментарий автора

    Нет, не лукавлю. Насколько я помню, FilmStrip и ThumbNail отличкаются только размером изображения. Значит, в зависимости от размеров текущего изображения и их количества, создаем определенное количество столбцов и нодов, и в каждом из них выводим нужное изображение. Для незадействованных ячеек (последние), запрещаем выделение. Все. Задача решена ;) .

    16
  17. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Разумеется, можно “руками” распределить все по колонкам, а можно обычным StringGrid’ом воспользоваться, а можно еще и без всяких List- и TreeView – просто вообще все самому “руками” отрисовать. А то, что трудоемкость будет во всех трех вариантах примерно одинаковая – ну, так нам же ж больше заняться нечем, кроме как собственные огороды на любой случай городить.

    …Отличие дерева от listview в том, что дерево принципиально “заточено” под отображение элементов сверху вниз. То есть – по принципу “один элемент – одна строка”. Строка может быть из одного столбца, может – из нескольких, но факта это не отменяет: один элемент – одна строка. Естественно, можно распределить элементы отображаемого множества не по принципу “один элемент – один node дерева”, а “один элемент – одна колонка одного node’а дерева” – и потом при изменении числа колонок (например – при resize’е контрола) заново перераспределять элементы исходного множества по node’ам/колонкам. И при изменении сортировки. и при вставке/удалении элементов.

    ListView же – изначально поддерживает разные способы отображения, как “одна строка – один элемент”, так и “несколько элементов на строку”, и пересчитывает взаиморасположение элементов в “сетке” сам. Причем – в случае FilmStrip – это даже не отображение вида “в ширину сколько влезет – дальше новая строка” – “а в ширину столько, чтоб в высоту влезло без scroll’а”. И в любом случае, где нет явной иерархии (иначе зачем вообще использовать дерево-то, без иерархии?..) – удобней пользоваться именно listview. Всякий инструмент хорошо для собственной области. И я в данном случае говорю не о конкретно EasyListview – а о listview вообще.

    Кстати – у EasyListview есть такая интересная возможность, как группировка. То есть – возможность по произвольным характеристикам разбить элементы на группы и показывать их группами (это, конечно, не древовидная иерархия – но возможность весьма полезная). Причем – в зависимости от типа отображения, группы могут показываться как по вертикали, как в дереве, так и по горизонтали.

    17
  18. aktuba
     Add karma Subtract karma  +0
    Цитировать.
    Комментарий автора

    Так а кто с этим спорит? Ты спросил, можно ли – я сказал “да”. Ты не поверил – я привел решение. Но я не говорил, что это легкий или правильный путь. EasyListView я использовал и он мне не понравился, если честно. Да, свои плюсы есть, но… Каждому свое, как говорится.

    18
  19. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Так а кто с этим спорит? Ты спросил, можно ли – я сказал “да”.

    Я не спрашивал “можно ли, извернувшись и из-под выподверта” – я спрашивал, можно ли это в нем сделать “из коробки” (что “извернувшись и из-под выподверта” можно сделать что угодно – в частности, как я уже сказал, хоть самому “руками” отрисовать – я прекрасно знаю). Ответ – нельзя. Потому что – принципиально только “таблица”.

    Да, свои плюсы есть, но… Каждому свое, как говорится.

    Еще раз повторюсь – должно быть не “каждому свое”, а “каждой задаче – свой инструмент”. Я прекрасно пользуюсь и тем, и другим компонентом в одних и тех же проектах – просто для разного, и не могу сказать, что какой-то из них мне нравится больше, нежели другой. Если иерархия – VirtualTreeview, если таблица/tbumbs – EasyListview. И они прекрасно уживаются.

    19
  20. aktuba
     Add karma Subtract karma  +0
    Цитировать.
    Комментарий автора

    Знаю, что уживаются. Пример показал уже. Но, я считаю, что EasyListView имеет очень ограниченную область применения. В фоторедакторе я столкнулся с кучей багов и глюков компонента – после этого не трогал и не собираюсь, т.к. компонент не годен для серьезной работы.

    VT – это не таблица, а заготовка. И использовать его надо соответственно – именно для этого и сделаны события и редакторы. Используя его только как таблицу/дерево, вы используете 15-20% функционала.

    По поводу “каждой задаче – свой инструмент” согласен, но с оговоркой – “каждой задаче – свой, надежный и практичный, инструмент. Для меня, в большинстве случаев, такой инструмент – VT. А ListView – это отросток, без которого в 99,99% случаев можно (а чаще – необходимо) обойтись.

    20
  21. Odysseos
     Add karma Subtract karma  +1
    Цитировать.

    Но, я считаю, что EasyListView имеет очень ограниченную область применения.

    Я же считаю ровно наоборот :)

    В фоторедакторе я столкнулся с кучей багов и глюков компонента – после этого не трогал и не собираюсь, т.к. компонент не годен для серьезной работы.

    Давно уже все поправлено.

    VT – это не таблица, а заготовка.

    Да и EasyListview – то же самое.

    И использовать его надо соответственно – именно для этого и сделаны события и редакторы.

    Все то же самое и в EasyListview.

    Используя его только как таблицу/дерево, вы используете 15-20% функционала.

    А вот здесь вот, как мне кажется, Вы уже перегибаете палку, пытаясь как раз “заткнуть VT все дыры” – потому что он – именно что дерево. Да, гиперудобное, да, которое можно сделать таблицей – но все остальные его использования, не в виде дерева (пусть и странно выглядящего в результате собственных доработок под надобности) – выглядят, при наличии более подходящих инструментов, по меньшей мере странно.

    …Кстати – а не подскажите ли, а как еще можно использовать VT, кроме как дерево/таблицу? А то у меня что-то даже и фантазия пасует. (Аналог ObjectInspector’а на VT – и прочие в-ту-сторону-ответвления – не предлагать: это тоже дерево, с одноуровневой иерархией (скорей даже – именно группировкой) и редакторами.)

    А ListView – это отросток

    Еще раз: listview вообще – это совершенно отдельный класс контролов, которые широко используются, например, самой Windows (к примеру – любое окно “Проводника” с файлами – это именно что listview). А если говорить про конкретно EasyListview – то это совершенно самостоятельный проект, никак не зависимый от VT, ничего от него не взявший (общего у них – сама идея виртуальности; ну да ни тот, ни другой родоначальниками оной не являются – любой list-, хоть -box, хоть -view в базовой VCL можно сделать виртуальным; да даже больше – и нижележащие windows’овые контролы – тоже).

    Появился EasyListview изначально из попытки сделать набор компонентов, который позволит делать аналоги Windows Explorer’а (VirtualShellTools), не пользуясь контролами самой Windows. Для отображения дерева папок авторы написали наследника от VirtualTreeview, а вот для отображения содержимого папок – свой собственный Listview, который позже выделили в отдельный проект. И ориентируется он по возможностям – на то, чтоб “переплюнуть” по возможностям стандартный listview в “Проводнике” Windows.

    без которого в 99,99% случаев можно (а чаще – необходимо) обойтись.

    Ну – это, очевидно, у кого какие задачи. Мне вот, например – дерево нужно существенно реже.

    21
  22. GL
     Add karma Subtract karma  +0
    Цитировать.

    Odysseos дай плиз ссылку как хоть элементарно работать с easylistview (создавать, удалять, изменять элементы в группах, сами группы и т.п.), всё перерыл ниче не находится в инете:(

    22
  23. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    GL Ну дык там же демки есть, в которых как раз основы вполне наглядно излагаются.

    23
  24. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.
    24
  25. aktuba
     Add karma Subtract karma  +0
    Цитировать.
    Комментарий автора

    Можно и в том и в другом компоненте подобное реализовать.

    25
  26. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    Можно и в том и в другом компоненте подобное реализовать.
    В том числе и связь с БД “в обе стороны”?

    26
  27. aktuba
     Add karma Subtract karma  +0
    Цитировать.
    Комментарий автора

    В том числе и связать с базой, например через обработчики.

    27
  28. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    Изучил указанную статью. Нашёл почти все ответы на свои вопросы. Не скажу что всё пока предельно ясно, но в общем направления работы достаточно конкретизировались. Единственное, чего нигде не могу найти – как всё-таки заставить VT отрисоваывать “плитку” – то есть сначала по горизонтали, пото по вертикали, как в проводнике Windows или при просмотре Thumbnails в каком-нибудь просмотровщике картинок?!?

    28
  29. aktuba
     Add karma Subtract karma  +0
    Цитировать.
    Комментарий автора

    В VT немного другой принцип отрисовки – ячейки. Они могут отрисовываться не по порядку.

    29
  30. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Kotъ-Begemotъ VT “из коробки” не умеет рисовать “плитку” – ее надо рисовать “руками” (то есть – делить ширину контрола дерева на желаемую ширину элементов, создавать такое количество колонок, а потом в каждом cell’е рисовать нужный элемент, основываясь на номере нода и номере колонки). Для Вашей задачи гораздо лучше подойдет именно EasyListview.

    30
  31. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    Для Вашей задачи гораздо лучше подойдет именно EasyListview.
    Смотрел и его. В режиме Thumbnails вроде бы то, что нужно, но пока не понял, можно л вместо какртинки отображать скажем, фон нужного цвета, и несколько надписей с учётом нужных цветов, расположения, и так далее…

    31
  32. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Kotъ-Begemotъ Конечно, можно. Есть обработчик


    OnItemThumbnailDraw(Sender: TCustomEasyListview;
    Item: TEasyItem;
    ACanvas: TCanvas;
    ARect: TRect;
    AlphaBlender: TEasyAlphaBlender;
    var DoDefault: Boolean);

    , в котором мы получаем рисуемый в данный момент элемент, холст, прямоугольник отрисовки – в нем как раз можно нарисовать элемент так, как хочется. Если мы нарисовали элемент сами – то должны сбросить значение DoDefault, если же хотим, чтобы данный элемент нарисовался самим контролом – то, наоборот, выставляем значение DoDefault.

    32
  33. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    Понятно, спасибо! Жаль, что по EasyListView нет такого подробного документа как для VT :) Да вообще в поставке даже описания свойств и методов нет, поэтому сложно сразу понять что к чему…

    33
  34. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    Odysseos
    Никак не могу попасть в обработчик OnItemThumbnailDraw :( Точка останова поставленная на код внутри обработчика вообще не срабатывает :( Видимо мешает установка какого-то свойства, но перебрал всё что мог, не могу найти :( (( Подскажите, пожалуйста, в какую сторону копать?

    34
  35. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Kotъ-Begemotъ
    Собственно, вопрос первый – а какая версия ELV? Использовать нужно последнюю с svn. Во-вторых – а режим Thumbnail или FilmStrip вообще включен?

    …Если мы посмотрим исходный код ELV, то обнаружим, что на пути к вызову OnIntemThumbnailDraw есть такие развилки:

    1. if Item.Visible then … – если элемент вообще видим

    2. PaintBefore – если создать наследника от ELV и там переопределить PaintBefore, чтоб он сам все рисовал, и возвращал Handled = True, то стандартная отрисовка вызываться не будет _вообще_ (тут, как я понимаю, явно не Ваш случай)

    3. if OwnerListview.IsThumbnailView – True вернется, если выстаывлен режим elsThumbnail или elsFilmStrip

    То есть – если выполнены условия Item.Visible и ListView.View in [elsThumbnail, elsFilmStrip] – то обработчик вызваться _обязан_. Если не вызывается – скиньте мне тестовый проект.

    35
  36. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    Odysseos
    Версия ELV самая последняя (на работе не установлено, поэтому не могу сказать номер), качал буквально на днях с официального сайта. Тут дело было видимо вот в чём: Я взял один из простеньких примеров, идущих в поставке, и в нём пытался задавать обработчик OnItemThumbnailDraw и он не срабатывал. А когда я попытался то же сделать используя код примера FullDemo – обработчик заработал…
    Так что, желаемого внешнего вида я уже практически добился, теперь занимаюсь связкой с базой данных…
    Спасибо за советы! Конечно, очень не хватает хотя бы справочника по свойствам-методам компонента, приходится только разбирая примеры смотреть, а в примерах тоже не всё рассмотрено подробно.

    36
  37. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    Odysseos
    Поаробовал еще раз. Открыл один из проектов входящих в демо к ELV:
    \EasyListview\Demos\Basic\Interfaced (Jim)
    и добавил в обработчик OnItemThumbnailDraw следующий код (прекрасно, почему-то работающий, будучи внедрён в другой проект – \EasyListview\Demos\Fulldemo):

    procedure TForm1.EasyListview1ItemThumbnailDraw(
    Sender: TCustomEasyListview; Item: TEasyItem; ACanvas: TCanvas;
    ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
    var
    UnitName: String;
    TW, X: Integer;
    begin

    DoDefault := False;

    ACanvas.Brush.Style := bsSolid;
    if Item.Index mod 2 = 0 then
    ACanvas.Brush.Color := clGreen
    else
    ACanvas.Brush.Color := clMoneyGreen;

    ACanvas.FillRect(ARect);
    if Item.Selected then
    ACanvas.Font.Color := clRed
    else
    ACanvas.Font.Color := clBlue;
    ACanvas.Font.Style := [fsBold];
    uNitName := IntToStr(Item.Index+1);
    TW := ACanvas.TextWidth(uNitName);
    X := ((ARect.Right-ARect.Left-TW) div 2);
    ACanvas.TextOut(ARect.Left+X, ARect.Top+2, uNitName);
    end;

    Запускаю, генерирую несколько десятков Items, переключаюсь в вид Thumbnail и… ничего. Обработчик OnItemThumbnailDraw не выполняется :( ((
    Могу скинуть проект, подскажите, только на какой адрес.

    37
  38. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Kotъ-Begemotъ
    Посмотрите контакты в профиле в моем ЖЖ (ссылка на него есть при наведении на мой ник).

    38
  39. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    Вроде немного прояснилось…
    Получается вот как:
    Если я “на пробу” заполняю список произвольным количеством элементов с помощью
    Group.Items.AddVirtual; // то метод ItemThumbnailDraw вызывается корректно.
    А вот если я для загрузки своих данных, скажем из БД заполняю создаваемую мной структуру-класс и добавляю элементы в список:
    Group.Items.AddInterfaced(UnitData); // метод ItemThumbnailDraw НЕ ВЫЗЫВАЕТСЯ.

    Может я что-то не так делаю?

    39
  40. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    Odysseos
    Посмотрите контакты в профиле в моем ЖЖ (ссылка на него есть при наведении на мой ник).
    У меня нет эккаунта ЖЖ, поэтому, как я понимаю сообщение я отправить не могу? А других вариантов связи я там что-то тоже не нашёл :(

    40
  41. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    А еще конкретнее, в случае AddInterfaced при “ручной” перерисовке Thumbnails вызывается:

    procedure TEasyItemInterfaced.ThumbnailDraw(ACanvas: TCanvas; ARect: TRect;
    AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
    var
    ThumbInf: IEasyThumbnail;
    begin
    if Supports(DataInf, IEasyThumbnail, ThumbInf) then
    ThumbInf.ThumbnailDraw(ACanvas, ARect, AlphaBlender, DoDefault)
    end;

    И… не отрабатывает. Supports возвращает False.

    41
  42. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Kotъ-Begemotъ

    Там перечислены номер ICQ, имя в Google-Talk (оно же – обычное “мыло” на gmail.com) и имя в Jabber’е (это нечто вроде “аськи”, но не “аська”, протокол обмена иной). Проще всего, видимо – послать мне письмо на gmail-овский адрес.

    42
  43. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Kotъ-Begemotъ

    Я AddInterfaced не пользовался, но – счас глянул в исходники ELV – и осмелюсь предположить, что Вы при вызове AddInterfaced в первом параметре (который const DataInf: IUnknown) передаете IUnknown от объекта, который не поддерживает IEasyThumbnail – только в этом случае Supports вернет False.

    …Собственно – а зачем Вы вообще пользуетесь AddInterfaced, а не обычным Add? То есть – на то имеется какая-то причина (с TEasyItem должны быть связаны именно какие-то интерфейсы), или просто “так захотелось”?

    43
  44. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    Odysseos
    Собственно – а зачем Вы вообще пользуетесь AddInterfaced
    Дело в том, что насколько я понял из примеров, нужно использовать AddInterfaced, чтобы потом была возможность “достучаться” до свойств этого объекта. Иными словами, мне нужно создать для каждого Item некую структуру (класс) заполнив её значениями из БД, и потом (в частности в той же процедуре OnItemThumbnailDraw по Item достучаться до этой структуры, и вытащить значения нужных полей, в соответствии со значениями которых и будет производиться отрисовка. Возможно я что-то неправильно понял?

    44
  45. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    Odysseos
    Там перечислены номер ICQ, имя в Google-Talk (оно же – обычное “мыло” на gmail.com) и имя в Jabber’е (это нечто вроде “аськи”, но не “аська”, протокол обмена иной). Проще всего, видимо – послать мне письмо на gmail-овский адрес.
    Не видно этой информации. Видно недоступна незарегистрированным в LJ пользователям. Ни аськи ни имени в GT мне не показывает…

    45
  46. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Kotъ-Begemotъ

    Мдя… А оставьте тогда здесь Вашу “аську” – я Вас сам добавлю. (Тем более, что по иному-то все равно по “аське” со мной не связаться – из-за чертовых спаммеров я отключил прием запросов на авторизацию и вообще всех событий от “пользователей-не-в-листе”… Я потому и не хочу “светить” тут контакты – спам стал вельми серьезной проблемой.)

    46
  47. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Kotъ-Begemotъ

    Чтобы вот при таком вызове:

    Group.Items.AddInterfaced(UnitData);

    сработало все так, как Вы предполагаете, надо класс UnitData объявить вот так:

    TUnitData = class(TInterfacedObject, IEasyThumbnail)

    , и самому написать методы, которые он отнаслеует от IEasyThumbnail – который там всего один, собственно:

    procedure ThumbnailDraw(ACanvas: TCanvas; ViewportRect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);

    Вот в этом методе самого, таким образом описанного, класса TUnitData, и пишется отрисовка картинка, и Supports вернет True, и метод этот будет вызван.

    47
  48. Odysseos
     Add karma Subtract karma  +0
    Цитировать.

    Kotъ-Begemotъ

    На самом деле, AddInterfaced стоит использовать, только если четко понимать, что и как он делает – ну и вообще весь механизм работы интерфейсов.

    В Вашем случае можно сделать все гораздо проще – в обычный Add можно передать параметр Data: TObject = nil – то есть, описываете TUnitData безо всяких интерфейсов, с теми свойствами и методами которые Вам нужны для работы с БД:

    TUnitData = class(TObject)

    end;

    , при создании нового элемента – создаете сначала экземпляр класса TUnitData, а потом передаете его в качестве параметра для функции Items.Add:

    var
    unit_data: TUnitData;
    item: TEasyItem;
    begin
    unit_data := TUnitData.Create(…);
    item := Group.Items.Add(unit_data);
    end;

    А далее во всех обработчиках, которые получают Item, элементарно приводим свойство Item.Data класса TObject к нашему классу TUnitData.

    То есть:

    procedure TfrmMain.elvGridItemThumbnailDraw(Item: TEasyItem; …);
    var
    unit_data: TUnitData;
    begin
    unit_data := (Item.Data as TUnitData);

    end;

    При такой работе – надо не забыть, что созданный экземпляр класса TUnitData надо непременно разрушить, когда сам ELV будет разрушен – для этого надо задаьб обработчик ELV OnItemFreeing, в котором как раз и вызвать деструктор для поля Data у Item’а, вот так:

    procedure TfrmMain.elvGridItemFreeing(Item: TEasyItem);
    begin
    Item.Data.Free();
    end;

    48
  49. Kotъ-Begemotъ
     Add karma Subtract karma  +0
    Цитировать.

    Odysseos
    Спасибо, большое! Сегодня обязательно попробую реализовать это на практике :) Остаётся “изнутри” метода отрисовки Thumbnail получить доступ к свойствам класса по Item.
    Моя аська 413669674 запроса на авторизацию нет.

    49
  50. Kotъ-Begemotъ
     Add karma Subtract karma  +1
    Цитировать.

    Odysseos
    Еще раз спасибо! А то действительно запутался несколько с интерфейсами…

    50
  51. marDuk
     Add karma Subtract karma  +0
    Цитировать.

    ссылка с поста только у меня не открывается?

    51
  52. AnTe
     Add karma Subtract karma  +0
    Цитировать.

    Подкажите, пожалуйста, как в VirtualTreeView привязать к узлам дерева объекты?

    в узлах TreeView от делфей, есть прекрасное свойство Data, которое имеет тип pointer. Через это свойство я и привязывал к узлу свой объект.

    В VirtualTreeView механизм какой-то муторный. Внутри хранятся данные типа “запись”, доступ – через мудрёный метод GetNodeData(Node). Сегодня уже попробовал сделать так:

    PRec = ^TRec;
    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;

    52
  53. AnTe
     Add karma Subtract karma  +0
    Цитировать.

    Вроде разобрался…. Но всё равно, не покидает ощущение “странности”, в реализации компонента.

    Итак, бился полчаса над задачей.
    Имеем

    TreeView – свойство Data: Pointer
    VirtualTreeView – метод GetNodeData: Pointer;

    пишу две процедуры

    procedure TfmTest.btnTreeViewClick(Sender: TObject);
    var TN: TTreeNode;
    begin
    TN := TreeView1.Items.AddFirst(nil, ‘First’);
    TN.Data := TObject.Create; // положил
    ShowMessage(Tobject(TN.Data).ClassName); // вывел, успешно
    end;

    procedure TfmTest.btnVirtualTreeViewClick(Sender: TObject);
    var
    NewNode: PVirtualNode;
    begin
    VT.NodeDataSize := SizeOf(TObject);
    NewNode := VT.AddChild(nil, TObject.Create); // положил
    ShowMessage(Tobject(VT.GetNodeData(NewNode)).ClassName); // вывел, неуспешно, т.к. по какой-то причине нужно использовать p^
    end;

    ShowMessage(Tobject(VT.GetNodeData(NewNode)^).ClassName);
    Работает превосходно

    После разбирательств выяснена причина, в методе GetNodeData:
    Result := PByte(@Node.Data) + ….
    т.е. реально результат возращает указатель, на указатель!
    потому то крышечку и надо ставить

    я всё никак не пойму, с какой целью эти танцы с бубном производятся?
    неужто, чтобы данные типа record хранить в дереве?
    ЗАЧЕМ??

    53

Поделитесь вашими мыслями

Поддерживаемые теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>