Загадочные макросы



Загадочные макросы

Вернемся в файл ATLGLcpp, где кроме функций, перечисленных выше, присутствуют загадочные макросы. Их смысл довольно прозрачен, но разработчика не должны устраивать догадки, ему нужны более точные знания. Сопровождающая документация, особенно бета-версий, не всегда дает нужные объяснения, поэтому приходится искать их самостоятельно в заголовочных файлах, расположенных по адресу: ...\Microsoft Visual Studio.Net\Vc7\indude или ...\Microsoft Visual Studio.Net\ Vc7\atlmfc\include.

Покажем, как это делается на примере. Нас интересует смысл функциеподобной макроподстановки:

DECLARE_LIBID(LIBID_ATLGLLib)

В результате поиска в файлах по указанному пути (маска поиска должна быть *.h) находим (в файле ATLBase.h), что при разворачивании препроцессором этот макрос превратится в статическую функцию класса CATLGLModule:

static void InitLibldO throw ()

{

CAtlModule::m_libid = LIBID_ATLGLLib;

}

Теперь возникает желание узнать, что кроется за идентификатором LiBiD_ATLGLLib. Во вновь созданном коде файла ATLGM.c находим макрос:



MIDL_DEFINE_GUID(IID,

LIBID_ATLGLLib,ОхЕбОбОЗВС,Ox9DE2, 0x4563,

OxA7,0xAF,Ox8A,Ox8C,Ox4E,0x80,0x40,0x58);

узнав смысл которого мы сможем понять, чем является LiBiD_ATLGLLib. В вашем проекте цифры будут другими, но я привожу здесь те, которые вижу сейчас, для того чтобы быть более конкретным и не загружать вас абстракциями, которых и так хватает. В этом случае поиск не нужен, так как объявление макроса расположено двумя строчками выше. Вот оно:

#define MIDL_DEFINE_GUID(type,name,1,wl,w2,bl,b2,b3,Ь4, \ Ь5,Ьб,b7,b8)

const type name = \ {I,wl,w2, {b1,b2,bЗ,b4,b5,b6,b7,b8}

}

Подставив значения параметров из предыдущего макроса, получим определение LiBiD_ATLGLLib, которое увидит компилятор:

const IID LIBID_ATLGLLib =

{

0xE60605BC, 0x9DE2, 0x4563,

{ 0xA7,0xAF,0x8A, 0x8C,Ox4E, 0x80, 0x40, 0x58 }

}

Отсюда ясно, что LIВID_АТLGLLib — это константная структура типа IID. Осталось узнать, как определен тип данных II D.

В хорошо знакомом файле afxwin.h находим определение typedef GUID IID;. Про Globally Unique Identifier (GUID) сказано очень много, в том числе и в документации Studio.Net. Как мы только что выяснили, изучив работу макросов и LiBio_ATLGLLib, тип IID также используется для идентификации библиотек типов. Система применяет два типа GUID: строковый в реестре, и числовой в клиентских приложениях. Второй макрос, который вы видели в классе

CATLGLModule:

DECLARE_REGISTRY_APPID_RESOURCEID(IDR_ATLGL,

"{E4541023-7425-4AA7-998C-D016DF796716}")

(цифры мои, ваши будут другими) создает строковый GUID. При расширении он превратится в три статические функции класса, две из которых готовят текстовую строку того или иного типа, а третья регистрирует, в случае если bRegister==TRUE, или убирает из реестра эту строку по адресу HKEY_CLASSES_ROOT\APPID\:

static LPCOLESTR GetAppId ()throw ()

{

//====== Преобразование к формату OLE-строки

return OLESTR("{E4541023-7425-4AA7-998C-D016DF796716}") ;

}

static TCHAR* GetAppIdTO throw ()

{

//====== Преобразование к Unicode или char* строке

return _T("{E4541023-7425-4AA7-998C-D016DF796716}") ;

}

// Если bRegister==TRUE, то происходит запись в реестр,

// иначе - удаление записи

static HRESULT WINAPI UpdateRegistryAppId(BOOL bRegister) throw()

{

_ATL_REGMAP_ENTRY aMapEntries [] =

{

{ OLESTRC'APPID") , GetAppIdO }, { NULL, NULL }

};

return ATL::_pAtlModule->UpdateRegistryFromResource( IDR ATLGL, bRegister, aMapEntries);

В данный момент вы сможете найти в реестре свой ключ и ассоциированную с ним строку (ATLGL) по адресу:

HKEY_CLASSES_ROOT\AppID\

{E4541023-7425-4AA7-998C-D016DF796716}

При запуске приложения вышеописанные функции были вызваны каркасом приложения и произвели записи в реестр. Отметьте также, что в реестре появилась еще одна (симметричная) запись по адресу HKEY_CLASSES_ROOT \APPID\ATLGL.DLL. Она ассоциирует строковый GUID с библиотекой ATLGL.DLL. Рассматриваемая строка-идентификатор встречается еще в нескольких разделах проекта, найдите их, чтобы получить ориентировку: в ресурсе "REGISTRY" > IDR_ATLGL (см. окно Resource View) и в файле сценария регистрации ATL.GL.rgs (см. окно Solution Explorer).

Возвращаясь к первому макросу DECLARE_LIBID(LiBiojvTLGLLib), отметим, что скрытая за ним функция initLibid тоже была вызвана каркасом и использована для регистрации библиотеки типов будущего СОМ-объекта. Вы можете найти эту, значительно более подробную, запись по ключу (цифры мои):

HKEY_CLASSES_ROOT\TypeLib\

{E60605BC-9DE2-4563-A7AF-8A8C4E804058}



Содержание раздела