Пишу shell extension (по руководству Michael Dunn, но без ATL), которое должно добавлять пункты в контекстное меню explorer-а. Реализовал интерфейсы IShellExtInit и IContextMenu, однако Windows упорно отказывается запрашивать интерфейс IContextMenu.
Кроме того, компонент по-разному ведет себя при вызове меню на рабочем столе и в окне explorer-a. Если, вызывая контекстное меню на рабочем столе, система по крайней мере вызывает метод IShellExtInit::Initialize, то при вызове из explorer-а не происходит даже этого! Класс просто создается, а потом разрушается.
КД>Очень странная реализация QueryInterface. Как минимум для IID_IContextMenu нужно было использовать КД>
КД>*ppv=static_cast<IContextMenu*>(this);
КД>
Спасибо, часть проблем решилась с внесением данной поправки.
Однако я не совсем понял, почему в данном случае необходимо применять static_cast, ведь мы возвращаем указатель на класс через void*, и, таким образом, не должно происходить сужение типа...
И еще, почему
Как минимум для IID_IContextMenu нужно было использовать...
Это не относится в той же мере и к IID_IShellExtInit?
Здравствуйте, dkotlyarov, Вы писали:
D>Спасибо, часть проблем решилась с внесением данной поправки. D>Однако я не совсем понял, почему в данном случае необходимо применять static_cast, ведь мы возвращаем указатель на класс через void*, и, таким образом, не должно происходить сужение типа...
static_cast обеспечивает корректное "преобразование" this к указателю на базовый класс IContextMenu. А именно, возвращает указатель, который ссылается на тот участок памяти, где начинаются данные интерфейса IContextMenu — там только указатель на таблицу виртуальных методов хранится.
присваивание вида
*ppv = this;
в твоем случае всегда возвращало указатель на первый в списке наследуемый класс — IShellExtInit. Для IID_IShellExtInit, IID_IUnknown это работало, а для IID_IContextMenu — нет
D>И еще, почему
Как минимум для IID_IContextMenu нужно было использовать...
Это не относится в той же мере и к IID_IShellExtInit?
И к нему, в принципе, тоже. А для IUnknown можно, например, возвращать тот же указатель, что и для IShellExtInit
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Пункт меню успешно добавляется при вызове контекстного меню на рабочем столе, а при вызове из explorer-а — нет
Я определил последовательность вызовов методов CShellExt в случае с рабочим столом и с explorer-ом. Из explorer-а почему-то вообще не вызывается IShellExtInit::Initialize и не запрашивается интерфейс IContextMenu...
D>Пункт меню успешно добавляется при вызове контекстного меню на рабочем столе, а при вызове из explorer-а — нет D>Я определил последовательность вызовов методов CShellExt в случае с рабочим столом и с explorer-ом. Из explorer-а почему-то вообще не вызывается IShellExtInit::Initialize и не запрашивается интерфейс IContextMenu...
Решил поднять эту бородатую ветку потому что столкнулся с идентичной проблемой и не нашёл явного ответа. Дело в том что компонент неправильно зарегистрирован в реестре, не хватает ключа ThreadingModel=Apartment. Вот и всё решение.