如何指定SelectDirectory的起始目录

  • 主题发起人 主题发起人 import
  • 开始时间 开始时间
I

import

Unregistered / Unconfirmed
GUEST, unregistred user!
下面的例子是正确的,但是为什么在Callback里面,必须采用全局变量,只要采用局部变量就会出现错误?我始终无法理解,难道是内存分配的原因?只要在Callback里面分配内存,就会出现错误!不过那个Longint(pchar(path))可以用一个integer(pchar('D:'))常量来代替,却又是正确的!真的很奇怪。我用HeapAlloc来分配内存也无法达到全局变量的效果。 unit Unit1;
interface
uses
  shlobj,ActiveX;
  
var
   Form1: TForm1;
   Path: string;   //起始路径
implementation
{$R *.DFM}
function BrowseCallbackProc(hwnd: HWND;uMsg: UINT;lParam: Cardinal;lpData: Cardinal): integer; stdcall;
begin
  if uMsg=BFFM_INITIALIZED then
    result :=SendMessage(Hwnd,BFFM_SETSELECTION,Ord(TRUE),Longint(PChar(Path)))
  else
    result :=1
end;
function SelDir(const Caption: string; const Root: WideString; out Directory: string): Boolean;
var
  WindowList: Pointer;
  BrowseInfo: TBrowseInfo;
  Buffer: PChar;
  RootItemIDList, ItemIDList: PItemIDList;
  ShellMalloc: IMalloc;
  IDesktopFolder: IShellFolder;
  Eaten, Flags: LongWord;
begin
  Result := False;
  Directory := '';
  FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);
  if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then
  begin
    Buffer := ShellMalloc.Alloc(MAX_PATH);
    try
      RootItemIDList := nil;
      if Root <> '' then begin
        SHGetDesktopFolder(IDesktopFolder);
        IDesktopFolder.ParseDisplayName(Application.Handle, nil, POleStr(Root), Eaten,           RootItemIDList, Flags);
      end;
      with BrowseInfo do begin
        hwndOwner := Application.Handle;
        pidlRoot := RootItemIDList;
        pszDisplayName := Buffer;
        lpszTitle := PChar(Caption);
        ulFlags := BIF_RETURNONLYFSDIRS;
        lpfn :=@BrowseCallbackProc;
        lParam :=BFFM_INITIALIZED;
      end;
      WindowList := DisableTaskWindows(0);
      try
        ItemIDList := ShBrowseForFolder(BrowseInfo);
      finally
        EnableTaskWindows(WindowList);
      end;
      Result := ItemIDList <> nil;
      if Result then begin
        ShGetPathFromIDList(ItemIDList, Buffer);
        ShellMalloc.Free(ItemIDList);
        Directory := Buffer;
      end;
    finally
      ShellMalloc.Free(Buffer);
    end;
  end;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  Path1: string;
begin
  Path :=Edit1.Text;
  SelDir('SelectDirectory Sample','d:',Path1);
  Edit1.Text :=Path1
end;
end.
2002.11.14:
今天终于解决了设置初始目录必须使用全局变量的问题!高兴哪!这样可以有一个极其好用的SelectDirectory函数了!可以指定Root目录,还可以设定初始化目录!!!!原来,在CallBack里面,那个lParam参数是可以传递数据的,而MSDN中说INIT消息的时候,lParam是0,是错误的,而且MSDN中关于wParam的说法是自相矛盾的!奇怪。
下面的函数可以指定初始化目录,只要在调用之前,赋值给Path参数即可。
 

Similar threads

后退
顶部