Windows Management Instrumentation. Опрос свойств, методов и описателей. Разработка компонента WMIControl, страница 22

Кроме множества узлов, соответствующих дискам и папкам, мы собираемся ввести корневой узел с именем "My Computer". Поэтому целесообразно договориться о способе индексирования изображений, используемых деревом. Он должен соответствовать логике метода, приведенного ниже. Добавьте этот метод в класс FileSystemControl.

int GetImageID(string type, string name)

{

return

type == "3" ? 2 :  // LocalDiskDrive

type == "5" ? 4 :  // CDROMDrive

type == "2" ? name.StartsWith("A:") ? 8 : 6 : // RemovableDrive

type == "4" ? 10 : // NetworkDrive

type == "6" ? 12 : 0; // RAMDrive

}

Цель метода — выбор индекса изображения. Следующая таблица поясняет смысл его кода.

Индекс изображения

Тип узла

Состояние

0

My Computer

1

My Computer

Selected

2

LocalDisk

3

LocalDisk

Selected

4

CDROM

5

CDROM

Selected

6

Removable disk

7

Removable disk

Selected

8

Removable disk(A:)

9

Removable disk(A:)

Selected

10

Network disk

11

Network disk

Selected

12

Ram Drive

13

Ram Drive

Selected

14

Folder

15

Folder

Selected

16

Folder (System, Hidden)

17

Folder (System, Hidden)

Selected

Особенности работы с большим деревом

Настало время подумать о дереве объектов файловой системы. В нем должен быть узел "My Computer", в который мы вложим все доступные диски (логические, съемные, сетевые). После этого в узлы, соответствующие дискам, мы вложим узлы, отображающие папки и т. д.

Алгоритмы управления большими деревьями (а наше, как раз такое) довольно сложны и требуют достаточно высокой культуры программирования. Если задаться целью один раз (при запуске программы) заполнить все дерево, то из этого ничего хорошего не выйдет. Сначала я написал рекурсивную функцию анализа и заполнения всего файлового дерева при начальном запуске приложения. Оказалось, что эта процедура занимает 5-7 минут, в течение которых приложение выглядит мертвым. Правда, после этого дерево раскрывает свои ветви мгновенно, потому что оно имеет информацию о всех своих ветвях. Если логических дисков и папок много (а в сетевой системе их очень много), то программа будет молчать очень долго. Кроме того, дерево потребует недопустимое количество памяти.

Обычно используют другие варианты работы с большими деревьями. Один из них состоит в том, что при проверке объекта файловой системы (диска или папки) он не сканируется далеко вглубь. Дерево обгоняет выбор пользователя лишь на один (или более) уровней вложенности узлов. Достаточно заполнить лишь один уровня (тот, который не виден пользователю). Если этого не сделать, то закрытый узел не будет иметь маркера раскрытия. Затем, когда пользователь действительно раскроет узел (это событие надо обработать), следует продвинуться вглубь дерева еще на один уровень вложенности. Раскрываемая же на данном шаге ветвь, уже наполнена реальными сущностями, так как это было выполнено на предыдущем шаге движения вглубь дерева.

Такой прием обеспечивает постепенное наполнение дерева по сценарию, определяемому пользователем. Вновь раскрываемые ветви вносят некоторую задержку, но после схлопывания (collapse) какой-либо ветви ее повторное раскрытие (expand) происходит быстро, так как информация уже записана в дереве (объекте tree класса TreeView). Альтернативным вариантом решения проблемы считается параллельное сканирование файлового дерева в отдельном потоке (thread) процесса приложения и постепенное заполнение его найденными узлами.

Развитие компонента