Здравствуйте.
Как известно, в ОС Windows существует несколько способов инициализации COM системы:
С помощью функции OleInitialize
С помощью функции CoInitializeEx
В моей программе планируется использовать перетаскивание файлов с помощью интерфейса IDropTarget и DirectShow. Причем DirectShow будет использоваться в нескольких потоках. Следовательно, COM система должна инициализироваться с помощью функции CoInitializeEx с флагом COINIT_MULTITHREADED. Но когда я инициализирую так COM систему функция RegisterDragDrop возвращает ошибку. Она требует, чтобы COM система инициализировалась с помощью функции OleInitialize. Но она инициализирует COM систему только в том потоке, в котором была вызвана.
Есть ли способ инициализации COM системы для нескольких потоках и чтоб функция RegisterDragDrop не возвращала ошибку?
Заранее благодарен
P/S Проект WINAPI+STL пишется в C++ MSVS 2015
Здравствуйте, Melamed, Вы писали:
M>...
M>Есть ли способ инициализации COM системы для нескольких потоках и чтоб функция RegisterDragDrop не возвращала ошибку?
Насколько я знаю, DirectShow может работать как в STA, так и в MTA (Single-Threaded Apartment / Multi-Threaded Apartment).
Вот здесь, например, используется CoInitialize(NULL), что равносильно CoInitializeEx с флагом COINIT_APARTMENTTHREADED, но при этом далее ниже
по тексту сказано, что "DirectShow supports the free-threading model, so you can also call CoInitializeEx with the COINIT_MULTITHREADED flag":
How To Play a File
https://learn.microsoft.com/en-us/windows/win32/directshow/how-to-play-a-file
Так что никто не запрещает вызвать OleInitialize, а затем в этом же потоке использовать и Drag-n-drop, и DirectShow
(OleInitialize — это функция, которая инициализирует STA и делает еще кое-что дополнительно).
А в других потоках, например, где только DirectShow, использовать COINIT_MULTITHREADED, как уже ответили выше.