“浏览文件夹”对话框(50分)

  • 主题发起人 主题发起人 3h
  • 开始时间 开始时间
3

3h

Unregistered / Unconfirmed
GUEST, unregistred user!
在95/98中,打开控制面板,系统,设备管理器,找上一个设备,选属性,
升级驱动程序,选搜索,指定位置,按“浏览”会弹出一个“浏览文件夹”
的对话框。

我就是要这个对话框。

在DELPHI和VB中均和OpenFile等通用对话框,自从95后引进了这个对话框
选择指定的文件夹(不是文件),我想,在95/98中常用到此对话框,应该
是,WIN将它作为一个资源来使用的。

那么能否通用调用API来得到这个窗口呢?

我近来写的一个小程序中需要选定一个文件夹,当然可以自己写,我也有第
三方控件,但我认为用第三方控件毕竟来不及自己学习来得有意思。再说那
个控件写的也不怎么样。我研究了一下,它是自己做一个窗口,然后将形状
做得象WIN的那样。毕竟不是利用WIN的资源,我觉得挺可惜,利用已有资源
不但能使程序变小而且稳定性、执行速度也会有提高的。

请诸位大侠想想办法,我找遍了几乎所有的HELP均没看到相关内容。
当然有可能是我笨没看到。:)

50分算了吧,我快变成穷光蛋了。:)
 
不会,学习学习!
 
3h:好象类似的控件比较多(烂),而且多数有SOURCE,你是在浪费分数嘛
 
; D4中已扩展了此函数。在Filectrl单元中(两个)。
1).function SelectDirectory(var Directory: string; Options: TSelectDirOpts; HelpCtx: Longint): Boolean; overload;

2).function SelectDirectory(const Caption: string;
const Root: WideString; out Directory: string): Boolean; overload;

如用于D3,可在D4中复制该函数代码过来(2)。(按住Ctrl,鼠标移至uses域的FileCtrl单击).
Caption : String; //对话框标题。
Root : WideString;//调用初始定位。
Directory : String; //所选择文件夹寄存变量。

另外,改变对话框Handle可控制其窗体显示位置,默认为ForceWindowHandle/0
(即屏幕左上角)。
可以修改该函数的对话框Handle为YoureForm.Handle。便其为ShowModal状态。
如果Root值为null则对话框的树架构从“我的电脑”开始。将Root值更改为"/"
可获得最高级别的对话框(包括桌面,控制面板及打印机等项)。
 
在Delphi的控件板上的Win 3.1标签下,有几个控件可以用来制作Directory Dialog:
1. Add a new DialogBox styled form to your project.
2. Put a DriveComboBox component on the top of your form wit OnChange.
3. Put a DirectoryListBox blow it.
4. Add a OkButton with ModalResult property "mrOK".
5. Add a CancelButton with ModalResult property "mrCancel".
6. Add a Public function Execute: boolean.
7. Add a Public Property Directory: string read GetDir Write SetDir.
type
TDirDialog = class(TForm)
DriveComboBox1: TDriveComboBox;
DirectoryListBox1: TDirectoryListBox;
BitBtnOK: TBitBtn;
BitBtnCancel: TBitBtn;
OpenDialog1: TOpenDialog;
procedure DriveComboBox1Change(Sender: TObject);
private
{ Private declarations }
Function GetDirectory: string;
procedure SetDirectory(value: string);
public
{ Public declarations }
function Execute: boolean;
property Directory: string read GetDirectory write SetDirectory;
end;

var
DirDialog: TDirDialog;

implementation

{$R *.DFM}

procedure TDirDialog.DriveComboBox1Change(Sender: TObject);
begin
DirectoryListBox1.Drive := DriveComboBox1.Drive;
end;

function TDirDialog.GetDirectory: string;
begin
result:=DirectoryListBox1.Directory;
end;

procedure TDirDialog.SetDirectory(value: string);
begin
DirectoryListBox1.Directory := value;
end;

function TDirDialog.Execute: boolean;
begin
result:= ShowModal = mrOK;
end;

end.
 
我把Always所说的函数封装成为一个TDirDialog类 -- DirDialogs.pas, 具有
OpenDialog相似的属性.
用法:
1.将DirDialogs放到你的lib目录下, 想用它的时候只需要将DirDialogs加入到uses
说明中即可. 加入以后, 就有一个DirDialog1的全程变量, 程序结束时自动free.
2.function Execute: boolean; //执行对话
3.property Prompt: string; //提示, default=''
4.property Directory: string; //运行结果路径
5.property Drive: string; //运行结果驱动器

unit DirDialogs;

interface
Uses Windows, FileCtrl;

Type
TDirDialog = class
private
fDir: String;
fCaption: String;
function GetDrive: String;
procedure SetDrive(Value: String);
public
function Execute: boolean;
published
property Caption: String read fCaption write fCaption;
property Drive: String read GetDrive;
property Directory: string read fDir;
end;
var
DirDialog1: TDirDialog;

implementation

uses SysUtils;

function TDirDialog.execute: boolean;
begin
result:= SelectDirectory(fCaption, fDir, fDir);
end;
function TDirDialog.GetDrive: String;
begin
if fDir='' then result:=''
else result:= ExtractFileDrive(fDir);
end;
initialization
DirDialog1:=TDirDialog.Create;
finalization
DirDialog1.free;
end.
 
试试下面的代码:这是我以前写的一个程序中的片段。如不行的话我
把完整的程序给你妹一份。

uses ShellApi, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;


var
BI: TBrowseInfo;
pIDLst: PItemIDList;
S: array[0..MAX_PATH-1] of char;

begin
FillChar(S, SizeOf(S), 0);
with BI do
begin
hwndOwner := Handle;
pidlRoot := nil;
pszDisplayName := nil;
lpszTitle := 'just do it!';
ulFlags := 0;
lpfn := nil;
lParam := 0;
iImage := 0;
end;
pIDLst := SHBrowseForFolder(BI);
SHGetPathFromIDList(pIDLst, @S);
// if BI.pszDisplayName <> nil then
FileListBox.Directory := S;

end;
 
我在”电子书库“中也用到这个东东,我是把它封装成函数使用,
RockBoy的跟我的差不多,不过他的一定不能通过编译,因为DELPHI
把这个功能放在SELOBJ单元中声明,应如下:

uses ShlObj;
//目录浏览函数
function TForm1.BrowseFolder:string;
var
Info:TBrowseInfo;
Dir:array[0..260] of char;
ItemId:PItemIDList;
begin
with Info do
begin
hwndOwner:=self.Handle;
pidlRoot:=nil;
pszDisplayName:=nil;
lpszTitle:='请选择相应文件夹';
ulFlags:=0;
lpfn:=nil;
lParam:=0;
iImage:=0;
end;
ItemId:=SHBrowseForFolder(Info);
if ItemId<>nil then
begin
SHGetPathFromIDList(ItemId,@Dir);
Result:=string(Dir);
end
else
Result:='';
end;

该函数如果返回的字符串为空,即用户选择了“取消”按钮。
 
我一直用这个来自 UNDU 的 <a href=/delphi/attachments/browsedr.zip>browsedr.zip</a>.
 
其实这个东西我已经知道了,只是因为这些天不能进论坛才没跟大家说。
再说前面几位高手如HUIZHANG等说的也是可行的,不过它是DELPHI内部写
的一个过程,不合题意。
最后我得到答案是跟斑竹一样,得到那个控件,然后分析其原码,不过有一
点跟大家不同的是,我要在USE下加
OLE2
而不是别的。为什么呢?大家按这个话题继续讨论还有机会得分。:)
 
; 关于 Folder Browser 该说的大概都说了,哪位高手有想过将它做成控件代替 Win31 页面的 DirectoryListbox 呢(Winzip7.0 的 Options -> Configuration
-> Folders -> Folder 已有先例)。这个想法现实吗?
 
大家再说点什么吧。 :)
 
多人接受答案了。
 
后退
顶部