Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Стандартные диалоги - Указание "специальной" папки [D5, Win95/98, Win2k]


-=GUEST=- ©   (2005-08-01 20:41:00) 

Есть стандартные диалоговые окна, типа TOpenDialog или TSaveDialog.

Как в качестве папки указать "виртуальную" папку, типа "Рабочий стол", "Мои документы" и т.д. PIDL этой папки имеется.

А точнее как указать папку не путем, а PIDL'ом.

Т.е. как сообщение CDM_GETFOLDERIDLIST, только наоборот.


-=GUEST=-   (2005-08-04 13:20:00) [1]

> Ученик   (04.08.05 07:20) [4]
Работает.
В результате получаем строчку, что-то типа
'::{20D04FE0-3AEA-1069-A2D8-08002B30309D}'
и открывается именно папка 'Мой компьютер'
т.е. нужно "преобразовать" TItemlDList в GUID-строку.

Можно ли как-то при уже открытой TOpenDialog выбрать папку.
Т.е. будет модифицированный TOpenDialog (как TOpenPictureDialog) c кнопкой с выпадающим меню. Пользователь в меню может выбрать наиболее часто используемые папки.


-=GUEST=-   (2005-08-04 12:41:00) [2]

> Ботвин Дмитрий   (04.08.05 11:27) [5]
Да, только нужно эту папку отурыть в окне выбора файлов (TOpenDialog), а не в окне выбора директорий


Ботвин Дмитрий   (2005-08-04 11:27:00) [3]

Для рабочего стола:

Uses ShlObj;

procedure CallBack(wnd: hWnd; uMsg: UINT; lParam, lpData: LParam) stdcall;
begin
 SendMessage( wnd, BFFM_ENABLEOK, 0, 1 );
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 bi: TBrowseInfo;
 s: PChar;
 PIDL, ResPIDL: PItemIDList;
begin
  SHGetSpecialFolderLocation( Handle, CSIDL_DESKTOP, PIDL );
  s := StrAlloc(128);
  bi.hwndOwner := Handle;
  bi.pszDisplayName := s;
  bi.lpszTitle := 'Выберите прапку';
  bi.pidlRoot := PIDL;
  bi.lpfn := addr( CallBack );
  ResPidl :=  SHBrowseForFolder ( bi );
  SHGetPathFromIDList( ResPidl, s );
  Caption := s;
end;

Для остальных папок, я думаю, сам переделаещь, изменив выделенный
параметр.


Ученик   (2005-08-04 07:20:00) [4]

>-=GUEST=-   (02.08.05 10:50) [2]
Для Windows 98 можно заменить

if IDesktopFolder.GetDisplayNameOf(ItemIDList, SHGDN_FORPARSING, StrRet) = NOERROR then begin  
...
end

на
       if SHGetDataFromIDList (IDesktopFolder, ItemIDList, SHGDFIL_DESCRIPTIONID,
                               @SHDescriptionID, SizeOf(SHDescriptionID)) = NOERROR then
         Result := '::' + GuidToString (SHDescriptionID.Id);

// SHDescriptionID: TSHDescriptionID;


wal   (2005-08-02 11:00:00) [5]

А ему (диалогу) GUID подсунуть?


-=GUEST=-   (2005-08-02 10:50:00) [6]

Не выходит (Windows 98, Delphi 5)

OpenDialog1.InitialDir := ShellFolderName(CSIDL_DRIVES);
ShellFolderName(CSIDL_DRIVES) возвращает 'Мой компьютер'
А TOpenDialog открывается в стандартной папке (в Win98 это 'Мои документы').

Т.е. передача пути строкой не подходит для папок кот. не имеют пути в файловой системе (например папка "Удаленный доступ").

Такие пути в идеале нужно передавать через ItemIDList: PItemIDList.

Как я писал выше для получения PItemIDList текущей папки есть сообщение CDM_GETFOLDERIDLIST, кот можно послать окну TOpenDialog. А вот обратное действие - задать текущую папку - нету.


Ученик   (2005-08-01 22:48:00) [7]



uses
 ActiveX, ShlObj, ShellApi;

function ShellFolderName(aCSIDL: Integer) : string;
var
 IShellMalloc   : IMalloc;
 IDesktopFolder : IShellFolder;
 ItemIDList: PItemIDList;
 StrRet: TStrRet;
begin
 Result := '';
 if (ShGetMalloc(IShellMalloc) = S_OK) then try
   if SHGetDesktopFolder(IDesktopFolder) = NOERROR then try
     if SHGetSpecialFolderLocation(0, aCSIDL, ItemIDList) = NOERROR then try
       if IDesktopFolder.GetDisplayNameOf(ItemIDList, SHGDN_FORPARSING, StrRet) = NOERROR then begin
         case StrRet.uType of
           STRRET_WSTR:   Result := WideCharToString(StrRet.pOleStr);
           STRRET_OFFSET: Result := PChar(UINT(ItemIDList) + StrRet.uOffset);
           STRRET_CSTR:   Result := StrRet.cStr;
         end
       end
     finally
       IShellMalloc.Free(ItemIDList)
     end
   finally
     IDesktopFolder := nil
   end
 finally
   IShellMalloc := nil
 end
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 OpenDialog1.InitialDir := ShellFolderName(CSIDL_DRIVES);
 OpenDialog1.Execute
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо