Элемент управления TreeControlEx


Данный элемент представляет собой таблицу строки которой могут быть заключены во вложенные категории, дерево которых располагается в первом столбце этой таблицы

Понятия:

Элемент: обозначает одну строку таблицы - горизонтальная линия, строка заключающая в себя все столбцы таблицы. Ряд свойств, таких как иконки, состояние чекбокса или группировку можно задать только для элемента.
Столбец, колонка: обозначает вертикальную область пересекающую все элементы и определяющую точки выравнивания/размежевания содержимого элементов. Все элементы имеют одинаковое число столбцов. Характеристики столбцов, такие как ширина, положение, заголовок, общие для всех элементов.
Ячейка: прямоугольная область какого-либо элемента ограниченная в пределах какого-либо столбца.
Нулевой столбец: крайний левый столбец. В нём отображается дерево и ряд прочих свойств общих для элементов. Его невозможно переместить с этой позиции, а попытки сделать это будут изменять только уникальные свойства ячеек и столбцов.
Чекбокс: флажок, отображающийся в нулевом столбце. Предоставляет визуально удобный способ менять TVIS_CHECK состояние элемента.
Иконка: пользовательский графический образ отображаемый между чекбоксом и текстом.
+/-: нкопка управления состоянием категории. Отображается только если элемент имеет субэлементы. Управляет необходимостью отображать или не отображать субэлементы данной категории.
Категория, группа: набор элементов имеющих один общий родительский (корневой) элемент. Группы могут включать в себя другие кркппы.
Корневой элемент: Элемент не состоящий ни в одной категории. Такой элемент всегда отображается. Может быть или не быть корнем категории.
Субэлемент, дочерний: любой элемент заключённый в категорию.
Дочерние первой близости: элементы, имеющие родителем указанный, но не субэлеменьы этих субэлементов.

Управление:

Клавиши ­­­- стрелки используются для перемещения курсора соотвественно вверх/вниз и влево/вправо, однако если курсор находится в первом столбце то стрелка вправо разворачивает категорию, а влево - сворачивает. Избежать этого можно нажимая стрелки удерживая клавишу Ctrl. Клавиша Пробел изменяет сосояние чекбокса элемента, даже если отображение этого чекбокса отключено. Нажимая Пробел или левую кнопку мышки удерживая клавишу Crtl можно помечать элементы. Клавиша Shift + стрелки или левая кнопка мышки помечает группу элементов. Клавиши PageUp и PageDown перемещают курсор на олин экран вверх или вниз, клавиши Home и End перемещают курсор к первому и последнему элементу списка. Одиночные щелчки левой кнопко мышки перемещают курсор в указанную ячейку, помимо этого если под курсором находится чекбокс элемента - он меняет своё состояние или значёк +/- родительского элемента группы - сворачивает и разворачивает группу.
Наведя курсор мыши на вертикальные риски области заголовков столбцов таблицы и перемещая его зажав левую кнопку мыши можно менять ширину столбцов.

Пределы и ограничения:

* При числе строк более 65536 начнутся проблемы с прокруткой содержимого (16битное ограничение полос прокрутки в Windows), также эта величина соответственна суммарной ширине столбцов
* Число уровней, глубинна вложенности дерева, должна быть не более 65536 уровней. Какие либо проверки в этой области отсутствуют так что при перевышении неизбежны ошибки.
* Суммарное число элементов, отдельно столбцов и отдельно строк допустимо не более 2^32 - 2, однако реальное число гораздо меньше т. к. ресурсы ОЗУ исчерпаются гораздло ранее.
* Также однако возможны проблемы при пересечении порога (int) т. е. (2^32)/2.
! При получении данных элемента если текста в ячейке больше чем указанного буфера приёмника то скопированная часть строки НЕ БУДЕТ завершаться нулём

Наборы собственных характеристик частей контрола:

Элемент: обладает общим чекбоксом, пользовательским значком, набором субэлементов (категорией), режимом отображения их, состоянием выделенности (которое автоматически устанавливается в "выделено" если выделена хотя-бы одна из ячеек элемента. Определяется указателем на элемент.
Ячейка: обладает собственной строкой текста, 32битной пользовательской величиной lParam и состоянием выделенности. Определяется указателем на элемент и номером столбца.
Столбец: обладает собственной шириной, положением относительно других столбцов (номером по порядку) и строкой-заголовком. Определяется номером столбца. Нумерация столбцов начинается с нуля.

Коды ошибок:

Все коды ошибок получаются вызовом функции GetLastError(). В контроле используются следующие коды ошибок:
Числовое значение
Мнемоника
Описание
6
ERROR_INVALID_HANDLE В функцию передан неправильный указатель
8
ERROR_NOT_ENOUGH_MEMORY
ОС отказала в выделениии памяти. Может позникать если в компьютере критически не хватает оперативной памяти для хранения слишком большого числа элементов контрола.
14
ERROR_OUTOFMEMORY
Достигнуто предельно возможное число элементов. (смотри пределы и ограничения)
160
ERROR_BAD_ARGUMENTS
Значения агрументов неверны и/или недопустимы (неправильный аргумент функции)
267
ERROR_DIRECTORY
Указывает на попытку запроса иррационального действия. Например см. TVM_SETITEMPOSITION
1168
ERROR_NOT_FOUND Указанный элемент не найден. (возникает например при попытке получить сведения о элементе по неинициализированному указателю на элемент)
1169
ERROR_NO_MATCH
Указаный элемен недостижим (например существует, но невидим на экране при попытке получить координаты ограничивающего прямоугольника)

Использование контрола:

Сперва перед любым использованием следует вызвать функцию InitTreeControlEx(), выполняющую предварительную подготовку к использованию. Затем вызывается CreateWindowEx() с именем класса окна TreeControlEx для ANSI или TreeControlExW для UNICODE варианта контрола, стоит заметить что в виду ограничений ОС семейства WinNT UNICODE версия контрола совместно с этими ОС должна использоваться только совместно с UNICODE режимом компиляции исполняемого модуля приложения.
Также стоит учесть что в виду технических особенностей контрол создаётся имея один столбец, в связи с чем для установки заголовка первого (крайнего левого) столбца следует использовать сообщение TVM_SETCOLUMN.
Многопоточность
- контрол не реинтерабелен! Хотя не будет отказа (т.к. отсутствуют проверки) вызов функций контрола из разных потоков или процессов могут привести к непредсказуемым результатам.
x64 - математика и принципы работы логики контрола не допускают простой компиляции его в 64битном виде! В виду технических ограничений WinNTx64, а также особенностей архитектуры x64 процессоров контрол невозможно использовать в составе 64битных приложений

Установка иконок элементов дерева

Контрол позволяет для элементов в первом столбце устанавливать и включать отображение пользовательских значков (отображаются непосредственно перед текстом) (см. картинку)
Для этого следует сперва создать имэйджлист:
HIMAGELIST himl = ImageList_Create(16, 16, ILC_COLORDDB | ILC_MASK, 4, 1);
и добавить в него собственные значки
hico = ExtractIconA(hInst, "dir_file.ico", 0);
ImageList_AddIcon(himl, hico);
...

и присвоить контролу созданный имэйджлист:
SendMessage(hCtrl, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM) himl); //(что в целом можно сделать и сразу после его создания, до заполнения)
В готовом листе иконки должны располагаться в следующем смысловом порядке: (значок категории)"+"; "-"; (чекбокс) не отмечен; отмечен
Беспокоится об удалении имэйджлиста не стоит - контрол сам удалит его при собственном удалении


Зависимости:

Заголовок: TCEXclass.h
Исодные коды: TCEXclass.cpp; TCEXclassres.rc; icn-.ico; icn+.ico; icnS.ico; icnU.ico