2005年04月07日

语句
……
%>
<2>定义变量dim语句
<%
dim a,b
a=10
b=”ok!”
%>
注意:定义的变量可以是数值型,也可以是字符或者其他类型的
<3>简单的控制流程语句
1. If 条件1 then
语句1
elseif 条件2 then
语句2
else
语句3
endif
2.while 条件
语句
wend
3.for count=1 to n step m
语句1
exit for
语句2
next
二.ASP数据库简单*作教程
<1>.数据库连接(用来单独编制连接文件conn.asp)
<%
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" & Server.MapPath("\bbs\db1\user.mdb")
%>
(用来连接bbs\db1\目录下的user.mdb数据库)
<2>显示数据库记录
原理:将数据库中的记录一一显示到客户端浏览器,依次读出数据库中的每一条记录
如果是从头到尾:用循环并判断指针是否到末 使用: not rs.eof
如果是从尾到头:用循环并判断指针是否到开始 使用:not rs.bof

<!–#include file=conn.asp–> (包含conn.asp用来打开bbs\db1\目录下的user.mdb数据库)
<%
set rs=server.CreateObject("adodb.recordset") (建立recordset对象)
sqlstr="select * from message" —->(message为数据库中的一个数据表,即你要显示的数据所存放的数据表)
rs.open sqlstr,conn,1,3 —->(表示打开数据库的方式)
rs.movefirst —->(将指针移到第一条记录)
while not rs.eof —->(判断指针是否到末尾)
response.write(rs("name")) —->(显示数据表message中的name字段)
rs.movenext —->(将指针移动到下一条记录)
wend —->(循环结束)
——————————————————
rs.close
conn.close 这几句是用来关闭数据库
set rs=nothing
set conn=nothing
——————————————————-
%>
其中response对象是服务器向客户端浏览器发送的信息
<3>增加数据库记录
增加数据库记录用到rs.addnew,rs.update两个函数
<!–#include file=conn.asp–> (包含conn.asp用来打开bbs\db1\目录下的user.mdb数据库)
<%
set rs=server.CreateObject("adodb.recordset") (建立recordset对象)
sqlstr="select * from message" —->(message为数据库中的一个数据表,即你要显示的数据所存放的数据表)
rs.open sqlstr,conn,1,3 —->(表示打开数据库的方式)
rs.addnew 新增加一条记录
rs("name")="xx" 将xx的值传给name字段
rs.update 刷新数据库
——————————————————
rs.close
conn.close 这几句是用来关闭数据库
set rs=nothing
set conn=nothing
——————————————————-

%>
<4>删除一条记录
删除数据库记录主要用到rs.delete,rs.update
<!–#include file=conn.asp–> (包含conn.asp用来打开bbs\db1\目录下的user.mdb数据库)
<%
dim name
name="xx"
set rs=server.CreateObject("adodb.recordset") (建立recordset对象)
sqlstr="select * from message" —->(message为数据库中的一个数据表,即你要显示的数据所存放的数据表)
rs.open sqlstr,conn,1,3 —->(表示打开数据库的方式)
——————————————————-
while not rs.eof
if rs.("name")=name then
rs.delete
rs.update 查询数据表中的name字段的值是否等于变量name的值"xx",如果符合就执行删除,
else 否则继续查询,直到指针到末尾为止
rs.movenext
emd if
wend
——————————————————
——————————————————
rs.close
conn.close 这几句是用来关闭数据库
set rs=nothing
set conn=nothing
——————————————————-
%>
<5>关于数据库的查询
(a) 查询字段为字符型
<%
dim user,pass,qq,mail,message
user=request.Form("user")
pass=request.Form("pass")
qq=request.Form("qq")
mail=request.Form("mail")
message=request.Form("message")
if trim(user)&"x"="x" or trim(pass)&"x"="x" then (检测user值和pass值是否为空,可以检测到空格)
response.write("注册信息不能为空")
else
set rs=server.CreateObject("adodb.recordset")
sqlstr="select * from user where user=’"&user&"’" (查询user数据表中的user字段其中user字段为字符型)
rs.open sqlstr,conn,1,3
if rs.eof then
rs.addnew
rs("user")=user
rs("pass")=pass
rs("qq")=qq
rs("mail")=mail
rs("message")=message
rs.update
rs.close
conn.close
set rs=nothing
set conn=nothing
response.write("注册成功")
end if
rs.close
conn.close
set rs=nothing
set conn=nothing
response.write("注册重名")
%>
(b)查询字段为数字型
<%
dim num
num=request.Form("num")
set rs=server.CreateObject("adodb.recordset")
sqlstr="select * from message where id="&num (查询message数据表中id字段的值是否与num相等,其中id为数字型)
rs.open sqlstr,conn,1,3
if not rs.eof then
rs.delete
rs.update
rs.close
conn.close
set rs=nothing
set conn=nothing
response.write("删除成功")
end if
rs.close
conn.close
set rs=nothing
set conn=nothing
response.write("删除失败")
%>
<6>几个简单的asp对象的讲解
response对象:服务器端向客户端发送的信息对象,包括直接发送信息给浏览器,重新定向URL,或设置cookie值
request对象:客户端向服务器提出的请求
session对象:作为一个全局变量,在整个站点都生效
server对象:提供对服务器上方法和属性的访问
(a) response对象的一般使用方法
比如:
<%
resposne.write("hello, welcome to asp!")
%>
在客户端浏览器就会看到 hello, welcome to asp! 这一段文字
<%
response.Redirect("www.sohu.com")
%>
如果执行这一段,则浏览器就会自动连接到 “搜狐” 的网址
关于response对象的用法还有很多,大家可以研究研究
request对象的一般使用方法
比如客户端向服务器提出的请求就是通过request对象来传递的
列如 :你在申请邮箱的所填写的个人信息就是通过该对象来将
你所填写的信息传递给服务器的
比如:这是一段表单的代码,这是提供给客户填写信息的,填写完了按
“提交”传递给request.asp文件处理后再存入服务器数据库
<form name="form1" method="post" action="request.asp">
<p>
<input type="text" name="user">
</p>
<p>
<input type="text" name="pass">
</p>
<p>
<input type="submit" name="Submit" value="提交">
</p>
</form>
那么request.asp该如何将其中的信息读入,在写入数据库,在这里就要用到
request对象了,下面我们就来分析request.asp的写法
<%
dim name,password (定义user和password两个变量)
name=request.form(“user”) (将表单中的user信息传给变量name)
password=request.form(“pass”) (将表单中的pass信息传给变量password)
%>
通过以上的几句代码我们就将表单中的数据读进来了,接下来我们要做的就是将
信息写入数据库了,写入数据库的方法上面都介绍了,这里就不一一复述了。

DATE
一个日期。支持的范围是 '1000-01-01''9999-12-31'。MySQL 以 'YYYY-MM-DD' 格式显示 DATE 值,但是允许你以字符串或数字给一个 DATE 列赋值。查看章节 6.2.2.2 DATETIMEDATETIMESTAMP 类型
DATETIME
一个日期和时间的组合。支持的范围是 '1000-01-01 00:00:00''9999-12-31 23:59:59'。MySQL 以'YYYY-MM-DD HH:MM:SS' 格式显示 DATETIME 值,但是允许你以字符串或数字给一个 DATETIME 列赋值。查看章节 6.2.2.2 DATETIMEDATETIMESTAMP 类型
TIMESTAMP[(M)]
一个时间戳。范围是 '1970-01-01 00:00:00'2037 年间的任意时刻。 MySQL 4.0 和更早版本中,TIMESTAMP 值是以 YYYYMMDDHHMMSSYYMMDDHHMMSSYYYYMMDDYYMMDD 格式显示的,它取决于 M 是否是 14 (或省略)、1286,但是允许你以字符串或数字给一个 TIMESTAMP 列赋值。 从 MySQL 4.1 开始,TIMESTAMP'YYYY-MM-DD HH:MM:DD' 格式作为字符返回。如果你你希望以数字形式返回则必须在该时间戳字段后加上 +0。不同的时间戳长度是不支持的。从 MySQL 4.0.12 开始,选项 --new 可以被用来使服务器与 4.1 一样运作。 TIMESTAMP 列有益于记录一个 INSERTUPDATE 操作的日期和时间,因为如果你自己没有给它赋值,它将被自动地设置为最近一次操作的日期和时间。也可以通过给它赋一个 NULL 而使它设置为当前的日期和时间。查看章节 6.2.2 Date 和 Time 类型。 参数 M 只影响一个 TIMESTAMP 列的显示格式;它的值总是占用 4 个字节存储。 注意,当 TIMESTAMP(M) 列的 M 是 8 或 14 时,它返回的是数字而其它的 TIMESTAMP(M) 列返回的是字符串。这仅仅是为了可以可靠地转储并恢复到其它格式的表中。查看章节 6.2.2.2 DATETIMEDATETIMESTAMP 类型
TIME
一个时间。范围是 '-838:59:59''838:59:59'。MySQL 以 'HH:MM:SS' 格式显示 TIME 值,但是允许你使用字符串或数字来给 TIME 列赋值。查看章节 6.2.2.3 TIME 类型
YEAR[(2|4)]
一个 2 或 4 位数字格式的年(缺省为 4 位)。允许的值是 190121550000(4 位年格式) 以及使用 2 位格式的 1970-2069 (70-69)。MySQL 以 YYYY 格式显示 YEAR 值,但是允许你使用字符串或数字来给 YEAR 列赋值。(YEAR 类型在 MySQL 3.22 之前不支持。) 查看章节 6.2.2.4 YEAR 类型
2005年03月26日

如何提高VFP应用软件的路径适应性
在使用各种商品化的应用软件时,发现部分软件,可以将它安装在硬盘的任何盘的任何目录中;而有的软件,则只能安装在设计者事先规定的特定盘和特定路径中。假如将它放在了另外的盘号和路径,就会出现”XXXX数据库找不到”等等之类错误,从而中断软件的运行。本文从VFP语言的编程特点出发,介绍了提高VFP应用程序路径适应性的具体实现方法。
1. 在VFP应用软件的项目中,有一个主文件,它是整个应用程序的运行起始点。在主文件的开头处,插入以下语句:
A.将该软件的目录(安装后目录),设置为当前目录
SET DEFAULT TO SYS(5)+SYS(2003)

B.从.INI文件或路径数据表中读取用户指定的该软件下的子目录名(.INI文件或路径数据表的内容,待软件安装后,根据软件下的子目录名,由用户输入),例如B.1。若软件设计时确定了子目录名,则执行B.2的语句。
B.1 这里以”路径数据表”为例,说明读取路径的过程。
USE PGPATH
MPATH=‘‘
LOCA FOR PH#‘ ‘ &&搜索字段PH(路径)不为空的记录
DO WHILE .NOT.EOF()
MPATH=MPATH+TRIM(PH)+‘,‘ &&连加成搜索路径
SKIP
ENDD
MPATH=LEFT(MPATH,1,LEN(MPATH)-1)

B.1 若子目录名固定,则将各子目录名赋给MPATH,例: 两个子目录名为
DATA1,DATA2,DATA3则:
MPATH=‘DATA1,DATA2,DATA3‘

C.设置搜索路径
SET PATH &MPATH.
D.打开各数据库
OPEN DATABASE 数据库1
OPEN DATABASE 数据库2

2. 在主程序文件以外的程序中,作如下处理:
在这些程序中,以上设定的搜索路径仅由项目内的自由表使用,打开自由表时,不要使用路径。对于只包含单个数据库的项目,数据库中的表、视图等可以通过以下语句来使用,无须再使用路径。
OPEN DATABASE [数据库名]
USE [表名]
而对于包含多个数据库的项目,在使用其内的表、视图等对象时,采用:
USE 数据库名!表名


3. 若要求应用程序在用户指定的目录中新建文件,则可以通过以下VFP函数来实现:
=PUTFILE([cCustomText] [, cFileName] [, cFileExtensions])
运行此函数,出现一个对话框,让用户选择文件(cFileName).( cFileExtensions)的存放目录。

4. 对VFP数据环境的分析。
报表、表单等设计时,数据环境内各个对象(如表、自由表、视图等)的CursorSource属性中包含自由表的绝对路径,以及Database属性中包含数据库的绝对路径。并且这二个属性都是只读的,无法修改。然而,在编程实践中发现,这二个属性值在项目连编时,都转化为相对于项目文件所在位置的相对路径。从而为设计路径通用性程序成为可能。这一点可通过查看使用了数据环境的各类文件(如:表单的 *、SCT,报表的 *、FRT)来证明,因此,在设计数据环境时,对数据对象,无须考虑路径的相对性。而且,数据环境中的数据库也是按SET PATH设定的顺序查找的。
5. 项目文件中的数据库
首先,要将它们标为”排除”。笔者,在项目”连编”前,有意改变它的数据库目
录,使”项目连编”时找不到数据库,当出现”找不到数据库”等错误信息时,选择 “忽
略”,连编后的应用程序,照样可使用。因此,连编后的应用程序中,不固定项目内(已
标为”排除”的)数据库的路径,也不必考虑路径问题。
6.最后要注意,在打开项目的环境下,调试运行主文件(整个应用程序的运行起始点)
时要将 SET DEFAULT TO SYS(5)+SYS(2003) 改为
SET DEFAULT TO [(设计环境中)连编后的应用程序存放的绝对路径]
因为设计项目时 SYS(5)+SYS(2003)得出的不一定是[连编后的应用程序存放的
绝对路径],如:设计项目时是先运行VFP系统,再打开项目文件,则得出的路径是
VFP系统的安装目录。

如何使用_Screen对象

VisualFoxPro中充分利用_SCREEN对象,就能对主窗口进行各种操作,如可以动态地改变主窗口的图标、标题、颜色等,也可以通过它引用其它的对象或属性。
   _SCREEN对象(即指主窗口)是从表单类派生出来的,表单中的部分属性、事件和方法在_SCREEN对象也存在,因而可以把主窗口当作表单来操作(但也有所不同,如在_SCREEN中不能像表单那样对LOADACTIVATE等事件添加代码,即不能够为_screen指定事件)
   下面举例说明如何利用_SCREEN对象:
  1.更改图标和标题
   VFP窗口的小狐狸图标和“MicrosoftVisualFoxPro”标题,改为你所喜欢的图标和标题,只需执行代码
   _SCREEN.ICON=″你的图标文件名(.ICO)″
   _SCREEN.CAPTION=″你的标题名

如果需要修改的东西很多,大家也可以用with…endeith进行设定,如:

with _screen
.visible=.t.
.closable=.t.
.controlbox=.t.
.maxbutton=.t.
.minbutton=.t.
.movable=.t.
.top=0
.left=0
.windowstate=2
.caption=’
建设银行计算机台帐管理系统
.picture=’zhj6.bmp’
.icon=’support.ico’
endwith
  2.动态地改变主窗口的图标和标题

   即让主窗口的图标和标题随时间的变化而变化。这就需要在_SCREEN中加入一个Timer类,Timer类是每经过一定的时间(Interval属性中设定,单位为毫秒)循环地执行其Timer事件中的代码。方法如下:先定义你的Timer类:点文件/新建//新建文件,这时弹出一窗口,上面有这几项需要填写:类名项填新建类名(如MyTimer),派生于项选Timer来源于项不用填,存储于项填新建类库名(如MyClass)。确定后出现类设计器(很像表单设计器),上有一小闹钟(Timer控件)把其Interval属性设为1000(时间间隔,毫秒),在Init事件中输入代码:
   PUBL NN
   NN=0&&NN为变化的标志变量

   Timer事件(每隔一定时间执行)输入:
   _SCREEN.ICON=IIF((1)^NN,″所需加入的图题1″图标2″)
   _SCREEN.CAPION=IIF((1)^NN,″所需加入的标题1″标题
2″)
   NN=NN
1
   关闭并保存,类建立完毕。

   可视地把该类添到_SCREEN中:由于_SCREEN与表单有所区别,故不能用表单设计器工具来完成拖放类定义,而是用类浏览器来完成,寻工具/类浏览器后,弹出一打开窗口,选择刚才建立的类库文件(MYCLASS),确定后,弹出类浏览器窗口,选中MyTimer类,这时在类浏览器的左上角有一小闹钟,把它拖放到主窗口中,你就会惊奇地发现你的主窗口不再是死气沉沉的了。不信?试试!
  3.利用_SCREEN得到主窗口内包含的表单数量
   执行:?_SCREEN.FORMCOUNT即可
4.
_screen中加入对象(如:图画),举例如下:
_screen.addobject(“imge1″,”quit1″) &&
建立一副图画
define class quit1 as image
top=-10
left=0
*height=_screen.height-50
*width=_screen.width-50
picture=’main_bmp.bmp’
backstyle=0
visible=.t.
* stretch=1

procedure click
quit
endproc 
enddefine
基于这个例子,上面第2个问题中加入timer类的问题可以这样解决:
_screen.addobject(“tmr1″,”caption1″) &&
建立一个timer
define class caption1 as timer1
Interval=1000
procedure init
PUBL NN
    NN=0&&NN为变化的标志变量

endproc

procedure timer
_SCREEN.ICON=IIF((
1)^NN,″所需加入的图题1″图标2″)
   _SCREEN.CAPION=IIF((1)^NN,″所需加入的标题1″标题
2″)
   NN=NN
1
endproc

enddefine
以上是有关_SCREEN对象的简单阐述,想要你的窗口美化起来,具体的工作还需要你自己去做。

在VisualFoxPro中充分利用_SCREEN对象,就能对主窗口进行各种操作,如可以动态地改变主窗口的图标、标题、颜色等,也可以通过它引用其它的对象或属性。
_SCREEN对象(即指主窗口)是从表单类派生出来的,表单中的部分属性、事件和方法在_SCREEN对象也存在,因而可以把主窗口当作表单来操作(但也有所不同,如在_SCREEN中不能像表单那样对LOAD、ACTIVATE等事件添加代码)。
下面举例说明如何利用_SCREEN对象:

1更改图标和标题
把VFP窗口的小狐狸图标和“MicrosoftVisualFoxPro”标题,改为你所喜欢的图标和标题,只需执行代码 _SCREEN.ICON=″你的图标文件名(.ICO)″
_SCREEN.CAPTION=″你的标题名″

2动态地改变主窗口的图标和标题
即让主窗口的图标和标题随时间的变化而变化。这就需要在_SCREEN中加入一个Timer类,Timer类是每经过一定的时间(在Interval属性中设定,单位为毫秒)循环地执行其Timer事件中的代码。
方法如下:先定义你的Timer类:点“文件/新建/类/新建文件”,这时弹出一窗口,上面有这几项需要填写:“类名”项填新建类名(如MyTimer),“派生于”项选Timer,“来源于”项不用填,“存储于”项填新建类库名(如MyClass)。确定后出现类设计器(很像表单设计器),上有一小闹钟(Timer控件)把其Interval属性设为1000(时间间隔,毫秒),在Init事件中输入代码:
PUBL NN
NN=0&&NN为变化的标志变量
在Timer事件(每隔一定时间执行)输入:
_SCREEN.ICON=IIF((-1)^NN,″所需加入的图题1″,″图标2″)
_SCREEN.CAPION=IIF((-1)^NN,″所需加入的标题1″,″标题2″)
NN=NN+1
关闭并保存,类建立完毕。
可视地把该类添到_SCREEN中:由于_SCREEN与表单有所区别,故不能用表单设计器工具来完成拖放类定义,而是用“类浏览器”来完成,寻工具/类浏览器”后,弹出一打开窗口,选择刚才建立的类库文件(MYCLASS),确定后,弹出类浏览器窗口,选中MyTimer类,这时在类浏览器的左上角有一小闹钟,把它拖放到主窗口中,你就会惊奇地发现你的主窗口不再是死气沉沉的了。

3利用_SCREEN得到主窗口内包含的表单数量
执行:?_SCREEN.FORMCOUNT即可

4利用_SCREEN得到打开的表单名
可执行:?_SCREEN.FORMS(1).NAME&&FORM(1)为数组

如何从表单返回一个值
可以在表单的Unload事件中用来RETURN命令返回一个值。

如何检查变量是否存在
使用TYPE()函数来检查一个变量是否存在。
IF TYPE(“Var”) = .t.
    MESSAGEBOX(“It exists”,0,”")?
ENDIF
或你可以检查是否TYPE(“Var”)=”U”,若是,则变量不存在。

如何把数组作为参数传递给表单
在FoxPro中,数组必须按址传递。SET UDFPARMS决定参数的传递方式。在默认情况下,当你用DO…WITH调用过程或表单时,参数是按址传递。在函数或方法中,参数是按值传递。
DIMENSION array[10]
DO FORM Form1 WITH array
在这种情况下,你必须用一个”@”符号强迫参数的传递为按址传递。
DIMENSION array[10]
MyForm = CREATEOBJECT(“Form1″, @myarray)

为什么退出VFP时提示“不能退出VFP”
使用ON SHUTDOWN命令。

如何同时设置多个对象的同一属性
用SetAll方法。例如,你决定为全部网格中的标题设置9号宋体。将以下代码放入网格的Init事件:
THIS.SETALL(“FontName”,”Arial”,”Header”)

Wait命令的应用
Wait命令应用很方便,我在VB,DELPHI等语言中就始终没有找到与其功能 相似的语句,
可是我们在VFP中使用时常常只是用到了它的部分功能,而忽略了 一些很有用的功能。 Wait
命令也有不少子句:
WAIT
  [cMessageText]
   [TO MemVarName]
   [WINDOW [AT nRow, nColumn]]
   [NOWAIT]
   [CLEAR | NOCLEAR]
   [TIMEOUT nSeconds]
比如我们的使用常常只是:
WAIT WIND ‘暂停…’
使’暂停…’这两个字停留在其默认窗口的右上角,其实完全可以用 [AT nRow, nColumn]来改
变其停留位置:
WAIT WIND ‘暂停…’ AT 10,30
使’暂停…’停留在指定的第10行,第30列上。
WAIT WIND ‘暂停…’ +CHR(13)+’另起一行…’ AT 10,30
在提示信息中加上CHR(13),提示信息可分行显示。 而:
WAIT WIND ‘暂停10秒…’ TIMEOUT 10
则可在无击键和鼠标移动的情况下只暂停10秒。




如何制作WINDOWS格式的更改日期的程序
制作一个WIN9X格式的日期设置程序对于你自己的软件,除能够起到美化程序界面,而且能够提高程序的易用性,主要步骤如下:
1、首先建立一个表单,在表单的INIT事件中要首先设置一个判断星期的循环程序。
2、在表单中加入年微调控件,编写该控件的InteractiveChange事件过程,主要是编写当年变动的时候,要刷新月中每天的星期。
3、加入月下拉选项框,进行月份选择,同样要编写该控件的InteractiveChange事件过程,主要是编写当月变动的时候,要刷新月中每天的星期。
4、加入Grid控件,以选择日期。
实例文件下载

如何将金额由小写变为大写
1、编写如下函数。该函数的返回值能够舍去数字之间的零,比较准确,符合会计准则,比较适合打印银行存单等。
PARAMETERS nAmount
PRIVATE ALL LIKE L_*
L_S1=’零壹贰叁肆伍陆柒捌玖’
L_S2=’亿仟佰拾万仟佰拾亿仟佰拾万仟佰拾元角分’
nAmount=LTRIM(STR(nAmount*100,LEN(L_S2)/2))
L_LEN=LEN(nAmount)
L_SS2=RIGH(L_S2,2*L_LEN)
L_DX=”
L_0JS=0 &&连续零的个数
L_N=0
DO WHILE L_N<L_LEN
    L_N=L_N+1
    L_SZ=SUBSTR(nAmount,L_N,1)
    L_SZ=SUBSTR(L_S1,2*VAL(L_SZ)+1,2)
    L_DW=SUBSTR(L_SS2,2*L_N-1,2)
    IF L_SZ=’零’
        L_SZ=”
        DO CASE
            CASE L_DW$’亿元’
            CASE L_DW=’万’
                IF RIGH(L_DX,2)=’亿’
                    L_DW=”
                ENDIF
            OTHERWISE
                L_DW=”
        ENDCASE
        L_0JS=L_0JS+1
    ELSE
        IF L_0JS>0
            L_SZ=’零’+L_SZ
        ENDIF
        L_0JS=0
    ENDIF
    L_DX=L_DX+L_SZ+L_DW
ENDDO
L_DX=L_DX+IIF(RIGH(nAmount,1)=’0′,’整’,”)
RETURN L_DX

2、编写如下函数。该函数的返回值比较适合于一些单据的填空式打印,如增值税发票等。
PARAMETERS nAmount,IsDW
nDZS=STRTRAN(ALLTRIM(STR(nAmount,18,2)),”.”,”") &&把小数点去掉
cHZDX=”零壹贰叁肆伍陆柒捌玖”
cDW=”分角元拾佰仟万拾佰仟亿拾佰仟万拾佰仟亿”
cRMBDX=”"
nCd=LEN(nDZS)
FOR i=1 TO LEN(nDZS)
    cNumbers=SUBSTRC(cHZDX,INT(VAL(SUBSTR(nDZS,I,1))+1),1) && 数字转换
    IF IsDW=1 &&如果要单位
        cDWs=SUBSTRC(cDW,nCd,1)
    ELSE
        cDWs=SPACE(0) &&不要单位的情况下
    ENDIF
    cRMBDX=cRMBDX+cNumbers+cDWS
    nCd=nCd-1
ENDFOR
RETURN cRMBDX

2005年03月25日

实现组合框的记忆选择

在编制管理系统时,往往一个相同的系统要由好几个部门使用,这样,在进入系统时,就要选择不同部门的名称。作为一个使用者,我们希望选择第一次,以后每次进入就不用再选择。以下方法将实现此功能。

  新建一个表单,在上面创建一个“组合框”对象,对表单做如下设置:

  init event:

  set safety off

  public z

  if .not.file(′mv.mem′)

  z=1

  else

  restore from mv additive

  endif

  thisform.combo1.additem(“第一个单位”)

  …

  thisform.combo1.additem(“第二个单位”)

  thisform.combo1.listindex=z

  destroy event:

  z=thisform.combo1.listindex

  save to mv all like z

vfp中将表单的内容直接打印
*******************************************
*– 程序名称:将表单的内容直接打印 –*
*– 将窗口中的内容以一个位图的形式打印 –*
*– 程序作者:未知,来源论坛转帖 –*
*– 使用方法:在表单中执行该程序既可 –*
* 例:在某表单的一个command –*
* 按纽中执行 do printform.prg –*
*******************************************
*– 定义常量
#define logpixelsx 88
#define logpixelsy 90
#define physicaloffsetx 112
#define physicaloffsety 113
#define srccopy 13369376
#define dib_rgb_colors 0

*– 调用本程序段中的子过程
do decl

*– 定义变量
private pnwidth, pnheight, lnbitsperpixel, lnbytesperscan
store 0 to pnwidth, pnheight, lnbitsperpixel, lnbytesperscan
local hwnd, hformdc, hprndc, hmemdc, hmembmp, hsavedbitmap,;
xoffsprn, yoffsprn, xscale, yscale, lcdocinfo, lcbinfo, lpbitsarray

*– 得到打印机设备的坐标偏移量
hprndc = getdefaultprndc() && 没有进行错误检查
xoffsprn = getdevicecaps(hprndc, physicaloffsetx)
yoffsprn = getdevicecaps(hprndc, physicaloffsety)

*– 得到屏幕的窗口句柄,及她们的宽度、高度等。
hwnd = getfocus() && a window with keyboard focus
hformdc = getwindowdc(hwnd)
= getwinrect (hwnd, @pnwidth, @pnheight)

*– 根据屏幕和打印机得到缩放值
xscale = getdevicecaps(hprndc, logpixelsx)/getdevicecaps(hformdc,logpixelsx)
yscale = getdevicecaps(hprndc, logpixelsy)/getdevicecaps(hformdc,logpixelsy)

*– 将屏幕的内容创建为位图图象数据
hmemdc = createcompatibledc (hformdc)
hmembmp = createcompatiblebitmap (hformdc, pnwidth, pnheight)
hsavedbitmap = selectobject(hmemdc, hmembmp)

*– 将位图数据从屏幕拷贝到虚拟设备上
= bitblt (hmemdc, 0,0, pnwidth,pnheight, hformdc, 0,0, srccopy)
= selectobject(hmemdc, hsavedbitmap)

* retrieving bits from the compatible bitmap into a buffer
* as a device-independent bitmap (dib) with a bitsperpixel value
* as one of the printer device context
lcbinfo = initbitmapinfo(hprndc)
lpbitsarray = initbitsarray()
= getdibits (hmemdc, hmembmp, 0, pnheight,;
lpbitsarray, @lcbinfo, dib_rgb_colors)

lcdocinfo = chr(20) + repli(chr(0), 19) && docinfo struct – 20 bytes
if startdoc(hprndc, @lcdocinfo) > 0
= startpage(hprndc)

= stretchdibits (hprndc, xoffsprn, yoffsprn,;
xoffsprn + int(xscale * pnwidth),;
yoffsprn + int(yscale * pnheight),;
0,0, pnwidth, pnheight,;
lpbitsarray, @lcbinfo, dib_rgb_colors, srccopy)

= endpage(hprndc)
= enddoc(hprndc)
endif

*– 退出时释放系统资源
= globalfree(lpbitsarray)
= deleteobject(hmembmp)
= deletedc(hmemdc)
= deletedc(hprndc)
= releasedc(hwnd, hformdc)
return

procedure getwinrect (lnhwnd, lnwidth, lnheight)
*– 返回指定句柄的窗口的宽和高
#define maxdword 4294967295 && 0xffffffff
local lprect, lnleft, lntop, lnright, lnbottom
lprect = repli (chr(0), 16)
= getwindowrect (lnhwnd, @lprect)

lnright = buf2dword(substr(lprect, 9,4))
lnbottom = buf2dword(substr(lprect, 13,4))

lnleft = buf2dword(substr(lprect, 1,4))
if lnleft > lnright
lnleft = lnleft – maxdword
endif
lntop = buf2dword(substr(lprect, 5,4))
if lntop > lnbottom
lntop = lntop – maxdword
endif

lnwidth = lnright – lnleft
lnheight = lnbottom – lntop
return

function getdefaultprndc
* returns device context for the default printer
#define pd_returndc 256
#define pd_returndefault 1024
local lcstruct, lnflags
lnflags = pd_returndefault + pd_returndc

* fill printdlg structure
lcstruct = num2dword(66) + repli(chr(0), 16) +;
num2dword(lnflags) + repli(chr(0), 42)
if printdlg (@lcstruct) <> 0
return buf2dword (substr(lcstruct, 17,4))
endif
return 0

function initbitmapinfo(htargetdc)
#define bi_rgb 0
#define rgbquad_size 4 && rgbquad
#define bhdr_size 40 && bitmapinfoheader

local lnrgbquadsize, lcrgbquad, lcbihdr

* use printer bitperpixel value
lnbitsperpixel = 24

* initializing bitmapinfoheader structure
lcbihdr = num2dword(bhdr_size) +;
num2dword(pnwidth) + num2dword(pnheight) +;
num2word(1) + num2word(lnbitsperpixel) +;
num2dword(bi_rgb) + repli(chr(0), 20)

* creating a buffer for the color table
if lnbitsperpixel <= 8
lnrgbquadsize = (2^lnbitsperpixel) * rgbquad_size
lcrgbquad = repli(chr(0), lnrgbquadsize)
else
lcrgbquad = “”
endif
return lcbihdr + lcrgbquad

procedure initbitsarray()
#define gmem_fixed 0
local lnptr, lnallocsize

* making sure the value is dword-aligned
lnbytesperscan = int((pnwidth * lnbitsperpixel)/8)
if mod(lnbytesperscan, 4) <> 0
lnbytesperscan = lnbytesperscan + 4 – mod(lnbytesperscan, 4)
endif

lnallocsize = pnheight * lnbytesperscan
lnptr = globalalloc (gmem_fixed, lnallocsize)
= zeromemory (lnptr, lnallocsize)
return lnptr

function num2word (lnvalue)
return chr(mod(m.lnvalue,256)) + chr(int(m.lnvalue/256))

function num2dword (lnvalue)
#define m0 256
#define m1 65536
#define m2 16777216
local b0, b1, b2, b3
b3 = int(lnvalue/m2)
b2 = int((lnvalue – b3*m2)/m1)
b1 = int((lnvalue – b3*m2 – b2*m1)/m0)
b0 = mod(lnvalue, m0)
return chr(b0)+chr(b1)+chr(b2)+chr(b3)

function buf2word (lcbuffer)
return asc(substr(lcbuffer, 1,1)) + ;
asc(substr(lcbuffer, 2,1)) * 256

function buf2dword (lcbuffer)
return asc(substr(lcbuffer, 1,1)) + ;
asc(substr(lcbuffer, 2,1)) * 256 +;
asc(substr(lcbuffer, 3,1)) * 65536 +;
asc(substr(lcbuffer, 4,1)) * 16777216

procedure decl && so many of them declared here
declare integer getfocus in user32
declare integer enddoc in gdi32 integer hdc
declare integer getwindowdc in user32 integer hwnd
declare integer deleteobject in gdi32 integer hobject
declare integer createcompatibledc in gdi32 integer hdc
declare integer releasedc in user32 integer hwnd, integer hdc
declare integer getwindowrect in user32 integer hwnd, string @lprect
declare integer globalalloc in kernel32 integer wflags, integer dwbytes
declare integer getdevicecaps in gdi32 integer hdc, integer nindex
declare integer selectobject in gdi32 integer hdc, integer hobject
declare integer startdoc in gdi32 integer hdc, string @ lpdi
declare integer globalfree in kernel32 integer hmem
declare integer printdlg in comdlg32 string @ lppd
declare integer deletedc in gdi32 integer hdc
declare integer startpage in gdi32 integer hdc
declare integer endpage in gdi32 integer hdc

declare rtlzeromemory in kernel32 as zeromemory;
integer dest, integer numbytes

declare integer createcompatiblebitmap in gdi32;
integer hdc, integer nwidth, integer nheight

declare integer bitblt in gdi32;
integer hdestdc, integer x, integer y,;
integer nwidth, integer nheight, integer hsrcdc,;
integer xsrc, integer ysrc, integer dwrop

declare integer stretchdibits in gdi32;
integer hdc, integer xdest, integer ydest,;
integer ndestwidth, integer ndestheight, integer xsrc,;
integer ysrc, integer nsrcwidth, integer nsrcheight,;
integer lpbits, string @lpbitsinfo,;
integer iusage, integer dwrop

declare integer getdibits in gdi32;
integer hdc, integer hbmp, integer ustartscan,;
integer cscanlines, integer lpvbits, string @lpbi,;
integer uusage
return && decl

如何创建一个根据屏幕分辩率自动调整的表单

概述
在一种分辩率下开发的屏幕在另一种分辩率下运行时, 可能与你期望的不同. 一种方案是开发不同分辩率下的多个不同的屏幕, 并在某一分辩率下运行相应的屏幕.

但是在 Visual FoxPro 中, 可以根据当前分辩率动态调整屏幕大小并重新安排对象. 本文用例子演示了如何这样做.

更多信息

逐步示例
在 640×480 分辩率下创建一个新表单. 添加一些文本框, 命令按钮和标签这样的控件到表单.

将以下代码放入表单的 Init 事件中和表单中的任何窗口任何容器对象(如页框中的页)的 Init 事件中:

** 假定屏幕是在 640×480 下创建的
LOCAL lnHeight, lnWidth, lnHeightdiff, lnWidthdiff

lnHeight = 480 && 原分辩率下的控件高度
lnWidth = 640 && 原分辩率下的控件宽度
lnHeightdiff = 0 && 保存不同高度的变量
lnWidthdiff = 0 && 保存不同宽度的变量

IF SYSMETRIC(2) <> lnHeight && 如果目前不是运行于 640×480 分辩率下
lnHeightDiff = SYSMETRIC(2) / lnHeight
lnWidthDiff = SYSMETRIC(1) / lnWidth

** 如果是在容器对象(如页框中的页等非表单且具有 ControlsCount 属性的容器)的 Init 事件中, 你需要注
** 释掉以下代码直到 ENDIF 代码行.

This.Height = This.Height * lnHeightDiff
This.Width = This.Width * lnWidthDiff
This.Top = This.Top * lnHeightDiff
This.Left = This.Left * lnHeightDiff

** 遍历各对象, 重新调整和安排它们.

FOR I = 1 TO This.ControlCount
WITH This.Controls(i)
.Height = .Height * lnHeightdiff
.Width = .Width * lnWidthdiff
.Top = .Top * lnHeightdiff
.Left = .Left * lnWidthdiff

** 你也可以在这里修改 FontSize 属性来重调字体
** IF TYPE(“.FontSize”) # “U”
** && IF 用于确保控件具有 FontSize 属性
** .FontSize = .FontSize * ((.5 * lnWidthdiff) + (.5 * lnHeightdiff))
** ENDIF
** 但是, 一些较高的屏幕分辩率会适当地修改字体外观, 因此在试以上代码前应进行测试.

ENDWITH
ENDFOR
ENDIF

ThisForm.Refresh()

在表同分辩率下运行表单. 可以观察到它们的自动适应