主题:[转帖]VFP经典问题集(中)
[color=000080]本文选自《我整理的一些VFP资料》chm文档,不是从论坛上下载的,所以实在不知道这位作者的姓名,向他的辛勤劳动致以最高的敬意!网络互联,资源共享,共同提高,从我做起。[/color]
<一>:如何让程序自动设定路径?
答:一般运行程序的目录并非固定不变,因此一般在程序启动时
都要查询当前运行程序的目录。下面这段程序给出当前路径的查询
方法:
Function SetPath()
LOCAL lcSys16, lcProgram
lcSys16 = SYS(16) &&查询当前运行程序名
lcProgram = SUBSTR(lcSys16, AT(":", lcSys16) - 1)
CD LEFT(lcProgram, RAT("\", lcProgram))
*-- If we are running MAIN.PRG directly, then
*-- CD up to the parent directory
IF RIGHT(lcProgram, 3) = "FXP"
CD ..
ENDIF
SET PATH TO PROGS, FORMS, LIBS, ;
MENU, DATA, ;
REPORTS, INCLUDE, HELP, ;
BITMAPS
SET CLASSLIB TO MAIN ,vfptool
ENDFUNC
<二>:如何对字符串进行加密、解密?
答:在VFP中,加解密字符串其实有很多种方法,在这里我作了一个函
数,希望对您有所帮助。
本函数功能: 1.加解密字符串。
2.如果有人非法修改密码,将提示非法修改。
入口: * LCZIP --判断是加密还是解密,.T. --加密,.F.解密。
*Lcpass--要加解密的字符串
返回: *加解密后字符串。注意:如果返回的字符串为“ERROR”
*证明密码出错或着密码被非法修改过
FunCtion CalcPassWord
Para Lczip,Lcpass
lCPASS=Allt(Lcpass)
IF LcZip &&加密
Lcpass="DALY"+Lcpass
LCNewPass=CHR(Len(Lcpass))
*处理字符串,使它不为空。因为我要把加密后的字符放到数据库,为防他人直接打开
数据库看出密码为空。
For i=1 To Len(Lcpass)
LCNewPass=LCNewPass+Chr(asc(SubStr(Lcpass,i,1))/32);
+Chr(asc(SubStr(Lcpass,i,1))%32)
EndFor
*取出字符串中的单个字符,并把它转为ASCII码。
*把ASCII码除于32得到的整数跟余数转为字符,再把两个字符和合为一个字符串
*经这种处理后,已经无法得知原来的字符,只有经计算机用反方法解开。
LCNewPass=PADR(LCNewPass,50,CHR(1)) &&返回50个字符长度,不足的用CHR(1)补足。
Else
IF LEN(lCPASS)#50 &&如果长度出错,证明非法修改过
=MESSAGEbOX("密码被非法修改",0,_screen.caption)
Return "ERROR"
ENDIF
For i=1 TO 50
IF asc(SubStr(Lcpass,i,1))>=32 &&检查密码是否被非法修改
=MESSAGEbOX("密码被非法修改",0,_screen.caption)
Return "ERROR"
ENDIF
EndFor
LCNewPass="" &&解密
For I=0 TO (asc(SubStr(Lcpass,1,1))*2)-9
LCNewPass=LCNewPass+Chr(asc(SubStr(Lcpass,i+10,1))*32;
+asc(SubStr(Lcpass,i+11,1)))
i=i+1
EndFor
EndIF
Return LcNewPass
<三>:怎样控制程序的退出?
答:在VFP中当要退出程序时,将会执行Shut 事件,这个事件可以
用On ShutDown 命令设定它的执行程序。默认程序是显示 “不能退
出 VFP”信息框。下面这个函数是询问您是否想退出程序。
**************************************
* Usage: On ShutDown do OnShutDown
*************************************
FUNCTION OnShutdown()
Yes_No = 4
Questionicon=32
DownNO=7
ASSKEY=MESSAGEBOX("您是否要退出这个程序", YES_NO+Questionicon , _screen.caption )
IF Asskey=DownNO
return .F.
Else
&&这里做退出程序的处理
EndIf
ENDFUNC
<四>:在屏幕中央显示提示框?
答:一般在处理数据时,都在屏幕中间显示一个提示正在处理数据
的提示框,Vfp 能否作到了。
当然能,而且很简单,只要您跟着下面的做法,一定能成在处理之前先做
lcMsg = "Processing, Please Wait......."
WAIT WINDOW lcMsg NOCLEAR NOWAIT AT SROW()/2, (SCOLS()-LEN(lcMsg))/2
处理后用Wait clear 清除等待框即可达到效果。
<五>:"&"符号是什么意思,该如何使用?
答:先用下面的例子说明“&”宏替换指令的基本功能
CC="ABC"
M_C="cc"
?&M_C &&显示结果为ABC
根据以上的例子说明“&”宏替换指令是一个取地址的指令。
下面是一些应用“&”宏替换指令的常用命令
a: olddbf = alia() && 贮存当前工作区的数据库名称到变量olddbf
&&其他命令,可能改变当前工作区.......
sele &olddbf &&用“&”宏替换指令把工作区返回原先的工作区
b: Oldfilter =set("filter")
* 贮存当前工作区数据库的过滤条件到变量Oldfilter
set filter to * 去掉当前工作区数据库的过滤条件
set filter to &Oldfilter
* 设定当前工作区数据库的过滤条件到原来的过滤条件
<六>:在运行中,我怎样测试变量是否存在?
答:您可以用 TYPE() 函数来测试变量是否存在,例如
IF TYPE("lMyVariable") # "U"
*变量存在,
ENDIF
您也可以检查 TYPE() = "U" (变量不存在)
<七>:传递给函数的参数是局部参数还是私有参数?
答:所有传递给函数的参数都是局部变量。
<八>:头文件有什么作用,该如何在程序或者表单中使用它?
答:头文件可以用来预先定义一些如公司名称、货币名称等固定不变的常量
在程序中,你可以用命令#include 头文件 来包含头文件。
在表单或者类设计时,你可以用Form/Include或者 Class/Include菜单来包含一个头文件。
如果你用的是Form/Include或者 Class/Include菜单来包含头文件,那么这个表单或者类的所有控件都可以对这个头文件的内容进行存取。如果你是在一个方法里用 #include来包含头文件,那么,只有这个方法可以存取它。
<九>:在运行期间,我如何才能知道文件是否存在?
答:你可以用函数 File("文件名"),如果文件存在,函数返回.T.,否则返回.F.
<十>:我每次启动编译后的VFP程序,VFP的系统菜单总是先出现,我该怎样避免?
答:在您的CONFIG.FPW文件中假如SYSMENU=OFF 的命令。
<十一>:当我的程序启动以后,应该怎样才能把VFP的主屏幕消掉?
答: 1:在您的CONFIG.FPW文件中假如Screen=OFF 的命令。
2:在表单的 Init 事件中,包含下列代码行:Application.Visible = .F.
<十二>:如何播放一个声音文件?
答:您可以利用API 或者ActiveX来调用,也可以用下面的命令来播放:
Set Bell TO "C:\sound.Wav" ,1
??Chr(7)
Set BELL TO
<十三>:我怎样在程序中设定多个处理程序或者类文件的关联?
答:用ADDITIVE 语句,例如
SET Procedure TO Proc.prg ADDITIVE
SET Library To Class.Vcx ADDITIVE
<十四>:如何在VFP的程序中,取得目前已经被用及可用的磁碟机代号?
答:可以利用API--GetLogicalDrives()来完成这项任务。
GetLogicalDrives()会传回一个数值,数值中的每一个BIT其值若为1 ,则表示该磁碟机为已用,其值若为0 ,则表示该磁碟机为可用。
Declare integer GetLogicalDrives in kernel32.dll AS Is_Driver_ready &&定义API函数
nReslut =Is_Driver_Ready()
cUsed_Driver="已经被用的磁碟机代号有:"
cAvail_Driver="可用的磁碟机代号有:"
nMask=1
FOR i=1 To 26 &&因为最多只有26个磁碟代号
IF Bitand(nReslut,nMask)!=0
cUsed_Driver=cUsed_Driver+CHR(64+i)+","
Else
cAvail_Driver=cAvail_Driver+CHR(64+i)+","
ENDIF
nMask=BitLShift(nMask,1)
Next
Wait cUsed_Driver+CHR(13)+cAvail_Driver Window
<十五>:如何得到符合条件的记录数?
答:VFP的Reccount()只能取到数据库全部记录数,但是无法得到过滤后数据的准确记录数。
这里利用Count 写了一个函数,可以对取得过滤后数据的准确记录数。
调用方式: Recordcount("表名") &&对表名进行记数
Recordcount() &&对当前表进行记数
Func Recordcount &&Edit By daly
para Ntable
Olddbf = alia()
IF !empty(ntable)
sele &ntable
Endif
count &&计算数目
IF !empty(olddbf)
sele &olddbf
Else
Sele 0
EndIF
return _tally &&_tally 是Count处理数
<十六>:如何用按键中断循环运行中的程序?
答:可以利用chrsaw() 和 inkey()来抓取键盘缓冲区的键值来达到目的
例如: 本函数用CTRL+C 来中断程序。
function chkbreak &&Edit By daly
para b_msg &&传入中断提示信息
if chrsaw() &&设定等待时间
t0=inkey() &&等待按键
clear typeahead &&清除键盘缓冲区
if t0=3 OR t0=17
if messagebox(b_msg,36,"信息提示")=6
RETURN .f.
endif
endif
endif
return .t.
<一>:如何让程序自动设定路径?
答:一般运行程序的目录并非固定不变,因此一般在程序启动时
都要查询当前运行程序的目录。下面这段程序给出当前路径的查询
方法:
Function SetPath()
LOCAL lcSys16, lcProgram
lcSys16 = SYS(16) &&查询当前运行程序名
lcProgram = SUBSTR(lcSys16, AT(":", lcSys16) - 1)
CD LEFT(lcProgram, RAT("\", lcProgram))
*-- If we are running MAIN.PRG directly, then
*-- CD up to the parent directory
IF RIGHT(lcProgram, 3) = "FXP"
CD ..
ENDIF
SET PATH TO PROGS, FORMS, LIBS, ;
MENU, DATA, ;
REPORTS, INCLUDE, HELP, ;
BITMAPS
SET CLASSLIB TO MAIN ,vfptool
ENDFUNC
<二>:如何对字符串进行加密、解密?
答:在VFP中,加解密字符串其实有很多种方法,在这里我作了一个函
数,希望对您有所帮助。
本函数功能: 1.加解密字符串。
2.如果有人非法修改密码,将提示非法修改。
入口: * LCZIP --判断是加密还是解密,.T. --加密,.F.解密。
*Lcpass--要加解密的字符串
返回: *加解密后字符串。注意:如果返回的字符串为“ERROR”
*证明密码出错或着密码被非法修改过
FunCtion CalcPassWord
Para Lczip,Lcpass
lCPASS=Allt(Lcpass)
IF LcZip &&加密
Lcpass="DALY"+Lcpass
LCNewPass=CHR(Len(Lcpass))
*处理字符串,使它不为空。因为我要把加密后的字符放到数据库,为防他人直接打开
数据库看出密码为空。
For i=1 To Len(Lcpass)
LCNewPass=LCNewPass+Chr(asc(SubStr(Lcpass,i,1))/32);
+Chr(asc(SubStr(Lcpass,i,1))%32)
EndFor
*取出字符串中的单个字符,并把它转为ASCII码。
*把ASCII码除于32得到的整数跟余数转为字符,再把两个字符和合为一个字符串
*经这种处理后,已经无法得知原来的字符,只有经计算机用反方法解开。
LCNewPass=PADR(LCNewPass,50,CHR(1)) &&返回50个字符长度,不足的用CHR(1)补足。
Else
IF LEN(lCPASS)#50 &&如果长度出错,证明非法修改过
=MESSAGEbOX("密码被非法修改",0,_screen.caption)
Return "ERROR"
ENDIF
For i=1 TO 50
IF asc(SubStr(Lcpass,i,1))>=32 &&检查密码是否被非法修改
=MESSAGEbOX("密码被非法修改",0,_screen.caption)
Return "ERROR"
ENDIF
EndFor
LCNewPass="" &&解密
For I=0 TO (asc(SubStr(Lcpass,1,1))*2)-9
LCNewPass=LCNewPass+Chr(asc(SubStr(Lcpass,i+10,1))*32;
+asc(SubStr(Lcpass,i+11,1)))
i=i+1
EndFor
EndIF
Return LcNewPass
<三>:怎样控制程序的退出?
答:在VFP中当要退出程序时,将会执行Shut 事件,这个事件可以
用On ShutDown 命令设定它的执行程序。默认程序是显示 “不能退
出 VFP”信息框。下面这个函数是询问您是否想退出程序。
**************************************
* Usage: On ShutDown do OnShutDown
*************************************
FUNCTION OnShutdown()
Yes_No = 4
Questionicon=32
DownNO=7
ASSKEY=MESSAGEBOX("您是否要退出这个程序", YES_NO+Questionicon , _screen.caption )
IF Asskey=DownNO
return .F.
Else
&&这里做退出程序的处理
EndIf
ENDFUNC
<四>:在屏幕中央显示提示框?
答:一般在处理数据时,都在屏幕中间显示一个提示正在处理数据
的提示框,Vfp 能否作到了。
当然能,而且很简单,只要您跟着下面的做法,一定能成在处理之前先做
lcMsg = "Processing, Please Wait......."
WAIT WINDOW lcMsg NOCLEAR NOWAIT AT SROW()/2, (SCOLS()-LEN(lcMsg))/2
处理后用Wait clear 清除等待框即可达到效果。
<五>:"&"符号是什么意思,该如何使用?
答:先用下面的例子说明“&”宏替换指令的基本功能
CC="ABC"
M_C="cc"
?&M_C &&显示结果为ABC
根据以上的例子说明“&”宏替换指令是一个取地址的指令。
下面是一些应用“&”宏替换指令的常用命令
a: olddbf = alia() && 贮存当前工作区的数据库名称到变量olddbf
&&其他命令,可能改变当前工作区.......
sele &olddbf &&用“&”宏替换指令把工作区返回原先的工作区
b: Oldfilter =set("filter")
* 贮存当前工作区数据库的过滤条件到变量Oldfilter
set filter to * 去掉当前工作区数据库的过滤条件
set filter to &Oldfilter
* 设定当前工作区数据库的过滤条件到原来的过滤条件
<六>:在运行中,我怎样测试变量是否存在?
答:您可以用 TYPE() 函数来测试变量是否存在,例如
IF TYPE("lMyVariable") # "U"
*变量存在,
ENDIF
您也可以检查 TYPE() = "U" (变量不存在)
<七>:传递给函数的参数是局部参数还是私有参数?
答:所有传递给函数的参数都是局部变量。
<八>:头文件有什么作用,该如何在程序或者表单中使用它?
答:头文件可以用来预先定义一些如公司名称、货币名称等固定不变的常量
在程序中,你可以用命令#include 头文件 来包含头文件。
在表单或者类设计时,你可以用Form/Include或者 Class/Include菜单来包含一个头文件。
如果你用的是Form/Include或者 Class/Include菜单来包含头文件,那么这个表单或者类的所有控件都可以对这个头文件的内容进行存取。如果你是在一个方法里用 #include来包含头文件,那么,只有这个方法可以存取它。
<九>:在运行期间,我如何才能知道文件是否存在?
答:你可以用函数 File("文件名"),如果文件存在,函数返回.T.,否则返回.F.
<十>:我每次启动编译后的VFP程序,VFP的系统菜单总是先出现,我该怎样避免?
答:在您的CONFIG.FPW文件中假如SYSMENU=OFF 的命令。
<十一>:当我的程序启动以后,应该怎样才能把VFP的主屏幕消掉?
答: 1:在您的CONFIG.FPW文件中假如Screen=OFF 的命令。
2:在表单的 Init 事件中,包含下列代码行:Application.Visible = .F.
<十二>:如何播放一个声音文件?
答:您可以利用API 或者ActiveX来调用,也可以用下面的命令来播放:
Set Bell TO "C:\sound.Wav" ,1
??Chr(7)
Set BELL TO
<十三>:我怎样在程序中设定多个处理程序或者类文件的关联?
答:用ADDITIVE 语句,例如
SET Procedure TO Proc.prg ADDITIVE
SET Library To Class.Vcx ADDITIVE
<十四>:如何在VFP的程序中,取得目前已经被用及可用的磁碟机代号?
答:可以利用API--GetLogicalDrives()来完成这项任务。
GetLogicalDrives()会传回一个数值,数值中的每一个BIT其值若为1 ,则表示该磁碟机为已用,其值若为0 ,则表示该磁碟机为可用。
Declare integer GetLogicalDrives in kernel32.dll AS Is_Driver_ready &&定义API函数
nReslut =Is_Driver_Ready()
cUsed_Driver="已经被用的磁碟机代号有:"
cAvail_Driver="可用的磁碟机代号有:"
nMask=1
FOR i=1 To 26 &&因为最多只有26个磁碟代号
IF Bitand(nReslut,nMask)!=0
cUsed_Driver=cUsed_Driver+CHR(64+i)+","
Else
cAvail_Driver=cAvail_Driver+CHR(64+i)+","
ENDIF
nMask=BitLShift(nMask,1)
Next
Wait cUsed_Driver+CHR(13)+cAvail_Driver Window
<十五>:如何得到符合条件的记录数?
答:VFP的Reccount()只能取到数据库全部记录数,但是无法得到过滤后数据的准确记录数。
这里利用Count 写了一个函数,可以对取得过滤后数据的准确记录数。
调用方式: Recordcount("表名") &&对表名进行记数
Recordcount() &&对当前表进行记数
Func Recordcount &&Edit By daly
para Ntable
Olddbf = alia()
IF !empty(ntable)
sele &ntable
Endif
count &&计算数目
IF !empty(olddbf)
sele &olddbf
Else
Sele 0
EndIF
return _tally &&_tally 是Count处理数
<十六>:如何用按键中断循环运行中的程序?
答:可以利用chrsaw() 和 inkey()来抓取键盘缓冲区的键值来达到目的
例如: 本函数用CTRL+C 来中断程序。
function chkbreak &&Edit By daly
para b_msg &&传入中断提示信息
if chrsaw() &&设定等待时间
t0=inkey() &&等待按键
clear typeahead &&清除键盘缓冲区
if t0=3 OR t0=17
if messagebox(b_msg,36,"信息提示")=6
RETURN .f.
endif
endif
endif
return .t.