VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - VB问题全功略(34)
发表评论(0)作者:不详, 平台:VB6.0+Win98, 阅读:10656, 日期:2002-02-02
VB问题全功略(34)

166、如何找出 Windows / System / Temp 目录的正确路径?(二)
167、如何将长文件名转成短文件名格式 (MS-DOS 8.3)
168、清除画面中各栏位资料
169、为您精心设计的画面拍张快照吧!( Taking a screenshot )
170、随心所欲地移除表单左上方的系统功能表的某几个项目

166、如何找出 Windows / System / Temp 目录的正确路径?(二)

记得我们分三个单元来说明如何找出 Windows / System / Temp 目录的正确路径?

当时我们都是使用 API 来做,使用的 API 分别是:

问题 如何找出 Windows 目录的正确路径?

使用 GetWindowsDirectory Function

问题 如何找出 System 目录的正确路径?

使用 GetSystemDirectory Function

问题 如何找出 Temp 目录的正确路径?

使用 GetTempPath Function

有的人不太喜欢使用 API,一来有的 API 有点难,一来比较不容易找到完整的资料说明或完整的范例。不过以上三个题目都可以不使用 API 就得到答案的!原因如下:

在我们启动电脑的同时,我们的操作系统,会挪出一个区块,用来存放一些系统环境变量,或许您会问,到底存了哪些东西呢?其实说来不外乎几个来源:

1、Autoexec.bat:TMP / TEMP / PATH / PROMPT .....
2、Config.sys:COMSPEC .....
3、Msdos.sys:WinDir / WinBootDir .....
4、当然您的电脑中不一定有 Autoexec.bat 或 Config.sys,不过没关系,系统自己会给定一些初始值!

而这些环境变量,在 VB 中只要使用 ENVIRON Statement 就可以抓得到!语法如下:

Environ[$](environmentstring)

其中 environmentstring 是一个环境变量的字串,例如:〈TEMP〉、〈WinDir〉、〈PATH〉...等。

所以,如果您 .....

要得到 TEMP 的路径,只要使用 Environ("TEMP") 即可,结果可能为 C:\WINDOWS\TEMP。
要得到 Windows 的路径,只要使用 Environ("Windows") 即可,结果可能为 C:\WINDOWS。
而如果您想找到 System 的路径,我想有了 Windows 路径之后,应该不是难事了吧!

167、如何将长文件名转成短文件名格式 (MS-DOS 8.3)

虽然在 Windows95/98 中已经都可以使用长文件名/目录 (最长可以到255个字元),但是在您将长文件名的文件或目录存档时,系统同时给了它一个可以相容于以前 MS-DOS 时代的 8.3 格式的文件名称!

到目前为止,还是有些软件会使用 8.3 格式的文件名称,在安装这些软件时,它们写到注册表中的资料,仍然采用 8.3 格式的文件名称,所以有时候,您在维护系统时,必须知道目前这时长文件的档案,转成 8.3 格式的文件名称之后是什么文件。

以下这个范例会让您在 DirListBox 及 FileListBox 中选择目录及文件名称,然后将您选出的(长)文件名转成 8.3 格式的文件名称,如果您有注意到的话,它不但是将文件名称转掉,连长文件的目录名称也会一起转成 8.3 格式的文件名称。


由于程序码较长,我不再列出程序码,而直接将文件压缩下载:

Source Code 下载

168、清除画面中各栏位资料

当一个 Form 中只有二、三个物件的时候,您要清除其中的资料,您会一个栏位一个栏位来清除,反正就是那么几个物件,二三行指令也就解决了!

但是,若您的 Form 中有二、三十个,甚至五、六十个以上的物件时,可就要想想办法了!以下的这个模组就在这种情形下产生了,一般要清除资料,最重要的二个属性就是 .Text 及 .LisIndex。

Public Sub ClearAllControls(frmFORM As Form)
Dim ctlControl As Object
On Error Resume Next
For Each ctlControl In frmFORM.Controls
ctlControl.Text = ""
ctlControl.ListIndex = -1
DoEvents
Next
End Sub

而在程序中要呼叫这个模组只要如下使用即可:

call ClearAllControls(Me)

169、为您精心设计的画面拍张快照吧!( Taking a screenshot )

我们在设计系统时,有时候会保留让使用者做屏幕 HardCopy 的功能。

以前,我总是要求使用者自己去按键盘上的【Print Screen】按钮,将画面的影像留在【剪贴板】中,并要求使用者自己到 Windows95/98 提供的【小画家】或【小作家】中,先做【贴上】的动作后,再将画面影像存成 .BMP 档或直接由印表机中印出。

上面这些动作,对一个程序开发者,或一个熟练的操作者并不困难,但是,很可悲的,大部份的使用者都不属于以上所描述的二种人,例如:我曾经写过一个系统是给大楼清洁维护公司的人员用的,其中有很多使用者甚至是一些学历不高的『欧巴尚』,不但程序的设计都要简化操作,连系统上线都是高难度的,更别说屏幕的 HardCopy 列印、存档的动作了!

不过,以上的动作,我们都可以直接在 VB 的程序中做到,要做到这个功能有二个方法:
方法一:直接模拟按【Print Screen】按钮,再将【剪贴板】中的图像抓到 Picture 中。
方法二:完全使用 API 来处理。

下面来看看第二种做法:

注释:请在声明区中加入以下声明:

Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hdc As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

Private Const SRCCOPY = &HCC0020

注释:在 Form 中加入二个 CommandButton,及一个 PictureBox,不必更改属性,加入以下程序码:

Private Sub Form_Load()
注释:将 Picture1 之长宽设定成和屏幕一样大小
Picture1.Width = Screen.Width
Picture1.Height = Screen.Height
End Sub

Private Sub Command1_Click()
注释:将屏幕画面抓下后放到 Picture1 中
Dim lngDesktopHwnd As Long
Dim lngDesktopDC As Long

Picture1.AutoRedraw = True
Picture1.ScaleMode = vbPixels
lngDesktopHwnd = GetDesktopWindow
lngDesktopDC = GetDC(lngDesktopHwnd)

Call BitBlt(Picture1.hdc, 0, 0, Screen.Width, Screen.Height, lngDesktopDC, 0, 0, SRCCOPY)
Picture1.Picture = Picture1.Image
Call ReleaseDC(lngDesktopHwnd, lngDesktopDC)
End Sub

Private Sub Command2_Click()
注释:将 Picture1 中的屏幕画面存成 .BMP 档
SavePicture Picture1, "C:\TEST.BMP"
End Sub

在以上的范例中,只要按下 Command1 就会将屏幕的画面截取下来放到 Picture1 中,按下 Command2 之后,就会将 Picture1 中的图片存成文件 ( 文件名称可自行更改 ),如果您想打印,也可以直接使用 PaintPicture 将图片丢到打印机中打出!

至于图片的打印,以后会另有单元介绍。
170、随心所欲地移除表单左上方的系统功能表的某几个项目

针对这个主题,其实以前已经讨论过二次了,只不过不是以这样直接了当的方式点出在题目中而已,不知道大家是否有印象?

这二次分别是:

问题:如何移除 Form 右上方之『X』按钮?

对应到系统功能表的【关闭】选项

问题:如何防止 Form 被移动?

对应到系统功能表的【移动】选项

而我在网路上闲逛时,看到有个外国人用了一个很笨的方法写了一个模组,不过对于不想研究 API 的人来说应该是很好用的模组,可以让您用选择的方式随便您想移除系统功能表的任一个项目!

完整程序码如下,说明加在其中:

注释:在声明区中加入以下声明:

注释:抓取系统 Menu 的 hwnd
Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Integer, ByVal bRevert As Integer) As Integer

注释:移除系统 Menu 的 API
Private Declare Function RemoveMenu Lib "user32" (ByVal hMenu As Integer, ByVal nPosition As Integer, ByVal wFlags As Integer) As Integer
注释:第一个参数是系统 Menu 的 hwnd
注释:第二个参数是要移除选项的 Index

Private Const MF_BYPOSITION = &H400&

注释:模组内容如下:

Private Sub RemoveMenus(frm As Form, remove_restore As Boolean, remove_move As Boolean, remove_size As Boolean, remove_minimize As Boolean, remove_maximize As Boolean, remove_seperator As Boolean, remove_close As Boolean)

Dim hMenu As Long

注释: 抓取系统 Menu 的 hwnd
hMenu = GetSystemMenu(hWnd, False)

If remove_close Then RemoveMenu hMenu, 6, MF_BYPOSITION 注释:是否移除【关闭】选项
If remove_seperator Then RemoveMenu hMenu, 5, MF_BYPOSITION 注释:是否移除【分隔线】
If remove_maximize Then RemoveMenu hMenu, 4, MF_BYPOSITION 注释:是否移除【放到最大】选项
If remove_minimize Then RemoveMenu hMenu, 3, MF_BYPOSITION 注释:是否移除【缩到最小】选项
If remove_size Then RemoveMenu hMenu, 2, MF_BYPOSITION 注释:是否移除【大小】选项
If remove_move Then RemoveMenu hMenu, 1, MF_BYPOSITION 注释:是否移除【移动】选项
If remove_restore Then RemoveMenu hMenu, 0, MF_BYPOSITION 注释:是否移除【还原】选项
End Sub

这个模组共有八个参数,第二个到第八个参数分别对应到系统功能表的七个选项! ( True / False )

今天如果我想做到和问题如何移除 Form 右上方之『X』按钮?一样的结果,表示我要将对应到系统功能表的【关闭】选项移除,则我只要将相对应的参数设成 True 即可,其他要保留的则为 False。

范例如下:

Private Sub Form_Load()
  RemoveMenus Me, False, False, False, False, False, True, True
End Sub