我们编程时也许遇到过这样的问题:在一个Label或是Panel上显示路径,当路径过长显示不下的时候,希望像某些安装程序拷贝文件的时候那样把路径缩短,其中部分用省略号代替,比如:
C:/Program Files/Borland/Delphi5/Source/Rtl/Win-->C:/Program Files/Borland/.../Win
自己编程实现并不难,不过不知什么原因,我一直没有动手做,忽然有一天,我看到了一篇文章,于是,一切问题迎刃而解,随之而来的,竟是意想不到的收获
那是一段Visual Basic的程序,不过,我第一眼就看到了一个函数的声明:PathCompactPath:
Private Declare Function PathCompactPath _
Lib "shlwapi" Alias "PathCompactPathA" ( ByVal hDC As Long, _
ByVal lpszPath As String, _
ByVal dx As Long) As Long
它需要三个引数,说明如下:
hDC:device context handle。
lpszPath:the address of the pathname。
dx:the width in pixels of the spot in which you want the pathname to fit。
经过几番修改,在Delphi中试验通过了,果然能够做到压缩路径的效果,但我更感兴趣的是,ShlWapi.dll中是不是还有不少可以用的好东东呢?打开MSDN,敲入“ShlWapi”一搜索,果然出现一堆(注意,是 “一堆”)以“Path”开头的函数,欣喜之情,不在话下。于是我便一个个查看其功能,发现我们需要的关于路径的几乎所有功能都有相应的的函数可以调用,比如:
PathAddBackslash、PathRemoveBackslash:在路径后面添加或去除“/”;
PathIsDirectory、PathIsHTMLFile、PathIsPrefix、PathIsRoot、PathIsURL……
等等,随便试了几个,可以用,接着我又琢磨如何找出其中全部的函数声明,我知道很多动态链接库在MSDN上都有相应的头文件,这次也许不会例外。果然又被我猜中!ShlWapi.H确实存在。接下来的工作就比较烦了,花了些时间,以“查找、替换”大法为辅助,我把其中关于路径操作的函数声明做成了ShlWapi.pas(ShlWapi.H中包括几部分的函数声明:字符串、路径、注册表、注册表流、调色板,还有一个很有用的函数DllGetVirsion,完整的声明可以在这里下载)。
再来说说PathComact(或者叫PathEllipsis), PathCompactPath函数需要设备的HDC做参数,使用起来可能会麻烦一点,所以还有另外一个函数PathCompactPathEx,参数与设备无关,不过关于字符和显示宽度的换算也有些地方需要推敲,我做了一个简单的EllipsisPanel控件,可以作为例子。
同样的功能,也可以用DrawText函数来完成,参数说明在MSDN 或者Delphi的Windows SDK Help中找能找到,功能比PathCompactPath要强,调用的时候可以选择是在路径中间省略还是在路径尾部省略(类似于资源管理器的标题栏不能显示完整路径名的时候做的处理)DFS的dfsEllipsisPanel就是用它做的。
來看看实际的例子吧!请在表单中加入一个 CommandButton 及一个 Label,不用更改任何属性,將以下的程序代码复制到表单中:
Private Sub Command1_Click()
Dim lhDC As Long, lCtlWidth As Long
Dim FileSpec As String
lhDC = Me.hDC
FileSpec = "C:/MyFolder/VisualBasic/MyReallyWayTooLongFolderName/"
FileSpec = FileSpec & "ButWhoCares/IhaveTheAPI.doc"
Me.ScaleMode = vbPixels
lCtlWidth = Label1.Width - Me.DrawWidth
PathCompactPath lhDC, FileSpec, lCtlWidth
Label1.Caption = FileSpec
End Sub
记住 Label1 的宽度不要太大,如果 Label1 的宽度本來就放得下全路径文件名,那就沒有必要压缩全路径文件名了!