Self-unregistration в СОМ-серверах MFC
От: Евгений Щербатов  
Дата: 22.03.02 11:15
Оценка: 30 (1)
Статья:
Добавление механизма self-unregistration в СОМ-сервера, созданные на основе библиотеки MFC
Автор(ы): Евгений Щербатов
Дата: 29.05.2001

Статья посвящена реализации механизма self-unregistration в СОМ-серверах, созданных на базе библиотеки MFC. Эта возможность, просто необходимая для любого нормального СОМ-сервера, не добавляется в MFC-приложения по умолчанию.


Авторы:
Евгений Щербатов

Аннотация:
Статья посвящена реализации механизма self-unregistration в СОМ-серверах, созданных на базе библиотеки MFC. Эта возможность, просто необходимая для любого нормального СОМ-сервера, не добавляется в MFC-приложения по умолчанию.
Вывод
От: alexdr Россия  
Дата: 23.03.02 11:15
Оценка:
Мораль проста: пишем на ATL, в крайнем случае — с поддержкой MFC
Re: Self-unregistration для CDocument
От: Constructor  
Дата: 02.07.04 07:38
Оценка:
Здравствуйте, Евгений Щербатов, Вы писали:

>Статья посвящена реализации механизма self-unregistration в СОМ-серверах, созданных на базе библиотеки MFC.


Интересная картина с регистрацией SDI (MDI) сервера.
При создании проекта Вы требуете установит галогку Automation в аппвизарде. Вам эта галочка нужна для инициализации СОМ. В случае с SDI галочка, как известно, делает из класса CDocument сервер автоматизации. Вы предлагаете и в SDI добавить еще классы-сервера, как для DLL. А я вот задумался, зачем добавлять еще классы-сервера, если CDocument и так уже сервер. Стал смотреть, как устроен COleTemplateServer.

COleObjectFactory::UpdateRegistryAll() вызывает у всех фабрик UpdateRegistry(BOOL).

Логично было бы предполочить, что COleTemplateServer::UpdateRegistry(BOOL) регистрирует CDocument как сервер. На деле не совсем так. В COleTemplateServer введена дополнительная функция void UpdateRegistry(OLE_APPTYPE, LPCTSTR*, LPCTSTR*) и мастер прописывает известную регистрацию:

m_server.UpdateRegistry(OAT_DISPATCH_OBJECT);
COleObjectFactory::UpdateRegistryAll();


UpdateRegistry(OLE_APPTYPE, LPCTSTR*, LPCTSTR*) в конечном итоге вызывает AfxOleRegisterServerClass, как и UpdateRegistry(BOOL). Получается, при регистрации CDocument AfxOleRegisterServerClass вызывается дважды.

Описанные вещщи меня насторожили. Еще больше меня насторожил предлагаемый способ un-регистрации:

if( cmdInfo.m_nShellCommand == CCommandLineInfo::AppUnregister )
{
    m_server.UpdateRegistry(OAT_DISPATCH_OBJECT);
    COleObjectFactory::UpdateRegistryAll(FALSE);
}


Получается, что при un-регистрации CDocument еще раз регистрируется, а потом уж un-регистрируется. Как-то корявенько...

В COleTemplateServer UpdateRegistry(BOOL) не переопределена. Далее, проверив исходники CDocument и не найдя там макросов DECLARE_OLECREATE_EX и IMPLEMENT_OLECREATE_EX, я, грешным делом, подумал, что для CDocument un-регистрация не выполнится. Я проверил с помошью regedit. Очень удивился, когда регистрация исчезла .

Оказывается, в CWinApp::ProcessShellCommand есть строки:

//...
// If we've been asked to unregister, unregister and then terminate
case CCommandLineInfo::AppUnregister:
    {
        UnregisterShellFileTypes();
        BOOL bUnregistered = Unregister();
// ...


Далее, в CWinApp::Unregister():

//...
POSITION pos = GetFirstDocTemplatePosition();
while (pos != NULL)
{
    CDocTemplate* pTempl = GetNextDocTemplate(pos);
    if (pTempl != NULL)
        pTempl->OnCmdMsg(0, CN_OLE_UNREGISTER, NULL, NULL);
}
//...


В конечном итоге вызывается

BOOL COleTemplateServer::OnCmdMsg(UINT nID, int nCode, void* pExtra,
    AFX_CMDHANDLERINFO* pHandlerInfo)
{
    BOOL bReturn;
    if (nCode == CN_OLE_UNREGISTER)
        bReturn = Unregister();
    else
        bReturn = COleObjectFactory::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);

    return bReturn;
}


В COleTemplateServer::OnCmdMsg стоит вызов невиртуальной Unregister, которая и удаляет соответствующие записи из реестра. Что интересно, что Unregister есть и в COleObjectFactory и ничего не делает.

Почему в COleTemplateServer не переопределили UpdateRegistry(BOOL), а вместо этого переопределили OnCmdMsg с такими хитрыми условиями, для меня остается загадкой...

Такое впечатление, что механизм регистрации и un-регистрации делали последовательно несколько человек, как в том мультике про письмо из Простоквашина.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.