Читать «Применение Windows API» онлайн - страница 33

А. И. Легалов

 _displayName [0] = '\0';

 _fullPath [0] = '\0';

 _browseInfo.hwndOwner = hwndOwner;

 _browseInfo.pidlRoot = root;

 _browseInfo.pszDisplayName = _displayName;

 _browseInfo.lpszTitle = title;

 _browseInfo.ulFlags = browseForWhat;

 _browseInfo.lpfn = 0;

 _browseInfo.lParam = 0;

 _browseInfo.iImage = 0;

 // Let the user do the browsing

 _p = SHBrowseForFolder(&_browseInfo);

 if (_p != 0) SHGetPathFromIDList(_p, _fullPath);

}

Вот так! Разве это не просто?

Далее: Вам, наверное, будет приятно услышать то, что я думаю об OLE?

Дефекты OLE

Что является неправильным в OLE

Рассказ посвященного лица

Перевод А. И. Легалова

Англоязычный оригинал находится на сервере компании Reliable Software

Вы могли слышать или читать критические мнения относительно OLE. Программисты обычно жалуются на сложность системы подсчета ссылок и недостатосную поддержку наследования. Microsoft обожествляет этот счетчик, говоря, что нет никакого другого способа, и что этот способ является для вас наилучшим[2]. Интерфейсы, как сказано, должно быть ссылочно подсчитаны (refcounted), и имеется мудрый, рубильник обеспечивающий соединение (агрегацию) частей (нежно называемый ухудшением (aggravation) OLE программистами), который обеспечивает те же самые функциональные возможности, что и наследование. Может быть они правы, и проблема взаимодействия с объектами, загружаемыми во время выполнения настолько сложна, что просто не имеется более лучшего способа? С другой стороны, возможно, что OLE имеет фатальный дефект, который только обостряется во всех других местах.

Фатальный дефект проекта OLE — требование того, чтобы была возможность добраться от любого интерфейса до любого другого интерфейса.

Технически это интерфейсное прыгание сделано за счет того, что каждый интерфейс наследует от матери всех интерфейсов IUnknown. IUnknown имеет фатальный метод QueryInterface, который, как предполагается, возвращает любой интерфейс, обеспечиваемый текущим объектом. Это единственное предположение препятствует наличию любой возможности простой реализации наследования. Позвольте мне объясняют почему.

Предположим, что Вы имеете объект FooObj с интерфейсом IFoo. Эта ситуация легко моделируется в C++ при наличии абстрактного класса (все методы — чистые виртуальные) IFoo и конкретного класс FooObj, который наследуется из IFoo и реализует все его методы.

Теперь Вам вдруг захотелось расширить этот объект, добавляя поддержку для другого интерфейса IBar. В C++ это тривиально, Вы только определяете класс FooBarObj, который наследует от FooObj и IBar. Этот новый класс поддерживает интерфейс IFoo вместе с его реализацией через наследование из FooObj. Он также поддерживает интерфейс IBar и обеспечивает реализацию методов IBar.

Любой, кто знает C++, может сделать это с закрытыми глазами. Так, почему же Вы не можете сделать то же самое в OLE? Здесь проявляется Изъян. Вы должны быть способны получить интерфейс IBar из интерфейса IFoo, используя его QueryInterface. Но, подождите минуту, объект FooObj, который обеспечивает реализацию всех методов IFoo, включая QueryInterface, не имеет никаких сведений относительно IBar! Невозможно было даже представить наличие IBar. Так, как же в этой ситуации обеспечить доступ к IBar?