home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / WIN / Programa / JPRSHBR.ZIP / JPRSHBR.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-08-11  |  7.3 KB  |  264 lines

  1. Unit JPRShBr;
  2.  
  3. //                       TShellBrowser
  4. //  A VCL encapsulation of the Win95/NT4 SHBrowseForFolder API function
  5. //
  6. //               Copyright ⌐ 1996 JP Ritchey
  7.  
  8. interface
  9.  
  10. uses Windows,Classes,ShellAPI;
  11.  
  12. type
  13.   TShellBrowserOption = (shbBrowseForComputer,shbBrowseForPrinter,
  14.                          shbDontGoBelowDomain,shbReturnFSAncestors,
  15.                          shbReturnOnlyFSDirs,shbStatusText);
  16.   TShellBrowserOptions = set of TShellBrowserOption;
  17.  
  18.  
  19.   TSelChangeEvent = procedure(Sender:TObject; NewFolder:String; IsDisplayName:boolean) of object;
  20.  
  21.   TShellBrowser = class(TComponent)
  22.   private
  23.     fOnInitialize:TNotifyEvent;
  24.     fOnSelChange:TSelChangeEvent;
  25.     fPrompt:String;
  26.     fRootPath:String;
  27.     fInitialPath:String;
  28.     fPathName:String;
  29.     fDisplayName:String;
  30.     fStatusText:String;
  31.     fCaption:String;
  32.     fOptions:TShellBrowserOptions;
  33.     fDialogWnd:HWND;
  34.     function BrowserCallback(Wnd:HWND; Msg:UINT; lParam:LPARAM):integer;
  35.     procedure SetStatusText(const Value:String);
  36.     procedure SetCaption(const Value:String);
  37.   public
  38.     constructor Create(AOwner:TComponent); override;
  39.     function Execute:boolean;
  40.     procedure EnableOK(Enable:boolean);
  41.     procedure SetSelection(const Value:String);
  42.     property DialogWnd:HWND read fDialogWnd;
  43.     property PathName:String read fPathName;
  44.     property DisplayName:String read fDisplayName;
  45.   published
  46.     property InitialPath:String read fInitialPath write fInitialPath;
  47.     property RootPath:String read fRootPath write fRootPath;
  48.     property Prompt:String read fPrompt write fPrompt;
  49.     property Caption:String read fCaption write SetCaption;
  50.     property StatusText:String read fStatusText write SetStatusText;
  51.     property Options:TShellBrowserOptions read fOptions write fOptions;
  52.     property OnInitialize:TNotifyEvent read fOnInitialize write fOnInitialize;
  53.     property OnSelChange:TSelChangeEvent read fOnSelChange write fOnSelChange;
  54.   end;
  55.  
  56. procedure Register;
  57.  
  58. implementation
  59.  
  60. uses SysUtils,Messages,Controls,OLE2,SHLOBJ;
  61.  
  62. procedure Register;
  63. begin
  64.   RegisterComponents('Dialogs',[TShellBrowser]);
  65. end;
  66.  
  67. function ItemIDListToPath(PIDL:PItemIDList):String;
  68. var
  69.   szPath:array[0..MAX_PATH] of char;
  70. begin
  71.   if ShGetPathFromIDList(PIDL,@szPath) then
  72.      Result := String(szPath)
  73.   else
  74.      Result := '';
  75. end;
  76.  
  77. function ItemIDListToDisplayName(PIDL:PItemIDList):String;
  78. var
  79.    pDesktopFolder:ISHELLFOLDER;
  80.    STRRET : TSTRRET;
  81. begin
  82.  if Succeeded(SHGetDesktopFolder(pDesktopFolder)) then
  83.     try
  84.        pDesktopFolder.GetDisplayNameOf(PIDL,SHGDN_NORMAL,STRRET);
  85.        case STRRET.uType of
  86.          STRRET_CSTR: REsult := String(STRRET.cStr);
  87.          STRRET_WSTR: Result := WideCharToString(STRRET.pOLEStr);
  88.          STRRET_OFFSET: Result := StrPas(Pchar(PIDL)+STRRET.uOffset);
  89.        end;
  90.     finally
  91.        pDesktopFolder.Release;
  92.        end
  93.  else
  94.     Result := '';
  95. end;
  96.  
  97. function PathToItemIDList(APath:String):PItemIDList;
  98. var
  99.    pidl:PITEMIDLIST;
  100.    pDesktopFolder:ISHELLFOLDER;
  101.    olePath:array[0..MAX_PATH] of TOLECHAR;
  102.    chEaten:ULONG;
  103.    dwAttributes:ULONG;
  104. begin
  105.  if Succeeded(SHGetDesktopFolder(pDesktopFolder)) then
  106.     try
  107.      MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,PChar(APAth),-1,olePath,MAX_PATH);
  108.      if Succeeded(pDesktopFolder.ParseDisplayName(0,nil,olePath,chEaten,pidl,dwAttributes)) then
  109.         Result := pidl
  110.      else
  111.         Result := nil;
  112.      finally
  113.        pDesktopFolder.Release;
  114.      end
  115.  else
  116.      Result := nil;
  117. end;
  118.  
  119.  
  120. function glBrowseCallback(Wnd:HWND; Msg:UINT; lParam:LPARAM; lData:TShellBrowser):integer; stdcall;
  121. begin
  122.   Result := lData.BrowserCallback(Wnd,Msg,lParam);
  123. end;
  124.  
  125. function OptionsToFlags(AOptions:TShellBrowserOptions):UINT;
  126. var
  127.   SBO:TShellBrowserOption;
  128. const
  129.   SBOArray:array[TShellBrowserOption] of UINT = (
  130.            BIF_BROWSEFORCOMPUTER,BIF_BROWSEFORPRINTER,BIF_DONTGOBELOWDOMAIN,
  131.            BIF_RETURNFSANCESTORS,BIF_RETURNONLYFSDIRS,BIF_STATUSTEXT);
  132. begin
  133.   Result := 0;
  134.   for SBO := Low(TShellBrowserOption) to High(TShellBrowserOption) do
  135.       if SBO in AOptions then
  136.          Result := Result or SBOArray[SBO];
  137. end;
  138.  
  139. constructor TShellBrowser.Create(AOwner:TComponent);
  140. begin
  141.   inherited Create(AOwner);
  142.   fOptions := [shbReturnFSAncestors,shbReturnOnlyFSDirs];
  143. end;
  144.  
  145. function TShellBrowser.Execute:boolean;
  146. var
  147.   BI:TBrowseInfo;
  148.   RootPIDL:PItemIDList;
  149.   IDList:PItemIDList;
  150.   Malloc:IMalloc;
  151.   PathSelected:array[0..MAX_PATH] of char;
  152. begin
  153.   FillChar(BI,Sizeof(BI),#00);
  154.   With BI do begin
  155.    if Owner is TWinControl then
  156.       hwndOwner := TWinControl(Owner).Handle
  157.    else
  158.       hwndOwner := 0;
  159.    if RootPath <> '' then
  160.       if lowercase(RootPath) = 'mycomputer' then
  161.          begin
  162.          SHGetSpecialFolderLocation(hwndOwner,CSIDL_DRIVES,RootPIDL);
  163.          pidlRoot := RootPIDL;
  164.          end
  165.       else
  166.          begin
  167.          RootPIDL := PathToItemIDList(RootPath);
  168.          pidlRoot := RootPIDL;
  169.          end
  170.    else
  171.       RootPIDL := nil;
  172.    ulFlags := OptionsToFlags(fOptions);
  173.    pszDisplayName := @PathSelected;
  174.    if fPrompt <> '' then
  175.       lpszTitle := Pchar(fPrompt);
  176.    lpfn := @glBrowseCallback;
  177.    lParam := longint(Self);
  178.   end;
  179.   Result := true;
  180.   IDList := SHBrowseForFolder(BI);  // display the dialog modally
  181.   if RootPIDL <> nil then
  182.      begin
  183.      SHGetMalloc(Malloc);
  184.      Malloc.Free(RootPIDL);
  185.      end;
  186.   fDialogWnd := 0;
  187.   if IDList <> nil then
  188.      begin
  189.      fPathName := ItemIDListToPath(IDList);
  190.      fDisplayName := ItemIDListToDisplayName(IDList);
  191.      SHGetMalloc(Malloc);
  192.      Malloc.Free(IDList);
  193.      end
  194.   else
  195.      begin
  196.      fPathName := '';
  197.      fDisplayName := '';
  198.      Result := false;
  199.      end;
  200. end;
  201.  
  202. function TShellBrowser.BrowserCallback(Wnd:HWND; Msg:UINT; lParam:LPARAM):integer;
  203. var
  204.   Temp:String;
  205. begin
  206.   Result := 0;
  207.   if Msg = BFFM_INITIALIZED then
  208.     begin
  209.     fDialogWnd := Wnd;
  210.     if InitialPath <> '' then
  211.        SetSelection(fInitialPath);
  212.     if fStatusText <> '' then
  213.        SetStatusText(fStatusText);
  214.     if fCaption <> '' then
  215.        Caption := fCaption;
  216.     if Assigned(fOnInitialize) then
  217.        fOnInitialize(Self);
  218.     end
  219.   else if Msg = BFFM_SELCHANGED then
  220.     if fDialogWnd <> 0 then
  221.        if Assigned(fOnSelChange) then
  222.           begin
  223.           Temp := ItemIDListToPath(PItemIDLIST(lParam));
  224.           if Temp = '' then
  225.              begin
  226.              Temp := ItemIDListToDisplayName(PItemIDLIST(lParam));
  227.              fOnSelChange(Self,Temp,true);
  228.              end
  229.           else
  230.              fOnSelChange(Self,Temp,false);
  231.           end;
  232. end;
  233.  
  234. procedure TShellBrowser.SetCaption;
  235. begin
  236.   fCaption := Value;
  237.   if fDialogWnd <> 0 then
  238.      SendMessage(DialogWnd,WM_SETTEXT,0,longint(PChar(fCaption)));
  239. end;
  240.  
  241. procedure TShellBrowser.EnableOK(Enable:boolean);
  242. var
  243.   wParam:Cardinal;
  244. begin
  245.  if Enable then wParam := 1 else wParam := 0;
  246.  if DialogWnd <> 0 then
  247.     SendMessage(DialogWnd,BFFM_ENABLEOK,wParam,wPAram);
  248. end;
  249.  
  250. procedure TShellBrowser.SetSelection(const Value:String);
  251. begin
  252.  if DialogWnd <> 0 then
  253.     SendMessage(DialogWnd,BFFM_SETSELECTION,1,longint(Pchar(fInitialPath)));
  254. end;
  255.  
  256. procedure TShellBrowser.SetStatusText;
  257. begin
  258.   fStatusText := Value;
  259.   if DialogWnd <> 0 then
  260.      SendMessage(DialogWnd,BFFM_SETSTATUSTEXT,0,longint(Pchar(fStatusText)));
  261. end;
  262.  
  263. end.
  264.