SHBrowseForFolder的回调函数使用(100分)

  • 主题发起人 主题发起人 Micro Whaight
  • 开始时间 开始时间
M

Micro Whaight

Unregistered / Unconfirmed
GUEST, unregistred user!
如何做到:当选择的目录变化时,即时的在窗口中显示出<br>相应的选中目录名.好象和SHBrowseForFolder的回调<br>函数中的消息: BFFM_SELCHANGED(是不是还有<br>BFFM_SETSTATUSTEXT?)有关.只是不知道具体该如何<br>写这个回调函数以及给BrowseInfo的lParam参数赋值.<br><br>可否请写段具体代码?因为我对回调函数及WinAPI不熟悉<br><br>相关函数如下:<br><br>function BrowseCallbackProc(hwnd: HWND; <br>&nbsp; uMsg: UINT; lParam: Cardinal;<br>&nbsp; lpData: Cardinal): integer; stdcall;<br>begin<br>&nbsp; if uMsg = BFFM_INITIALIZED then<br>&nbsp; &nbsp; result := SendMessage(Hwnd,BFFM_SETSELECTION,<br>&nbsp; &nbsp; &nbsp; Ord(True),Longint(PChar(sStartPath)))<br>&nbsp; &nbsp; &nbsp; //sStartPath是个全局字符串变量,用于初始定位<br>&nbsp; else if uMsg = BFFM_SELCHANGED then<br>&nbsp; begin<br>// &nbsp;result := ??????????<br>// &nbsp;result := SendMessage(Hwnd, BFFM_SETSTATUSTEXT, ?????)<br>&nbsp; end<br>&nbsp; else<br>&nbsp; &nbsp; result := 1;<br>end;<br><br>function SelDir(const Caption: string; <br>&nbsp; const Root: WideString; out Directory: string): Boolean;<br>var<br>&nbsp; ...<br>&nbsp; BrowseInfo: TBrowseInfo;<br>begin<br>&nbsp; ...<br>&nbsp; sStartPath := ExtractFileDir(Application.ExeName);<br>&nbsp; with BrowseInfo do<br>&nbsp; begin<br>&nbsp; &nbsp; hwndOwner := Application.Handle;<br>&nbsp; &nbsp; pidlRoot := RootItemIDList;<br>&nbsp; &nbsp; pszDisplayName := Buffer;<br>&nbsp; &nbsp; lpszTitle := PChar(Caption);<br>&nbsp; &nbsp; ulFlags := BIF_RETURNONLYFSDIRS;<br>&nbsp; &nbsp; lpfn := @BrowseCallbackProc;<br>// &nbsp;lParam := ???????????????????<br>&nbsp; end;<br>&nbsp; ...<br>end;<br>
 
真的没办法吗?还是太过麻烦?再加100分。 :)
 
BROWSEINFO info;<br>LPCITEMIDLIST itemid;<br>char dir[50];<br>info.hwndOwner=this-&gt;Handle;<br>info.pidlRoot=NULL;<br>info.pszDisplayName=NULL;<br>info.lpszTitle="select directory";<br>info.ulFlags=0;<br>info.lpfn=NULL;<br>info.lParam=0;<br>info.iImage=0;<br>itemid=SHBrowseForFolder(&amp;info);<br>if(itemid!=NULL)<br>&nbsp;{<br>&nbsp;SHGetPathFromIDList(itemid,dir);<br>&nbsp;Label1-&gt;Caption=AnsiString(dir);<br>&nbsp;}<br>
 
对不起, wangxd, 可能我没把问题说清楚. 我是想在那个调出的<br>系统选择文件夹对话框中, 根据用户的选择, 即时地反映出当前<br>选择的目录(此时用户还没有按下"选择文件夹"对话框中的确定按<br>钮).效果有点象... 象NetVampire 3.3中的选择下载文件保存目<br>录中的效果: 在打开这个对话框后, 用户选择了一个目录, 就会在<br>对话框中显示目录的名称, 但是用户还没有按下确定按钮. 你说的<br>方法, 只能在用户按下 "确定" 按钮后, 才能在某个 Label 中显<br>示. 这个我已经实现了.
 
与其这样,不如不使用SHBrowseForFolder,自己做一个文件夹选择窗口<br>systree控件可以很方便地实现这个,比SHBrowseForFolder还好看,而且支持多选<br>
 
这样子:<br>&nbsp; <br>function BrowseCallbackProc(Handle: HWND;<br>&nbsp; uMsg: UINT; lParam: Cardinal;<br>&nbsp; lpData: Cardinal): integer; stdcall;<br>var<br>&nbsp; dirbuf: array[0..Max_Path-1] of Char;<br>begin<br>&nbsp; Result := 0;<br>&nbsp; if uMsg = BFFM_INITIALIZED then<br>&nbsp; begin<br>&nbsp; &nbsp; if GetCurrentDirectory(Max_path,@dirbuf) &gt; 0 then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // WParam is TRUE since you are passing a path.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // It would be FALSE if you were passing a pidl.<br>&nbsp; &nbsp; &nbsp; &nbsp;SendMessage(Handle,BFFM_SETSELECTION,1,LongInt(@Dirbuf));<br>&nbsp; end<br>&nbsp; else if &nbsp;uMsg = BFFM_SELCHANGED then<br>&nbsp; begin<br><br>&nbsp; &nbsp; &nbsp;// Set the status window to the currently selected path.<br>&nbsp; &nbsp; &nbsp;if SHGetPathFromIDList(PItemIDList(lParam) ,@Dirbuf) then<br>&nbsp; &nbsp; &nbsp; &nbsp;SendMessage(Handle,BFFM_SETSTATUSTEXT,0,LongInt(@Dirbuf));<br>&nbsp; end;<br>end;<br><br>function SelectDirectoryEx(const Caption: string; const Root: WideString;<br>&nbsp; out Directory: string): Boolean;<br>var<br>&nbsp; WindowList: Pointer;<br>&nbsp; BrowseInfo: TBrowseInfo;<br>&nbsp; Buffer: PChar;<br>&nbsp; RootItemIDList, ItemIDList: PItemIDList;<br>&nbsp; ShellMalloc: IMalloc;<br>&nbsp; IDesktopFolder: IShellFolder;<br>&nbsp; Eaten, Flags: LongWord;<br>begin<br>&nbsp; Result := False;<br>&nbsp; Directory := '';<br>&nbsp; FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);<br>&nbsp; if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc &lt;&gt; nil) then<br>&nbsp; begin<br>&nbsp; &nbsp; Buffer := ShellMalloc.Alloc(MAX_PATH);<br>&nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; RootItemIDList := nil;<br>&nbsp; &nbsp; &nbsp; if Root &lt;&gt; '' then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; SHGetDesktopFolder(IDesktopFolder);<br>&nbsp; &nbsp; &nbsp; &nbsp; IDesktopFolder.ParseDisplayName(Application.Handle, nil,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; POleStr(Root), Eaten, RootItemIDList, Flags);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; with BrowseInfo do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; hwndOwner := Application.Handle;<br>&nbsp; &nbsp; &nbsp; &nbsp; pidlRoot := RootItemIDList;<br>&nbsp; &nbsp; &nbsp; &nbsp; pszDisplayName := Buffer;<br>&nbsp; &nbsp; &nbsp; &nbsp; lpszTitle := PChar(Caption);<br>&nbsp; &nbsp; &nbsp; &nbsp; ulFlags := BIF_RETURNONLYFSDIRS or BIF_STATUSTEXT;//包含 BIF_STATUSTEXT<br>&nbsp; &nbsp; &nbsp; &nbsp; lpfn := @BrowseCallbackProc; &nbsp;//回调函数<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; WindowList := DisableTaskWindows(0);<br>&nbsp; &nbsp; &nbsp; try<br>&nbsp; &nbsp; &nbsp; &nbsp; ItemIDList := ShBrowseForFolder(BrowseInfo);<br>&nbsp; &nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; &nbsp; EnableTaskWindows(WindowList);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; Result := &nbsp;ItemIDList &lt;&gt; nil;<br>&nbsp; &nbsp; &nbsp; if Result then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; ShGetPathFromIDList(ItemIDList, Buffer);<br>&nbsp; &nbsp; &nbsp; &nbsp; ShellMalloc.Free(ItemIDList);<br>&nbsp; &nbsp; &nbsp; &nbsp; Directory := Buffer;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; finally<br>&nbsp; &nbsp; &nbsp; ShellMalloc.Free(Buffer);<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>end;<br><br>SelectDirectoryEx 这个函数主要是从 FileCtrl.pas 中拷过来的,只作了些修改。其它<br>的参考了 MSDN。运行测试过了。
 
谢谢bbkxjy!!!<br><br>请到543347贴拿另外的100分.
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
后退
顶部