Сам по себе термин COM-dll — кривой. Хороший, правильный термин — COM-сервер.
Так вот COM-сервер — это «некто», кто порождает и отдаёт тебе ссылки на COM-объекты.
Бывают разные виды COM-серверов, и один из них, — внутрипроцессный (inprocess), — реализуется в виде отдельного PE-файла (это может быть dll, ocx, cpl и тому подобное), который подгружается в АП процесса.
Способ, которым COM-клиент запрашивает у COM-сервера создание объекта может быть любым: вплоть до отправки оконного сообщения. Обычно, чаще всего этот способ — вызов экспортируемой функции COM-сервера, но вообще говоря: конкретный способ не документирован.
Кроме того, при использовании внутрипроцессных COM-серверов, COM-клиент должен ещё и найти PE-файл, внутри которого реализован COM-сервер. Найти и загрузить его.
Технология ActiveX построена над COM и документирует некоторые вещи:
- Единый для всех способ обратиться к члену объекта по его строковому имени или проекто-совместимому идентификатору.
- Единый для всех способ получить море информации о COM-сервере.
- Единый для всех способ запросить у COM-сервера создание COM-объекта, при котором, к тому же, не трубется знать, где находится реализация COM-сервера.
Первое обеспечивается за счёт IDispatch, второе — благодаря TLB, а третье зиждется на регистрации COM-серверов в реесте и инкапсуляции нудного процесса загрузки COM-сервера + создания COM-объекта внутрь функции CoCreateInstance.
Таким образом, ActiveX-сервер это COM-сервер, который поддерживает три этих момента. А если конкретно: это COM-сервер, внутри которого лежит TLB, который умеет регистрировать сам себя в реестре и объекты которого поддерживают IDispatch (и возможно ITypeInfo).
Если что-то из этого не поддерживается, то COM-сервер вряд ли можно назвать ActiveX-сервером.
В то же время, COM-сервер — ничуть не устаревшее явление. Если возможности и техники, даруемые технологией ActiveX, не нужны, можно не реализовывать их поддержку и создавать обычный COM-сервер с product-specific-способом создания объектов.
Вот например DX-овые библиотеки — это внутрипроцессный COM-серверы. Но они не являются ActiveX-серверами. Нельзя создать экземпляр класса Direct3D вызовом CoCreateInstance. Класс Direct3D не зарегистрирован в реестре как создаваемый. Но экземпляр этого класса можно создать вызовом экспортируемой функции Direct3DCreate8 из библиотеки d3d8.dll, внутри которой реализован COM-сервер.
Так что ActiveX-сервер является таким же частным случаем COM-сервера, каким является COM-сервер, реализованный в виде DLL, по отношению к библиотеки DLL вообще.
VB по умолчанию создаёт ActiveX-сервера, то есть COM-сервера, поддерживающие то, что должен поддерживать сервер, желающий называться ActiveX-сервером.
Просто COM-сервер можно сделать с помощью FNDLL, пометив класс(ы) как PublicNotCreatable и экспортировав функцию, создающую экземпляр такого класса и возвращающего ссылку на него.
Тогда FNDLL убьёт экспорт ненужных функций (DllRegisterServer), потому как регистрировать нечего, библиотека станет нерегистрируемой, потеряет статус ActiveX-сервера и
Думаю, разжевал понятно.