如何实现像OFFICE中的软件里的打开文件对话框(open dialog)?(300分)

  • 主题发起人 主题发起人 yexiaofeng
  • 开始时间 开始时间
Y

yexiaofeng

Unregistered / Unconfirmed
GUEST, unregistred user!
在OFFICE的各个软件中,使用了增强的打开文件对话框。其中有一个功能我觉得非常有用:
在用户打开文件时,只需输入前几个字母,它就会自动根据目录下的文件补全文件名及后缀
名(只要目录中存在以那几个字母开头的文件)。这项功能在从一个具有非常多文件的目录
下打开文件时非常有用。我想知道怎样才能实现这样的功能?
希望各位大富翁能给出实现思路。是否要从DELPHI中继承open dialog写一个新控件来实现
这样的功能?DELPHI中的open dialog有这样的属性或方法实现吗?如果直接调用office的
DLL来实现是否可行?难度有多大?
 
你要的就是这个吧:

uses
CommDlg;

type //定义打开文件对话框信息结构回调函数
TLPOFNHOOKPROC = function(h: hwnd; uMsg: UINT; wp: wparam; lp: lParam): integer;
type //定义打开文件对话框信息结构
TOpenInfo = packed record
lStructSize: dword;
hwndOwner: hwnd;
hInstance: Hwnd;
lpstrFilter: LPCTSTR;
lpstrCustomFilter: LPTSTR;
nMaxCustFilter: dword;
nFilterIndex: dword;
lpstrFile: lptstr; //该参数使用来存放对话框返回的文件名(包含路径)的,得是一个至少256个长的Pchar
nMaxFile: dword; //该参数使用来指定info.lpstrFile长度以及存放对话框返回的文件名的长度的
lpstrFileTitle: lptstr;
nMaxFileTitle: dword;
lpstrInitialDir: lpctstr;
lpstrTitle: lpctstr;
Flags: dword;
nFileOffset: word;
nFileExtension: word;
lpstrDefExt: lpctstr;
lCustData: Lparam;
lpfnHook: TLPOFNHOOKPROC;
lpTemplateName: lpctstr;
pvReserved: integer;
dwReserved: dword;
FlagsEx: dword;
end;

function GetOpenFileName(var info: TOpenInfo): Boolean; stdcall; external 'comdlg32.dll' name 'GetOpenFileNameA';

procedure TForm1.Button1Click(Sender: TObject);
var
info: TOpenInfo;
lpstrFile: array[0..1000] of char;
lpstrFileTitle: array[0..1000] of char;
lpstrFilter: array[0..50] of char;
S: string;
begin
FillChar(lpstrFile, SizeOf(lpstrFile), 0);
FillChar(lpstrFileTitle, SizeOf(lpstrFileTitle), 0);
FillChar(lpstrFilter, SizeOf(lpstrFilter), 0);
S := '文本文件';
Move(S[1], lpstrFilter, Length(S));
S := '*.TXT';
Move(S[1], lpstrFilter[9], Length(S));

info.lStructSize := sizeof(info);
info.hWndOwner := handle;
info.hInstance := hinstance;
info.lpstrFilter := lpstrFilter;
info.lpstrCustomFilter := nil;
info.nMaxCustFilter := 0;
info.nFilterIndex := 1;
info.lpstrFile := lpstrFile;
info.nMaxFile := SizeOf(lpstrFile);
info.lpstrFileTitle := lpstrFileTitle;
info.nMaxFileTitle := SizeOf(lpstrFileTitle);
info.lpstrInitialDir := 'c:/';
info.lpstrTitle := 'Open Test';
info.Flags := OFN_EXPLORER + OFN_ALLOWMULTISELECT;
info.nFileOffset := 0;
info.nFileExtension := 0;
info.lpstrDefExt := 'txt';
info.lCustData := 0;
info.lpfnHook := nil;
info.lpTemplateName := '';
info.pvReserved := 0;
info.dwReserved := 0;
info.FlagsEx := 0;
try
if GetOpenFileName(info) then
ShowMessage(info.lpstrFile);
except
Caption := SysErrorMessage(getlasterror);
end;
end;
 
其实这儿定义的TOpenInfo就是CommDlg单元里的TOpenFilename
所以用TOpenFilename代替TopenInfo后就不用自己声明TopenInfo了。
 
to xianjun:
很高兴您回答我的问题。
但我对控件开发实在是不熟悉,希望你能给我一个例子或告诉我使用上面的函数实现我的要
求的具体步骤。谢谢~
 
如果是库的话可以采用SQL语句进行模糊查询。
如果为文件的话,有点麻烦。
 
我现在给的并不是一个控件,只是一个API调用而已
你只要New一个Application,然后放一Button上去,Double Click它。
再把implementation以下的代码用我上面贴出来的替换运行就可以看到效果了
不过不知是不是你要的效果。
 
OK
我马上试试~
成功的话就结帐~
谢谢你~
 
to Tense: 我觉得只能用操作系统提供的功能了吧,难道还自己写代码实现?
也不是不可以,但是太麻烦了,得不偿失。
 
TO Tense:
你只要打开work或excel试试它的对话框就知道我所说的效果了~
我也觉得这比较麻烦,要不就不会拿那么多分问这个问题了~
 
to xianjun:
我试了你所说的方法了
但好像没什么反应啊。
 
看了下FrontPage2000的效果,的确很好,减少输入。
但xianjun你的代码在delphi6中编译没有通过,你应该在delphi5中通过的吧。
yexiaofeng, 以前在我的系统中,只是数据库的查询才提供如此类似的功能,用SQL执行,
但对文件采用delphi自带的对话框用OLE Container内嵌,没有考虑到这些功能,
以后准备加上这些功能,一下好象有点困难。

 
to xianjun:
我仔细看了看你的代码,看不太懂,但你的代码好想是用来找出符合要求的2文件,但不能
通过打开文件对话框中的输入来选择文件~

能有更详细的方法实现我的目标吗?
 
to Tense:
我在DELPHI5中编译通过,但看不到效果。
我觉得在DELPHI6中应该可以的,可能是你在粘贴代码的时候有错误。xianjun说的方法有点
点问题,就是在贴完代码后该在最后加上一个END.(如果你是完全把implementation以下的
代码用xianjun贴出来的替换的话这样做后就能编译通过)

很高兴能遇到一个朋友对这个问题感兴趣,我个人认为这个功能很有用,不过实现起来确实
是比较有难度,我曾查找过很多论坛及第三方控件网页,都没找到符合要求的方法或控件。

 
我用的是Delphi6,你们都通不过吗?
我这里好好的。
如果还不行的话,我把DEMO给你发过去吧
在我这儿是可以实现你的效果的
不过我用的是Win2K + SP2,跟操作系统应该也有关。
 
我在WIN98下试了一下,确实不行! :(
WIN2K是内置就支持这个功能了。
如果要自己实现的话应该也可以,用FindFirst, FindNext, FindClose函数
不过要看看是否十分必要了。
不知WINME下有没有这个功能?
 
to xianjun:
我的信箱是yexiaofeng@neteasecom

>>我在98下使用你的代码,可以编译通过,但点击BUTTON后没有反应啊。你是用你的代码在
2000下实现那样的对话框的吗?有机会的话我也去试试。

>>我觉得这样的对话框能给用户带来很大的方便,有必要实现。希望大侠能给出实现的思路。
 
呵呵, DEMO是不用发了,因为我在98下也试了,是没反应
只对2000有效。

实现思路就是我在上面说的,在用户输入的时候你用FindFirst等函数找出相应目录
下的相关文件,再把其列出来。
 
但问题是我无法在DELPHI中的open dialog的到输入文件名的onkeypress时间啊,也不知道
它有没有这个事件。
 
to xianjun:
我觉得如果能调用OFFICE中的DLL函数应该是最好的解决方法,但不知道如何做。
 
我看过类似的文章,就是用Dll!。我还有个控件,各位要吗?[:)]
 
后退
顶部