РЕДАКТИРОВАТЬ: Чувак, я не касался MFC с 2000 года. Я надеялся остаться таким до конца своей жизни. :-) В любом случае ...
По-видимому, волшебники развивались с прошлого века. Следующие шаги для добавления поддержки ATL COM и приложения MFC предназначены для VS 2008.
- Создание простого приложения на основе диалогового окна MFC под названием MFCTest. НЕ установите флажок Автоматизация в мастере.
- Щелкните правой кнопкой мыши проект и выберите Добавить / Класс ... В диалоговом окне выберите Простой объект ATL. Вы получите предупреждение о том, что в проект будет добавлена поддержка ATL.
- Откроется новый мастер с опциями для нового объекта ATL.
Вы должны быть сделаны.
Честно говоря, я не вижу смысла размещать здесь сгенерированный мастером код. Но если у вас есть дополнительные вопросы по отдельным частям этого кода, опубликуйте их в SO, и я вам помогу.
РЕДАКТИРОВАТЬ: Это постепенно превращается в статью. Если мы продолжим в том же духе, я мог бы даже опубликовать книгу. : -)
Если у вас есть простой объект ATL, интегрированный в проект MFC, вы можете добавить к нему интерфейс RTD. Вам нужно будет оба наследовать от интерфейса и добавить его в COM_INTERFACE_MAP
. Поскольку интерфейс RTD представляет собой интерфейс IDispatch
, вам придется наследовать ваш класс от IDispatchImpl <> и добавить IDispatch к COM_INTERFACE_MAP
, используя COM_INTERFACE_ENTRY2
(чтобы указать, что он реализован через IRtdServer
.
Я не очень знаком с тем, как работает RTD. Вам также может понадобиться добавить поддержку точек подключения COM в ваш класс, если Excel нужно добавить подписку на ваши обновления. Вот также ссылка для обновления ваших точек подключения в ATL знание.
Кстати, я наткнулся на это сообщение в блоге, в котором есть C ++ определения двух интерфейсов RTD . Возможно, они у вас уже есть, но я решил добавить их для полноты картины.
Самый простой способ - создать новый проект ATL EXE с помощью мастера VS и разрешить ему принимать участие в регистрации и управлении процессом. Остальное не так уж и отличается.
Если вам нужен конкретный образец, чтобы начать свое путешествие обратно в страну COM вне процесса, вы можете посмотреть на LABRADOR .
Несколько ссылок, которые могут вас заинтересовать:
РЕДАКТИРОВАТЬ: Если вам просто нужно знать, как зарегистрировать объект в вашем EXE с помощью COM, чтобы клиентские приложения могли CocreateInstance его, посмотрите CoRegisterClassObject . Однако:
- объект должен быть COM-объектом
- вам нужно реализовать фабрику классов для этого
- если вы хотите, чтобы управление процессами (т. Е. COM запускало ваше приложение по требованию), необходимо зарегистрировать ClassID в реестре
- если клиент собирается создать его через ProgID, ProgID необходимо зарегистрировать в реестре
- вам может понадобиться пользовательский прокси / заглушка dll, если вы делаете пользовательское упорядочение
- если ваше приложение имеет пользовательский интерфейс, вам придется изменить логику выключения, чтобы, когда пользователь закрывает пользовательский интерфейс, приложение не выходило до тех пор, пока не будет выпущена последняя ссылка COM на ваши объекты
РЕДАКТИРОВАТЬ 2: Я бы по-прежнему предлагал вам взглянуть на образец ATL вне процесса и на скелет, который сгенерирует мастер ATL, чтобы понять последовательность операций. Однако вам может потребоваться немного углубиться в код ATL, чтобы увидеть, что именно происходит.
Вот краткая версия процесса:
При запуске приложению необходимо проверить наличие определенного аргумента командной строки - / embedded . Если этот аргумент присутствует, это означает, что приложение запускается COm в ответ на вызов CoCO. В этот момент приложение может не отображать свой пользовательский интерфейс.
Независимо от того, показывает ли приложение пользовательский интерфейс или нет, оно должно регистрировать фабрики классов для любых объектов COM, которые оно предоставляет через API CoRegisterClassObject, о котором я упоминал выше.
Если приложение запускается через COM, оно может отключиться в последнем справочном выпуске COM. (Обычно это определяется с помощью дополнительного глобального счетчика ссылок, который увеличивается для любого объекта AddRef и уменьшается для любого объекта Release). Однако приложение не должно закрываться само по себе, если оно обнаружило, что пользователь взаимодействовал с его пользовательским интерфейсом. в таком случае отключение откладывается до тех пор, пока пользователь не закроет последний пользовательский интерфейс явным образом (чтобы упростить это обнаружение, приложение обычно не показывает свой пользовательский интерфейс, пока пользователь не попытается запустить его явно)
Если приложение было запущено пользователем и пользовательский интерфейс las закрыт, приложение должно проверить, имеются ли в нем какие-либо ссылки на COM-объекты. Если их нет, он может отключиться сам. Однако, если есть ссылки на COM, приложение должно скрыть пользовательский интерфейс, но продолжать работу, пока не будет выпущена последняя ссылка.
Если приложение достигло точки, в которой оно будет закрыто, оно должно отозвать все регистрации фабрики классов.