Учебник по Visual C++ .Net




Обращаемся к операционной системе - часть 2


Теперь займемся созданием вспомогательных функций, которые понадобились при разработке функции OninitialUpdate. Введите в файл LeftView.cpp реализацию функции GetSysimgList, объявление которой уже существует в файле интерфейса LeftView.h класса CLef tview:

void CLeftView::GetSysImgList()

{

SHFILEINFO info;

// Попытка получить описатель системного списка значков

HIMAGELIST hlmg = (HIMAGELIST)

::SHGetFilelnfо("С:\\",0, Sinfo,sizeof (info), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);

//=== Приписываем описатель системного списка

//=== изображений объекту CImageList

if (Ihlmg !m_pImgList->Attach(hlmg))

{

MessageBox(0,"He могу получить System Image List!");

return; }

//=== Связывание списка с элементом управления деревом m_Tree.SetlmageList(m_pImgList, TVSIL_NORMAL);

}

Функция SHGetFilelnfo позволяет получить информацию о каком-либо объекте файловой системы. Последний параметр уточняет смысл вопроса. Определяем его с помощью битовых констант SHGFI_SYSICONINDEX и SHGFI_SMALLICON, которые означают, что мы интересуемся индексами значков в системном списке и нам нужны маленькие значки. Вы помните, что Windows поддерживает значки двух типов: большие (32x32) и маленькие (16x16). Результатом вызова функции будет описатель (handle) всего списка значков, который мы затем должны связать с элементом m_Tree. Но сначала требуется прикрепить (attach) Windows-описатель списка к объекту класса CimageList, адрес которого мы храним в переменной m_pImgList.

Понятие прикрепить описатель (attach a handle) вы будете встречать достаточно часто, программируя в рамках MFC, но значительно реже, чем разработчики, базирующиеся на платформе SDK (Software Development Kit), которые не пользуются классами MFC. Вместо этого они используют многочисленные структуры и прямо вызывают функции API из программы на языке С или C++. При этом им иногда приходится писать в 5-10 раз больше кода. Итак, понятие прикрепить описатель означает примерно следующее: дать объекту класса ту функциональность, которой обладает Windows-объект, обычно описываемый структурой и адресуемый с помощью описателя (handle). Внутри многих классов MFC скрыто существуют Windows-описатели, которые должны быть правильно инициализированы. Часто, но не всегда, это делается без нашего участия. Иногда мы должны предпринять какие-то действия для инициализации описателя. В данном случае это можно сделать прямым присвоением, например m_pimgList->m_hImageList = himg; но такой способ менее надежен, так как в нем непосредственно запоминается какой-то адрес памяти. Содержимое по этому адресу система может изменить в результате наших же манипуляций с объектами, и тогда мы получим проблему под названием «Irreproducible Bug» (невоспроизводимая ошибка). Точнее будет сказать трудновоспроизводимая ошибка — самый неприятный тип ошибок, для борьбы с которыми идут в ход все средства (даже AssertValid и Dump). Значительно надежнее использовать метод Attach класса CimageList, так как в этом случае система будет следить за перемещениями структур, адресуемых описателем. При этом работает класс CHandleMap и его метод SetPermanent, которые, к сожалению, не документированы.




Содержание  Назад  Вперед