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

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

Вопросы по SHBrowseForFolder [D7, WinXP]


rolex ©   (2005-01-29 20:58:00) 

К примеру, как сделать, чтобы окошко вылезало не где-попало, а в определённой позиции? И ещё, как сделать, чтобы нельзя было выделить CD-приводы?
А использую я эту функцию вот так:
var
 lpItemID : PItemIDList;
 BrowseInfo : TBrowseInfo;
 TempPath : array[0..MAX_PATH] of char;
begin
 FillChar(BrowseInfo, sizeof(TBrowseInfo), #0);
 BrowseInfo.hwndOwner := Form1.Handle;
 BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS;
 lpItemID := SHBrowseForFolder(BrowseInfo);
 if lpItemId <> nil then
 begin
   SHGetPathFromIDList(lpItemID, TempPath);
   ListBox1.Items.Add(TempPath);
   GlobalFreePtr(lpItemID);
 end else ShowMessage('Пусто!');
end;


a.denisov   (2005-01-30 13:06:00) [1]

Не за что, как я говорил, в частном сл-е все работает хорошо. До тех пор, пока не изменится внутренняя реализация SHBrowseForFolder:)


rolex   (2005-01-30 12:30:00) [2]

Спасибо вам, a.denisov, огромное! Очень помогли!


a.denisov   (2005-01-30 02:45:00) [3]

Хотя, в обоих сл-ях функци могут быть доработаны, например,после строки:
     until not Assigned(H);
неплохо смотрится:
     TreeView_Select(T, TreeView_GetFirstVisible(T), TVGN_CARET);


a.denisov   (2005-01-30 02:31:00) [4]

Или, например, более кардинальное средство. Функция обратного вызова просто удаляет ненужные папки или диски:

{$DEFINE DELETE_UNNECESSARY}

function BrowseCallbackProc(Wnd: HWND; uMsg: UINT; lParam, lpData: LPARAM): Integer stdcall;
var
 buf               : array[0..MAX_PATH] of char;
 DriveType         : UINT;
{$IFDEF DELETE_UNNECESSARY}
 T                 : THandle;
 H                 : HTREEITEM;
 Item              : TTVItem;

 procedure EnumTreeViewItems;
 begin
   T := FindWindowEx(Wnd, 0, WC_TREEVIEW, nil);
   if T <> 0 then begin
     H := TreeView_GetFirstVisible(T);
     H := TreeView_GetChild(T, H);
     repeat
       FillChar(Item, SizeOf(Item), 0);
       Item.hItem := H;
       Item.mask := TVIF_HANDLE;
       if TreeView_GetItem(T, Item) then
         TreeView_Select(T, H, TVGN_CARET);
       H := TreeView_GetNextSibling(T, H);
     until not Assigned(H);
   end;
 end;

 procedure DeleteTreeViewItem;
 begin
   T := FindWindowEx(Wnd, 0, WC_TREEVIEW, nil);
   if T <> 0 then begin
     H := TreeView_GetSelection(T);
     TreeView_DeleteItem(T, H)
   end;
 end;

{$ENDIF}

begin
 Result := 0;
 case uMsg of
   BFFM_SELCHANGED: begin
       if (lParam <> 0) and SHGetPathFromIDList(PItemIDList(lParam), @buf) then begin
         DriveType := GetDriveType(PChar(@buf));
         if DriveType = DRIVE_CDROM then
{$IFDEF DELETE_UNNECESSARY}
           DeleteTreeViewItem;
{$ELSE}begin
           SendMessage(Wnd, BFFM_ENABLEOK, 0, 0);
         end
         else
           SendMessage(Wnd, BFFM_ENABLEOK, 0, 1);
{$ENDIF}
       end;
     end;
   BFFM_INITIALIZED: begin
{$IFDEF DELETE_UNNECESSARY}
       EnumTreeViewItems;
{$ENDIF}
       SetWindowPos(Wnd, HWND_TOP,
         Form1.Left, Form1.Top, 0, 0, SWP_NOSIZE or SWP_SHOWWINDOW);
     end;
 end;
end;

Одно но: Дескриптор дерева в случае установки стиля диалога BIF_NEWDIALOGSTYLE придется искать внутри встроенного диалога с дескиптором GetDlgItem(Wnd,100) и именем класса 'SHBrowseForFolder ShellNameSpace Control'


a.denisov   (2005-01-30 01:50:00) [5]

Суть в обработке сообщений диалога в функции обратного вызова BrowseCallbackProc.
Для этого, перед вызовом SHBrowseForFolder установить указатель lpfn на такую функцию:

 BrowseInfo.lpfn := BrowseCallbackProc;
 lpItemID := SHBrowseForFolder(BrowseInfo);

И, функция, собственной персоной:

function BrowseCallbackProc(Wnd: HWND; uMsg: UINT; lParam, lpData: LPARAM): Integer stdcall;
var
 buf               : array[0..MAX_PATH] of char;
begin
 Result := 0;
 case uMsg of
   BFFM_SELCHANGED: begin
       if (lParam <> 0) and SHGetPathFromIDList(PItemIDList(lParam), @buf) then
         if GetDriveType(PChar(@buf)) = DRIVE_CDROM then
           SendMessage(Wnd, BFFM_ENABLEOK, 0, 0)
         else
           SendMessage(Wnd, BFFM_ENABLEOK, 0, 1);
     end;
   BFFM_INITIALIZED:
     SetWindowPos(Wnd, HWND_TOP,
       Form1.Left, Form1.Top, 0, 0, SWP_NOSIZE or SWP_SHOWWINDOW);
 end;
end;


Наверх

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