最新Windows API调用系统对话框.docx
- 文档编号:29618844
- 上传时间:2023-07-25
- 格式:DOCX
- 页数:17
- 大小:24.88KB
最新Windows API调用系统对话框.docx
《最新Windows API调用系统对话框.docx》由会员分享,可在线阅读,更多相关《最新Windows API调用系统对话框.docx(17页珍藏版)》请在冰豆网上搜索。
最新WindowsAPI调用系统对话框
WindowsAPI调用系统对话框
WindowsAPI调用系统对话框
转一些从shell32.dll导出的函数
外壳对话框
外壳对话框的秘密
常见的Windows的通用对话框被封装在Comdlg32.dll,这给我们的编程提供了很大的便利。
但它还不够完整,我们在系统里经常能看到大量的可重复使用的对话框,但在Windows的文档里你却找不到它们的调用方法。
而如果我们自己去做这样的界面是非常费时费力的而且也是没有必要的,因为这些对话框实际上很容易得到。
这里我要介绍一些已经众所周知或不为认知的对话框,它们可以应用在我们的程序中使程序显得非常友好和专业。
浏览文件夹对话框
图2.23
大多数Delphi程序员都知道如何使用VCL的TOpenDialog控件来让用户浏览将要打开的文件。
然而有时你可能只想让用户选择文件夹而不是特定的文件,windows已经提供了一个这样的对话框如图2.23所示。
我们可以通过公开的函数SHBrowseForFolder来调用(这个函数定义在ShlObj单元),函数定义如下:
functionSHBrowseForFolder(varBrowseInfo:
TBrowseInfo):
PItemIDList;stdcall;
这个函数只有一个参数,但这个参数是一个比较复杂的记录类型
TBrowseInfo=packedrecordhwndOwner:
HWND;
pidlRoot:
PItemIDList;
pszDisplayName:
PChar;
lpszTitle:
PChar;
ulFlags:
UINT;
lpfn:
TFNBFFCallBack;
lParam:
LPARAM;
iImage:
Integer;
end;
hwndOwner数据成员包含对话框的父窗体的窗口句柄,可以把它设成0。
PIdlRoot数据成员指向一个PIDL的指针对应于对话框初始化时的根目录。
指定了PIdlRoot后,就只有根目录及它的子目录会出现在对话框中。
可以设定它为nil,这时缺省的根目录是桌面,pszDisplayName数据成员指向一个缓冲区可以用来储存被用户选中的文件名,缓冲区的大小至少为MAX_PATH这个常数那么大,否则遇到特别长的文件名会溢出。
lpszTitle数据对象指向一个以null结尾的字符串,字符串作为对话框的标题来显示。
注意标题不要太长,否则显示时会被截断。
ulFlags标志数据对象用来限制在对话框中显示的文件夹类型。
可以设定它为0或下列值的组合:
//在对话框中会包含一个状态区,回调函数可以通过向对话框发送消息来设定状态
BIF_STATUSTEXT
//只允许选择标准文件系统,若选了非标准的文件夹如打印机,确认按钮会变灰
BIF_RETURNONLYFSDIRS=[message]01;
//不选择网络文件夹
BIF_DONTGOBELOWDOMAIN=[message]02;
//给状态条留出空白
BIF_STATUSTEXT=[message]04;
//只选择文件系统的上级目录
BIF_RETURNFSANCESTORS=[message]08;
//只选择计算机
BIF_BROWSEFORCOMPUTER=00;
//只选择打印机
BIF_BROWSEFORPRINTER=00;
//包括文件也可以选
BIF_BROWSEINCLUDEFILES=00;
注意:
如果你想对话框显示lpszTitle里的用户定制的状态条信息,必须包括BIF_STATUSTEXT标识。
Lpfn数据对象是一个回调函数类型的指针,函数类型如下:
TFNBFFCallBack=function(DialogHandle:
HWND;
MessageID:
UINT;PIDL:
PItemIDList;Data:
LPARAM):
Integer;stdcall;
这是一个回调函数,可以用来在同用户交互时控制和更新对话框的显示。
如果你不想控制对话框,可以把它设成nil,lParam数据对象允许你在回调函数中以参数lpfn形式返回一个指针(通常我们用它来返回对象),当然也可以把它设成为0。
IImage数据成员不需要设置,因为它是用来接收系统中同文件夹相关的图标列表索引的,我们这里设它为0。
SHBrowseForFolder函数返回一个唯一的指向被选择的文件夹的PIDL。
如果文件夹是一个传统的文件对象的话,可以用函数SHGetPathFromIDList把PIDL转换为真实的目录。
同时,作为调用者,必须负责释放被返回的itemidentifierlist,使用IMallocCOM接口来释放。
注意:
不要用FreeMem或其他方法来释放PIDL,这是因为外壳的内存管理是独立的,只能用IMalloc来释放。
现在我们已经可以显示对话框了,那让我们更深入一步看看如何能够控制对用户动作的反应,这就要用到了回调函数TFNBFFCallBack。
注意回调函数的意思就是,你只是实现了它,系统就知道什么时候去调用它,就好比一个守株待兔的例子。
DialogHandle参数代表对话框窗口句柄。
通常可以用这个句柄给对话框发消息,MessageID参数并不是一个TMessage结构的记录,它是对话框通过回调函数发给用户消息的,它可以是下面两个值:
BFFM_INITIALIZED=1;//对话框将要显示
BFFM_SELCHANGED=2;//用户选中了某项
PIDL参数包含其他的额外信息。
如果MessageID是BFFM_INITIALIZED,PIDL将等于nil。
如果MessageID是BFFM_SELCHANGED,PIDL的值将是一个PIDL对应于用户选择的文件夹。
Data参数包含用户付给TbrowseInfo记录中的Lparam数据成员的值,通常可以传递一个对象指针。
下面是一个简单的回调函数的例子:
functionBrowseForFolderCallback(DialogHandle:
HWND;
MessageID:
UINT;PIDL:
PItemIDList;Data:
LPARAM):
Integer;
begin
//响应对话框的通知消息
case(MessageID)ofBFFM_INITIALIZED:
DialogInitialized(DialogHandle,Data);
BFFM_SELCHANGED:
HandleNewSelection(DialogHandle,PIDL,Data);
end;
Result:
=0;//总返回0.
end;
在回调函数里,可以根据用户的输入发送三个用户的消息给对话框,下面是消息ID:
//改变对话框的状态信息
BFFM_SETSTATUSTEXT=WM_USER+100;
//控制确定按钮失效与否
BFFM_ENABLEOK=WM_USER+101;
//改变选择的文件夹
BFFM_SETSELECTION=WM_USER+102;
通常,这些消息发送给对话框使之根据用户的选择更新显示,当然你也可以发送其他的消息给对话框,比如可以发送WM_SETTEXT消息来改变对话框的标题。
下面是一个发送消息的例子(见表2.11):
PostMessage(DialogHandle,BFFM_SETSELECTION,True,LPARAM(PChar(NewPath)));
表2.11MessageIDWParamLParamBFFM_SETSTATUSTEXT没有使用一个指向新的状态信息的PcharBFFM_ENABLEOK没有使用True使得确认按钮有效,False无效
BFFM_SETSELECTION如果Lparam是路径则为True,若Lparam是PIDL则为False指向被选择的文件路径或PIDL的Pchar
另外要提到的是,Delphi也提供了对这个函数的封装,那就是SelectDirectory函数。
关于对话框
通常我们都要在自己的程序里加上一个关于对话框来显示一些版本信息等等,Windows为我们提供了一个标准的对话框如图2.24所示,可以在一定范围内对它定制,不过它只适合显示简单的标识和文本(我觉得用处极小)。
我们可以通过函数ShellAbout来调用它(声明在ShellAPI单元里),函数定义如下:
functionShellAbout(Owner:
HWND;ApplicationName:
PChar;
OtherText:
PChar;IconHandle:
HICON):
Integer;stdcall;
Owner参数标识了拥有对话框的父窗体句柄,通常设为0,表明没有父窗体。
ApplicationName参数包含对话框的标题,字符串中可以包含"#"字符,它能起到分割符的作用。
这种情况下,函数会把分割符前的字符串作为标题栏,分割符后的部分作为"Microsoft"字符串后的第一行。
OtherText参数包含了打算显示在Microsoft版本和版权信息后的字符串。
IconHandle参数标识了打算显示在对话框上的图标标识,如果设为0,函数会显示Windows缺省的图标。
图2.24
图2.25
格式化对话框
SHFormatDrive函数会显示一个格式化对话框,如图2.25所示,它是一个半公开的函数。
但现在它不在微软的SDK里。
然而微软承认它的存在并把它从Shell32.dll里用名字公开声明,Delphi中的函数定义如下:
functionSHFormatDrive(Owner:
HWND;Drive:
UINT;
FormatID:
UINT;OptionFlags:
UINT):
DWORD;stdcall;
Owner参数标识拥有对话框的窗体句柄,文档中推荐不要设为0,但实际上好像没什么影响。
Drive参数是用来标识打算格式化的驱动器的数值,它是以0为底的,从A开始A:
=0,B:
=1依此类推。
FormatID参数允许我们指定一个格式化的模板,通常情况下,只要赋值为SHFMT_ID_DEFAULT就可以了。
OptionFlags参数是一个选项掩码,来确定格式化的选项。
当前有两个选项:
SHFMT_OPT_FULL=[message]01;//快速格式化
SHFMT_OPT_SYSONLY=[message]02;//复制系统文件
如果函数调用失败,会返回下列错误中的一种来表明错误原因,错误常数如下:
SHFMT_NOFORMAT=$FFFFFFFD;//驱动器无法格式化
SHFMT_CANCEL=$FFFFFFFE;//格式化被取消了
SHFMT_ERROR=$FFFFFFFF;//其他错误
WindowsNT和WideChar
在进一步研究未公开的函数前,我们必须清楚一点,对于未公开的函数来说以null结尾的字符串类型参数大多数被声明为类型指针而不是PChar。
这有点像陷阱,但必须承认这是事实。
在Win9X上所有的字符串类型参数声明为PAnsiChar,而在WindowsNT上被声明为PWideChar。
如果你想你的应用程序适应所有平台,你必须考虑两种情况,在运行时要判断平台类型,这是很讨厌的,但这也是使用未公开的API的代价。
选择图标对话框
图2.26
我们要讨论的第一个完全未公开的函数是PickIconDlg。
如图2.26所示这个函数会显示一个对话框,用户可以用来从文件中选择一个图标资源。
它通常是用文件类型编辑器来关联图标和某一文件类型的,也会在快捷方式对话框中被调用来修改快捷方式的图标。
这个函数从Shell32.dll用值62来公开出来,函数定义如下:
functionPickIconDlg(Owner:
HWND;FileName:
Pointer;
MaxFileNameChars:
DWORD;varIconIndex:
DWORD):
LongBool;stdcall;
Owner参数和上面的意义类似。
FileName参数指向一个缓冲区,包含了被浏览图标的文件名,缓冲区要不小于MAX_PATH+1。
MaxFileNameChars指定字符数量大小。
IconIndex常数是以0为底的图标索引,当对话框打开时会把焦点定在IconIndex对应的图标上,函数返回后,IconIndex指向最后被选的图标索引。
如果用户点了取消按钮,函数返回False。
运行程序对话框
图2.27RunFileDlg函数是相当灵活的,如图2.27所示就是调用开始菜单的运行子菜单后会显示的对话框,我们通过值61把它从Shell32.dll暴露出来。
下面是函数声明:
procedureRunFileDlg(Owner:
HWND;IconHandle:
HICON;
WorkPath:
Pointer;Caption:
Pointer;Description:
Pointer;Flags:
UINT);stdcall;
Owner参数就不用再说了。
IconHandle参数是显示在对话框上的图标句柄,如果为nil,缺省的icon将会使用。
WorkPath参数指向一个字符串来指定应用程序运行的工作路径。
Title参数指向作为对话框标题的字符串,如果为nil,就使用缺省的标题。
Description参数指向一个描述字符串,主要是告诉用户如何去做,可以设为nil,这时使用缺省的描述。
Flags参数用一组位掩码来设定对话框的属性。
下面是定义:
RFF_NOBROWSE=;//移去浏览按钮
RFF_NODEFAULT=;//无缺省的选项
RFF_CALCDIRECTORY=;//由文件名确定工作路径
RFF_NOLABEL=;//去掉编辑框标签
RFF_NOSEPARATEMEM=;//去掉在单独的内存空间运行的复选框(只对NT有效)
这个对话框一个很好的特性是允许你控制用户可以运行的应用程序。
当用户选择了确认按钮,对话框的父窗体会发送一个通知消息来传递将要运行的程序信息。
通知消息是一个WM_NOTIFY消息,它的通知代码设定为RFN_VALIDATE(-510),然后lParam指向一个TNM_RunFileDlg记录。
定义如下:
TNM_RunFileDlg=packedrecordhdr:
TNMHdr;
lpFile:
Pointer;
lpDirectory:
Pointer;
nShow:
LongBool;
end;
hdr数据对象是TNMHdr类型,它是一种标准的Windows数据类型,每个WM_NOTIFY消息的lParam参数都会指向这个数据成分。
同时根据不同的消息类型,可能一些额外的数据跟在记录后面,标准的TNMHdr记录定义如下:
TNMHdr=packedrecordhwndFrom:
HWND;
idFrom:
UINT;
code:
UINT;
end;
记录中的hwndFrom包含发送消息的窗口句柄,idFrom则包含发送消息的控件标示符,code中包含标识被发送的消息的通知代码。
在TNMHdr记录后被打包的额外数据包含三个数据成分:
LpFile指向一个包含将要运行的文件的路径字符串;LpDirectory指向正在运行程序的工作目录字符串;最后,nShow用来指定将要运行的应用程序是否可见。
对于本文中特定的消息,只对TNMHdr记录中的Code感兴趣,通过检验Code可以确保我们收到一个运行文件校验消息,同时使我们可以存取额外的TNM_RunFileDlg数据成员。
当TNMHdr记录中的code等于RFN_VALIDATE(-510)时,可以获得一个TNM_RunFileDlg记录。
下面是校验消息的代码:
varFileToRun:
String;
.
ifTheMessage.Msg=WM_NOTIFYthenifPNMHdr(TheMessage.LParam).code=RFN_VALIDATEthenWideCharToStrVar(PNM_RUNFILEDLG(
TheMessage.LParam).lpFile,FileToRun);
.
注意只有当我们已经检验TNMHdr的Code为RFN_VALIDATE后,才映射LParam参数为PNM_RunFileDlg类型。
通知消息的返回值决定了应用程序是否能够运行,下面是可能的值:
RF_OK=[message];//允许程序运行
RF_CANCEL=;//取消操作,关闭对话框
RF_RETRY=;//取消操作,对话框仍然打开
查找文件对话框
图2.28
调用查找文件对话框的函数是SHFindFiles,对话框如图2.28所示。
它是从Shell32.dll按索引值90公开出来的:
functionSHFindFiles(SearchRoot:
PItemIDList;
SavedSearchFile:
PItemIDList):
LongBool;stdcall;
SearchRoot参数允许从一个特定的文件夹开始查找,同在资源管理器中在文件夹上用右键点击查找菜单的效果是一样的。
如果设为nil,那么查找是从桌面开始的。
SavedSearchFile参数让你指定一个以前查询保存的查找策略文件(*.fnd文件),根据以前的设定来查找,若不需要的话可以设定为nil。
如果你指定了一个非空值的SearchRootPIDL,那么在调用完SHFindFiles后必须负责释放掉。
但是有点奇怪的是,如果你指定了一个非空的SavedSearchFilePIDL参数,函数成功调用的话,你不能去释放这个PIDL,否则会出错,但如果调用失败了的话,你必须释放它。
同大多数对话框函数不一样,这个函数是非模态的,也就是系统在另外一个独立的线程中启动对话框,然后立即返回,对话框会在你的程序结束后自动关闭。
也就是说你没有任何直接的方法来告诉用户如何使用查找到的结果,所以要想知道用户找到的文件的话,最好是让你的程序支持文件拖放,以便让用户把找到的文件拖放给你。
查找电脑对话框
同SHFindFiles比较接近的一个函数是SHFindComputer,这个函数调用的结果同开始菜单上查找电脑菜单调用的结果是一样的。
它的参数同SHFindFiles完全一样,不同之处在于它完全忽略传递给它的参数,很显然是保留起来为了将来扩展的需要。
这里我们只要把参数都设成nil就可以了,另外注意这个对话框也是非模态的。
SHFindComputer是从Shell32.dll以索引号91公开出来的:
functionSHFindComputer(Reserved1:
PItemIDList;
Reserved2:
PItemIDList):
LongBool;stdcall;
查找文件对话框
通过调用GetFileNameFromBrowse函数可以调出这个对话框,不过说实在的,它实际上只是GetOpenFileName函数的简单封装。
而我们常用的TOpenDialog控件也是对GetOpenFileName函数封装,这个函数我们很少会去直接用它。
不过还是写出来吧,它是从Shell32.dll里按索引值63公开出来的:
functionGetFileNameFromBrowse(Owner:
HWND;
FileName:
Pointer;MaxFileNameChars:
DWORD;
InitialDirectory:
Pointer;DefaultExtension:
Pointer;
Filter:
Pointer;Caption:
Pointer):
LongBool;stdcall;
图2.29
大多数参数对应于OPENFILENAME结构的成员。
Owner参数我想就不用再重复了,FileName参数指向一个初始化对话框编辑控制文件名的缓冲区,函数返回后FileName包含被选择的文件路径,它的大小一般设成MAX_PATH+1那么大。
MaxFileNameChars参数用来指定FileName缓冲区的大小。
InitialDirectory参数指向对话框初始化的目录名,但如果FileName参数被指定了,InitialDirectory就会被忽略而使用FileName参数中的路径。
DefaultExtension参数指向一个包含要搜索的缺省扩展名的字符串。
Filter参数指向一个以null结尾的可以用来在下拉列表中限定文件类型的过滤字符串。
Caption参数指向对话框标题字符串。
如果用户选择了一个要打开的文件,函数返回True,当有错误发生,用户选择取消按钮或关闭对话框的话会返回False。
外壳对象属性对话框
另一个未公开的对话框函数是SHObjectProperties,它可以用来显示外壳对象的属性,比如驱动器、文件夹或文件等,运行效果如图2.29所示。
函数可以从Shell32.dll中按索引值178公开出来,定义如下:
functionSHObjectProperties(Owner:
HWND;Flags:
UINT;
ObjectName:
Pointer;InitialTabName:
Pointer):
LongBool;stdcall;
Flags参数用来指定ObjectName参数对应对象的类型,它可以是下列标识:
//打印机
OPF_PRINTERNAME=;
//路径
OPF_PATHNAME=;
ObjectName参数指向一个包含路径名的字符串或是要显示属性的打印机名。
如果打印机是本地的,可以使用实际的打印机名,如果是网络打印机,就需要使用完整的UNC样式名称,比如\COMPUTERNAME\PRINTERNAME。
InitialTabName参数指向一个属性对话框中页面名称字符串,用来指定要显示的缺省页面。
如果InitialTabName参数为nil,或不匹配任何页面的名称,第一个属性页面将会被显示。
如果函数调用成功会返回True,如果失败会返回False。
要想获得扩展的错误信息,可以调用API函数GetLastError。
要注意的是这个对话框是非模态的,类似于查找文件对话框,所以函数一被调用,就肯定会显示一个对话框,同时我们没有办法知道用户什么时候关闭了对话框。
映射网络驱动对话框
图2.30
图2.30显示了映射网络驱动器的对话框,我们通过SHNetConnectionDialog函数调用它(win9x和WinNT上都支持),它可以按索引值160从Shell32.dll暴露出来,函数定义如下:
functionSHNetConnectionDialog(Owner:
HWND;
ResourceName:
Pointer;ResourceType:
DWORD):
DWORD;stdcall;
SHStartNetConnectionDialog函数也会显示同样的对话框,但它显示的对话框是非模态的,同时只在NT上才支持。
它可以按索引值215从Shell32.dll中公开出来,函数定义如下:
functionSHStartNetConnectionDialog(Owner:
HWND;
ResourceName:
PWideChar;ResourceType:
DWORD):
DWORD;stdcall;
上面两个函数的参数完全相同。
其中ResourceName参数指向一个要连接的网络资源UNC路径名。
指定了这个参数的话,显示的对话框中被预设的连接资源就不可改变了。
如果这个参数为nil,则在对话框中用户可以指定要连接的资源。
ResourceType参数可以是下面的值之一:
RESOURCETYPE_DISK或RESOURCETYPE_PRINT。
它的不同将会生成不同的对话框。
参数为RESOURCETYPE_DISK允许我们为网络驱动资源
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 最新Windows API调用系统对话框 最新 Windows API 调用 系统 对话框