home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 December / Chip_2001-12_cd1.bin / zkuste / delphi / kolekce / d345 / JWTOOL.ZIP / jwtool / jwShellBrowseFolder.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-09-29  |  7.6 KB  |  225 lines

  1. unit jwShellBrowseFolder;
  2.  
  3. //  Version History
  4. //     Num     Date                 Notes
  5. //     1.00  September 27, 2001    Initial Release
  6.  
  7. //  Created By:
  8. //    Joseph Wilcock
  9. //    Coockoo@hotmail.com
  10. //    http://msnhomepages.talkcity.com/RedmondAve/coockoo/
  11.  
  12. interface
  13.  
  14. uses
  15.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
  16.  
  17. type
  18.   TBrowseKind = ( bkError, bkComputers, bkPrinters, bkAncestors, bkFolders );
  19.   TRootStart = ( rsError, rsNone, rsCONTROLS, rsDESKTOP, rsDESKTOPDIRECTORY,
  20.         rsDRIVES, rsFONTS, rsNETHOOD, rsNETWORK, rsPERSONAL, rsPRINTERS,
  21.         rsPROGRAMS, rsRECENT, rsSENDTO, rsSTARTMENU, rsSTARTUP, rsTEMPLATES );
  22.  
  23.   TjwShellBrowseFolder = class(TComponent)
  24.   private
  25.     { Private declarations }
  26.     FHandle: THandle;
  27.     FBrowseKind: TBrowseKind;
  28.     FDontGoBelowDomain: Boolean;
  29.     FStatusText: Boolean;
  30.     FCaptionText: String;
  31.     FSelectedFolder: String;
  32.     FRootStart: TRootStart;
  33.     procedure SetBrowseKind(const Value: TBrowseKind);
  34.     procedure SetCaptionText(const Value: String);
  35.     procedure SetDontGoBelowDomain(const Value: Boolean);
  36.     procedure SetStatusText(const Value: Boolean);
  37.     procedure SetRootStart(const Value: TRootStart);
  38.   protected
  39.     { Protected declarations }
  40.     Function SetSelection( hwnd: THandle; const Value: String ): Boolean;
  41.     function EnableOK( hwnd: THandle ): Boolean;
  42.     Function BrowseCallbackProc( hwnd: THandle; uMsg: UINT; lParam, lpData: LPARAM ): Integer; stdcall;
  43.     Function GetFolder( aHandle: THandle; Caption: String; Flags: UINT; RootStart: TRootStart ): String;
  44.   public
  45.     { Public declarations }
  46.     constructor Create(AOwner: TComponent); override;
  47.     Function Execute: Boolean;
  48.     Property SelectedFolder: String Read FSelectedFolder;
  49.     Property CarryHandle: THandle Read FHandle Write FHandle;
  50.   published
  51.     { Published declarations }
  52.     Property BrowseKind: TBrowseKind Read FBrowseKind Write SetBrowseKind default bkFolders;
  53.     Property DontGoBelowDomain: Boolean Read FDontGoBelowDomain Write SetDontGoBelowDomain Default True;
  54.     Property StatusText: Boolean Read FStatusText Write SetStatusText Default False;
  55.     Property CaptionText: String Read FCaptionText Write SetCaptionText;
  56.     Property RootStart: TRootStart Read FRootStart Write SetRootStart Default rsDESKTOP;
  57.   end;
  58.  
  59. procedure Register;
  60.  
  61. implementation
  62.  
  63. uses ShlObj;
  64.  
  65. procedure Register;
  66. begin
  67.   RegisterComponents('JwTools', [TjwShellBrowseFolder]);
  68. end;
  69.  
  70. { TjwShellBrowseFolder }
  71.  
  72. Function TjwShellBrowseFolder.GetFolder( aHandle: THandle; Caption: String; Flags: UINT; RootStart: TRootStart ): String;
  73. var
  74.   BrowseInfo: TBrowseInfo;
  75.   PIDL,RIDL: PItemIDList;
  76.   DisplayName: Array[0..MAX_PATH] of Char;
  77.   RootFlag: Integer;
  78. begin
  79.   // this is an interesting way to do it, but DON'T do this to a pointer
  80.   //   ....it turns it null....
  81.   RootFlag := 0;
  82.   Case RootStart of
  83.     rsCONTROLS: RootFlag := CSIDL_CONTROLS;
  84.     rsDESKTOP: RootFlag := CSIDL_DESKTOP;
  85.     rsDESKTOPDIRECTORY: RootFlag := CSIDL_DESKTOPDIRECTORY;
  86.     rsDRIVES: RootFlag := CSIDL_DRIVES;
  87.     rsFONTS: RootFlag := CSIDL_FONTS;
  88.     rsNETHOOD: RootFlag := CSIDL_NETHOOD;
  89.     rsNETWORK: RootFlag := CSIDL_NETWORK;
  90.     rsPERSONAL: RootFlag := CSIDL_PERSONAL;
  91.     rsPRINTERS: RootFlag := CSIDL_PRINTERS;
  92.     rsPROGRAMS: RootFlag := CSIDL_PROGRAMS;
  93.     rsRECENT: RootFlag := CSIDL_RECENT;
  94.     rsSENDTO: RootFlag := CSIDL_SENDTO;
  95.     rsSTARTMENU: RootFlag := CSIDL_STARTMENU;
  96.     rsSTARTUP: RootFlag := CSIDL_STARTUP;
  97.     rsTEMPLATES: RootFlag := CSIDL_TEMPLATES;
  98.   end;
  99.   SHGetSpecialFolderLocation( aHandle, RootFlag, RIDL );
  100.   FillChar( BrowseInfo, SizeOF(BrowseInfo), #0 );
  101.   with BrowseInfo do
  102.     begin
  103.       hwndOwner := aHandle;  // Handle of the owner window for the dialog box
  104.       pidlRoot := RIDL;      // Pointer to an item identifier list (an ITEMIDLIST structure)
  105.                              //   specifying the location of the "root" folder to browse from
  106.       pszDisplayName := @DisplayName[0];   // Pointer to a buffer that receives the display
  107.                                            //   name of the folder selected by the user
  108.       lpszTitle := @Caption[1];  // Pointer to a null-terminated string that is displayed
  109.                                  //   above the tree view control in the dialog box
  110.       ulFlags := Flags;          // Value specifying the types of folders
  111.                                  //   to be listed in the dialog box as well as other options
  112.       //lpfn := @BrowseCallbackProc;             // Address an application-defined function that
  113.                                  //   the dialog box calls when events occur.
  114.       //lParam: LPARAM;          // extra info that's passed back in callbacks
  115.       //iImage: Integer;         // output var: where to return the Image index.
  116.     end;
  117.   PIDL := ShlObj.SHBrowseForFolder( BrowseInfo );
  118.   Result := '';
  119.   if Assigned( PIDL ) then
  120.     begin
  121.       if ShlObj.SHGetPathFromIDList( PIDL, Displayname ) then
  122.         Result := StrPas( DisplayName );
  123.       GlobalFreePtr(PIDL);
  124.     end;
  125.   //  I'm not sure if I can use this function or if I need to get the SHMalloc
  126.   //     object to do it.  This seems to work, but... I'm not sure...
  127.   GlobalFreePtr(RIDL);
  128. end;
  129.  
  130. function TjwShellBrowseFolder.BrowseCallbackProc(hwnd: THandle; uMsg: UINT;
  131.   lParam, lpData: LPARAM): Integer;
  132. begin
  133. //  Obviously, this isn't implimented... the API is *very* poorly documented.
  134.   case uMsg of
  135.     BFFM_INITIALIZED:;
  136.      BFFM_SELCHANGED:;
  137.   end;
  138.   Result := 0;
  139. end;
  140.  
  141. constructor TjwShellBrowseFolder.Create(AOwner: TComponent);
  142. begin
  143.   inherited Create( aOwner );
  144.   FBrowseKind := bkFolders;
  145.   FDontGoBelowDomain := True;
  146.   FStatusText := False;
  147.   FCaptionText := 'Select a folder';
  148.   FSelectedFolder := '';
  149.   FRootStart := rsDESKTOP;
  150.  
  151.   // You know, this is good to have, yet not exactly necessary.
  152.   //   Therefore, I decided to do this and allow the value to
  153.   //   be overridden.
  154.   if ( Owner is TForm ) then
  155.     FHandle := ( Owner as TForm ).Handle
  156.   else
  157.     FHandle := 0;
  158. end;
  159.  
  160. function TjwShellBrowseFolder.EnableOK( hwnd: THandle ): Boolean;
  161. begin
  162.   // Yet again, another function undefined...
  163.   //SendMessage(hwnd, BFFM_ENABLEOK, 1, 0);
  164.   Result := False;
  165. end;
  166.  
  167. function TjwShellBrowseFolder.Execute: Boolean;
  168. var
  169.   Flags: UINT;
  170. begin
  171.   Result := False;
  172.   Flags := 0;
  173.   case FBrowseKind of
  174.     bkComputers: Flags := BIF_BROWSEFORCOMPUTER;
  175.      bkPrinters: Flags := BIF_BROWSEFORPRINTER;
  176.     bkAncestors: Flags := BIF_RETURNFSANCESTORS;
  177.       bkFolders: Flags := BIF_RETURNONLYFSDIRS;
  178.   end;
  179.   if FDontGoBelowDomain then
  180.     Flags := Flags and BIF_DONTGOBELOWDOMAIN;
  181.   if FStatusText then
  182.     Flags := Flags and BIF_STATUSTEXT;
  183.   FSelectedFolder := GetFolder( 0, FCaptionText, Flags, FRootStart );
  184.   Result := Length( FSelectedFolder ) > 0;
  185. end;
  186.  
  187. procedure TjwShellBrowseFolder.SetBrowseKind(const Value: TBrowseKind);
  188. begin
  189.   FBrowseKind := Value;
  190. end;
  191.  
  192. procedure TjwShellBrowseFolder.SetCaptionText(const Value: String);
  193. begin
  194.   FCaptionText := Value;
  195. end;
  196.  
  197. procedure TjwShellBrowseFolder.SetDontGoBelowDomain(const Value: Boolean);
  198. begin
  199.   FDontGoBelowDomain := Value;
  200. end;
  201.  
  202. procedure TjwShellBrowseFolder.SetRootStart(const Value: TRootStart);
  203. begin
  204.   FRootStart := Value;
  205. end;
  206.  
  207. procedure TjwShellBrowseFolder.SetStatusText(const Value: Boolean);
  208. begin
  209.   FStatusText := Value;
  210. end;
  211.  
  212. function TjwShellBrowseFolder.SetSelection(hwnd: THandle;
  213.   const Value: String): Boolean;
  214. begin
  215.   // ...ibdib...
  216.   Result := True;
  217.   try
  218.    // SendMessage(hwnd, BFFM_SETSELECTION, 1, PChar(@Value[1]+#0));
  219.   except
  220.     Result := False;
  221.   end;
  222. end;
  223.  
  224. end.
  225.