#windows-shell #windows-explorer #shell-extensions #common-dialog
Вопрос:
В Windows 7 я разработал расширение пространства имен оболочки (NSE), которое представляет иерархию данных, очень похожую на файловую систему. Его точкой соединения является рабочий стол. Я могу щелкнуть [ ] каждого узла в элементе управления дерева проводника Windows, чтобы развернуть этот узел. Когда я нажимаю на папку в древовидном представлении, я вижу список «папок» и «файлов», как и ожидалось, в представлении, представленном DefView. Если я дважды щелкну по «файлу», DefView послушно вызовет мою соответствующую папку IShell::CreateViewObject, чтобы запросить IContextMenu, а затем в конечном итоге вызоветIContextMenu::Команда вызова, в этот момент я выполняю ShellExecuteEx с классом LP, установленным в расширение «файла». Затем проводник послушно запускает соответствующее приложение EXE в соответствии с расширением «файл» с моим странным путем «файл», указанным в качестве аргумента командной строки. Однако, если я дважды щелкну по одной из своих «папок» в представлении DefView, Проводник откажется просматривать папку. Анализ стека вызовов показывает, что Проводник пытается выполнить некоторую проверку зон на моих странных путях к «файлам». Я попытался возиться сПанель управления->Параметры Интернета->>Безопасность>> зоны, добавив мои странные пути к файлам в различные зоны, но это не сработало. Из стека вызовов я вижу, что существует две проверки зон: первичная и вторичная. Я предполагаю, что я мог бы обойти это с помощью грубой силы, но я хотел бы знать санкционированный способ обойти эти проверки зон или, скорее, заставить Проводника просматривать мои «папки». Как ни странно, у IFileDialog нет этой проблемы, и он без колебаний просматривает мои «папки». Я также попытался добавить следующий код в свой IShellFolderView::MessageSFVCB:
switch (uMsg)
{
case SFVM_GETZONE:
{
DWORD zone = URLZONE_TRUSTED;
* ((DWORD *)lParam) = zone;
}
return S_OK;
...
Это не помогло.
У меня также есть сильное ощущение, что мое перетаскивание будет заблокировано по той же основной причине.
Есть какие-нибудь идеи?
Вот (частичный) стек вызовов:
MyDLL.dll!MyShellFolder::GetAttributesOf(unsigned int uCount, const _ITEMIDLIST * * aPidls, unsigned long * pdwAttributes) Line 385 C
shell32.dll!CShellItem::GetAttributes(unsigned long,unsigned long *) Unknown
shell32.dll!CDefView::_SelectionHasFolderJunction(void) Unknown
shell32.dll!CDefView::_ZoneCheckFrame(unsigned long,int) Unknown
shell32.dll!CDefView::_InvokeContextMenuVerbOnSelectionWorker(char const *,unsigned int) Unknown
shell32.dll!CDefView::_InvokeContextMenuVerbOnSelection(char const *,unsigned int) Unknown
shell32.dll!CDefView::OnActivateSelection(unsigned long) Unknown
ExplorerFrame.dll!UIItemsView::WndProc(struct HWND__ *,unsigned int,unsigned __int64,__int64) Unknown
Комментарии:
1. Проводник действительно вызывает множество вещей, которые не нужно реализовывать, я сомневаюсь, что ваша проблема связана с безопасностью, скорее всего, это проблема с вашим кодом. Двойной щелчок по элементу оболочки аналогичен вызову пункта контекстного меню по умолчанию (выделенного жирным шрифтом) для этого элемента. По умолчанию для папок по умолчанию используется пункт контекстного меню «Открыть» (глагол = открыть). Вы не хотите вызывать ShellExecute вслепую при каждом вызове. Для этого (и фактически для каждого элемента) вы должны передать действие в DefView. Как создать контекстное меню (SHCreateDefaultContextMenu?). Опубликуйте воспроизводящий проект;
2. Я создаю свое контекстное меню вручную. Как уже упоминалось, IContextMenu::InvokeCommand работает для моих «файлов», но никогда не вызывается для моих «папок». Я отредактировал свой пост, чтобы показать стек вызовов при двойном щелчке одной из моих «папок».
3. Вы должны попробовать с помощью меню по умолчанию проверить, все ли работает нормально. Это не потому, что вы видите стек, который вызывает что-то, о чем вы не знаете, что это причина вашей проблемы, оболочка использует сотни интерфейсов. Также убедитесь, что в ваших папках есть атрибут SFGAO_BROWSABLE. Трудно сказать больше без воспроизведения кода.
4. Почти не связаны, но почему вы заставляете lpClass? Все, что зарегистрировано, обычно работает, если для него установлено значение NULL. Другие приложения не будут его устанавливать…
5. Делает codeproject.com/articles/17809/… ведите себя как исследователь или ИФилеДиалог?