Вернемся в файл 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}