Можно ли наследовать реализацию IShellFolder по умолчанию?

Я пытаюсь реализовать расширение пространства имен оболочки с единственной целью — переопределить обработчик миниатюр (IExtractImage) в определенной папке. Я хочу, чтобы все остальное было таким же, как в обычной папке, и мне не хотелось бы переопределять все, что сделано в реализации по умолчанию IShellFolder...

Итак, возможно ли наследовать эту реализацию по умолчанию? Если да, то как?

Использование композиции также было бы приемлемым решением, но как я могу получить экземпляр класса для данной папки?


person Thomas Levesque    schedule 03.12.2014    source источник
comment
Вам нужно получить указатель интерфейса реализации по умолчанию, а затем в вашей реализации интерфейса вы перенаправляете все вызовы методов, кроме того, для которого вы изменяете поведение. Чтобы получить указатель на интерфейс IShellFolder объекта пространства имен, вы должны...   -  person Roman R.    schedule 03.12.2014
comment
Зарегистрировать IThumbnailProvider для вашего типа файла?   -  person patthoyts    schedule 03.12.2014
comment
@patthoyts, нет, мне это не подойдет; поэтому мне нужно создать расширение пространства имен (см. file-type">этот вопрос для более подробной информации)   -  person Thomas Levesque    schedule 03.12.2014
comment
@RomanR., да, это то, что я имел в виду под композицией. Но я все еще работаю над тем, как получить экземпляр реализации IShellFolder по умолчанию для моей папки. По-видимому, соответствующим классом является папка файловой системы оболочки (CLSID {F3364BA0-65B9-11CE-A9BA-00AA004AE837}).   -  person Thomas Levesque    schedule 03.12.2014
comment
Кажется, вы начинаете с CLSID, а в статье MSDN (см. ссылку выше) предлагается начинать с SHGetDesktopFolder или SHGetFolderLocation.   -  person Roman R.    schedule 03.12.2014
comment
@RomanR., да, я этим и занимаюсь; Я только что отметил, какой класс я получаю, когда я вызываю BindObject на рабочем столе IShellFolder   -  person Thomas Levesque    schedule 03.12.2014
comment
ИМХО это практически невозможно. Это была бы огромная задача, оболочка очень недокументирована и постоянно меняется от версии Windows к версии Windows. Я понимаю, что это не крутой ответ :-)   -  person Simon Mourier    schedule 04.12.2014


Ответы (1)


1) Существует множество расширений оболочки, которые могут запрашивать содержимое ваших файлов. Например, обработчик значков .ico-файлов. Также пользователь может установить, например, расширение информационной подсказки, которое показывает тег ID3 из mp3-файла, а также запрашивает содержимое файла. Пользователь может настроить дополнительные столбцы в подробном представлении, и некоторые из них запрашивают содержимое файла. Таким образом, вы должны контролировать множество деталей в расширении пространства имен вашей оболочки.

2) Чтобы создать реализацию по умолчанию, просто вызовите CoCreateInstance(CLSID_ShellFileSystemFolder, nil, CLSCTX_INPROC_SERVER, IID_IShellFolder, ShellFolder).

3) Есть проблема. Например:

  1. Shell запрашивает неизвестный IShellFolder3 из NSE.
  2. Ваш NSE не реализует IShellFolder3, и NSE запрашивает IShellFolder3 из реализации по умолчанию и возвращает результат.
  3. Вызов оболочки IShellFolder3.GetUIObject с IID_IExtractImage и IShellFolder3 по умолчанию вернет установленный обработчик миниатюр.

Также такие методы могут привести к АВ внутри Проводника (из моей практики).

Поэтому я считаю, что ваша NSE должна реализовать все известные интерфейсы, реализованные по умолчанию. Если вы не хотите менять поведение метода, просто передайте параметры реализации по умолчанию. Known (by me) interfaces: IBrowserFrameOptions, IOleCommandTarget, IPersist, IPersistIDList, IPersistFolder, IPersistFolder2, IPersistFolder3, IParentAndItem, IShellFolder, IShellFolder2, IObjectWithFolderEnumMode, IShellDetails, IShellFolderViewCB, IFolderFilter, INameSpaceTreeControlFolderCapabilities, IShellIcon, IShellIconOverlay, IFolderType, IFolderViewSettings, IExplorerPaneVisibility, IPropertyStoreFactory, IPropertyStore , IItemNameLimits, IThumbnailFactory.

4) Насколько я понимаю, вы должны контролировать запросы следующих интерфейсов: IDataObject, IDropTarget, IExtractIconA(W), IExtractImage, IPropertyStore, IPropertyStoreFactory, IShellFolder(2), IQueryInfo.

5) IShellIcon.GetIconOf должен возвращать значок расширения по умолчанию.

6) Также, если ваша папка содержит подпапки, не забудьте вернуть вашу реализацию, когда оболочка запрашивает IShellFolder(2) подпапки.

person Denis Anisimov    schedule 03.12.2014
comment
Спасибо, это очень полезно! - person Thomas Levesque; 03.12.2014
comment
Тяжело только в начале. - person Denis Anisimov; 03.12.2014
comment
Хорошо, основной принцип, кажется, работает... Главное, чего мне не хватало, это как создать экземпляр ShellFileSystemFolder (я вообще не знаком с COM). Теперь мне нужно реализовать все эти интерфейсы;) - person Thomas Levesque; 04.12.2014
comment
Некоторые из упомянутых вами интерфейсов, похоже, не реализованы ShellFSFolder; должен ли я реализовать их где-то еще, возможно, в классе, возвращаемом BindToObject или GetUIObjectOf? - person Thomas Levesque; 05.12.2014
comment
Какие интерфейсы вы имеете в виду? - person Denis Anisimov; 05.12.2014
comment
IBrowserFrameOptions, IPersistIDList, IObjectWithFolderEnumMode, IShellDetails, IShellFolderViewCB, IFolderFilter, IFolderViewSettings, IPropertyStoreFactory, IPropertyStore, IExtractIconA/W не реализованы в ShellFSFolder. Кроме того, я ничего не могу найти о IFolderType; его вроде нигде нет. - person Thomas Levesque; 05.12.2014
comment
Я скопировал список интерфейсов из своего NSE, поэтому просто игнорируйте их. IFolderType — geoffchappell.com/studies/windows/shell/shell32/ интерфейсы/. IPropertyStoreFactory, IPropertyStore, IExtractIconA/W можно запрашивать с помощью BindToObject, BindToStorage или GetUIObjectOf. - person Denis Anisimov; 05.12.2014
comment
Хорошо, спасибо. Я проверил, вызвав QueryInterface в ShellFSFolder для каждого интерфейса, и он вернул E_NOINTERFACE для тех, которые я упомянул. - person Thomas Levesque; 05.12.2014
comment
Я забыл про очень важный интерфейс IObjectWithSite. Пожалуйста, проверьте это тоже. - person Denis Anisimov; 11.12.2014
comment
Спасибо! я посмотрю - person Thomas Levesque; 11.12.2014