|
Программирование >> Перегруженные имена функций и идентификаторы
пример. Оболочка Windows имеет понятие Рабочего стола, являющегося корнем файловой системы. Вы обращали внимание, как Windows приложения допускают пользователя, просматривают файловую систему, начинающуюся на рабочем столе? Этим способом вы можете, например, создавать файлы непосредственно на вашем рабочем столе, двигаться между дисководами, просматривать сетевой дисковод, и т.д. Это, в действительности, Распределенная Файловая система (PMDFS - poor mans Distributed File System). Как ваше приложение может получить доступ к PMDFS? Просто. В качестве примера напишем код, который позволит пользователю выбирать папку, просматривая PMDFS. Все, что мы должны сделать - это овладеть рабочим столом, позиционироваться относительно его, запустить встроенное окно просмотра и сформировать путь, который выбрал пользователь. char path [MAX PATH]; path [0] = \0; Desktop desktop; ShPath browseRoot (desktop, unicodePath); if (browseRoot.IsOK ()) { FolderBrowser browser (hwnd, browseRoot, BIF RETURNONLYFSDIRS, Select folder of your choice ); if (folder.IsOK ()) strcpy (path, browser.GetPath ()); Давайте, запустим объект desktop. Он использует интерфейс по имени IShellFolder. Обратите внимание, как мы приходим к Первому Правилу Захвата. Мы распределяем ресурсы в конструкторе, вызывая функцию API SHGetDesktopFolder. Интеллектуальный указатель интерфейса будет заботиться об управлении ресурсами (подсчет ссылок). class Desktop: public SIfacePtr<IShellFolder> public: Desktop () if (SHGetDesktopFolder (& p) != NOERROR) throw SHGetDesktopFolder failed ; Как только мы получили рабочий стол, мы должны создать специальный вид пути, который используется PMDFS. Класс ShPath инкапсулирует этот путь . Он создан из правильного Unicode пути (используйте mbstowcs, чтобы преобразовать путь ASCII в Unicode: int mbstowcs(wchar t *wchar, const char *mbchar, size t count)). Результат преобразования - обобщенный путь относительно рабочего стола. Обратите внимание, что память для нового пути распределена оболочкой - мы инкапсулируем это в SShellPtr, чтобы быть уверенными в правильном освобождении. class ShPath: public SShellPtr<ITEMIDLIST> public: ShPath (SIfacePtr<IShellFolder> & folder, wchar t * path) ULONG lenParsed = 0; hresult = folder->ParseDisplayName (0, 0, path, & lenParsed, & p, 0); bool IsOK () const { return SUCCEEDED ( hresult); } private: HRESULT hresult; Этот путь оболочки станет корнем, из которого окно просмотра начнет его взаимодействие с пользователем. С точки зрения клиентского кода, окно просмотра - путь, выбранный пользователем. Именно поэтому он наследуется от SShellPtr<ITEMIDLIST>. Между прочим, ITEMIDLIST - официальное имя для этого обобщенного пути. class FolderBrowser: public SShellPtr<ITEMIDLIST> { public: FolderBrowser ( HWND hwndOwner, SShellPtr<ITEMIDLIST> & root, UINT browseForWhat, char const *title); char const * GetDisplayName () { return displayName; } char const * GetPath () { return fullPath; } bool IsOK() const { return p != 0; }; private: char displayName [MAX PATH]; char fullPath [MAX PATH]; BROWSEINFO browseInfo; FolderBrowser::FolderBrowser ( HWND hwndOwner, SShellPtr<ITEMIDLIST> & root, UINT browseForWhat, char const *title) 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); Вот так! Разве это не просто? Как функции, не являющиеся методами, улучшают инкапсуляцию Когда приходится инкапсулировать, то иногда лучше меньше, чем больше.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |