网络安全 频道

VFP编程技巧

三、pass.scx 表单。
  功能:口令字效验、取出KLK中保存的硬盘卷标、判断当前硬盘卷标是否
合法、 取出KLK中的权限。
在表单及对象的方法或事件中,各自的代码是:
1.this.ini
if type(''debug0'')=''U'' &&如果未通过Main.prg而调式,则:
  wait wind ''请您从执行Main.PRG开始,进行调式......''
  this.release
  retu
endi
******以下为解密klk.dat文件**************************************
thisform.Vfpjmdbf1.pass_kl=''12345678'' &&设置加解密口令
thisform.Vfpjmdbf1.path_ml=dqml &&设定klk.dat文件所在目录
thisform.Vfpjmdbf1.jiEmi_file=''klk.dat'' &&存放密码的资料库文件名
thisform.Vfpjmdbf1.jiEmi &&解密klk.dat文件,并打开以''klk''为别名的工作区
thisform.Vfpjmdbf1.Visible=.f. &&隐藏 Vfpjmdbf1
Go top
******************以下为取磁盘卷标的WIN32API调用*******************
Stor 0 to C_var,C_cd,C_qf
C_disk=''c:\'' &&指定磁盘
DECLARE INTEGER GetVolumeInformation IN Win32API STRING @, STRING @,;
 INTEGER,; INTEGER @, INTEGER @, INTEGER @, STRING @, INTEGER
xx=GetVolumeInformation(C_disk,"",20,@C_var,@C_cd,@C_qf,0,0)
CLEAR DLLS
* C_var=指定磁盘的卷标,是个十进制的数值。
if varjb=0 &&klk.varjb=0 表明是第一次运行本软件
  repl varjb with C_var &&将磁盘卷标写入klk.varjb字段
  thisform.Vfpjmdbf1.jiAmi_file=''''
  thisform.Vfpjmdbf1.jiAmi   &&先关闭,以保存修改
  *要保存修改必须经Vfpjmdbf1.jiAmi来关闭库才行,
  thisform.Vfpjmdbf1.jiEmi_file=''klk.dat'' &&存放密码的资料库
  thisform.Vfpjmdbf1.jiEmi     &&再打开
else           &&否则是已运行过本软件
  if varjb<>C_var   &&判断klk.varjb是否等于当前磁盘卷标(C_var)
    =Messagebox("对不起!您现在运行的软件未经过作者确认,不能运行... ",;
          0+48+0,"警告")
    quit
  endi
endi

2.this.unload
if type(''debug0'')=''U''
  do Case    &&根据klk.qx字段决定菜单的屏蔽操作
  case qx=1
   set skip of bar 1 of 权限F .t.
   set skip of bar 2 of 权限F .t.
  case qx=2
   set skip of bar 1 of 权限F .t.
   set skip of bar 2 of 权限F .t.
   set skip of bar 3 of 权限F .t.
  endc
  use       &&关闭klk
endi

3.thisform.text1.keypress
if nKeyCode#13
  retu
endi
loca for allt(this.value)==allt(Passkl) &&查找相符的口令字
if !foun()
  =Messagebox("对不起!您的口令有误,不能运行...... ",; 0+48+0,"警告")
  thisform.release
  quit    &&退出系统,为了简单,口令效验我只设了一次。
endi
thisform.release

  四、查看和修改KLK的表单,这里就不具体写代码了。
  
  五、菜单1.MPR 主菜单,这里就不具体写代码了。

  实例中的权限密码是:0=全权        口令=aaaaaa
             1=可修改自己的密码  口令=666666 
             2=不能作任何修改   口令=888888

  需要以上程序源代码实例的,这里下载

  从以上代码中可以看出,里面没有什么新的东西,所用的工具或资料,在我网上都
可找到,我只不过是把它们拼凑一下而已。您可把这个实例编译成EXE文件(VFP5.0的
朋友可能无法把共享版的Vfpjmdbf.vcx编进去),先在您的机器上运行一下,然后再
把它们直接拷贝到另外一台机器上一试,您看看还能运行否?
  当然,别人只要用REFOX7.06把里面的Main.prg反编译出来,去掉:
“ do form (Dqml+''pass'')”这一句,还是可以非法拷贝的,那怎么办?
  最好的办法是加密您的EXE文件,这样您的软件就比较保险了,最起码Refox等现成
的反编译工具是不可能反编译的。
  在我网上有加密VFP&EXE的工具下载,您可下载一试。
  需要说明的是:在我网上下载的vfpjmdbf.vcx和Vfp&Exe.exe都是共享版,功能和
使用次数都有一定的限制,如果您觉得还可以,请您花很少一点钱来注册这两个工具,
注册后,我将提供正式版和今后的免费升级。(最新Vfp&Exe.exe可以设置您自己的图表了)

  如何把数字转换为汉字大写金额代码分析

  •   [编程心得]又和您见面了,这次所写的是:怎样才能合理利
    用 VFP本身所提供的命令和函数来组织代码、编制程序,以提高
    运行效率。为了能说明问题,我以数字转换为大写为例,通过对
    三组代码的对比来谈谈我个人对此问题的认识。
      每种语言提供给我们的命令或函数,可以说最能体现这种语
    言的本质,而每个程序员如何运用和组织这些命令或函数,则可
    以直接反映这个程序员对这种语言的理解和掌握程度。现在虽然
    更多的是强调如何学习和掌握面向对象的编程方法,以及如何灵
    活运用这些对象中的事件和方法来组织代码,但我们切不可忽视
    对这些最基本的语言命令或函数的学习、理解和灵活掌握。
      下面我们以数字转换为大写为例来加以说明:
      对于如何把数字转换为汉字大写金额的编程,我在网上看到
    了许多种写法,代码最多的一种写法,其代码竟多达 100多行,
    让人看了眼花缭乱,很难理解,而代码最少的却连10行都不到,
    而其运行结果却是完全相同,可见理解和合理组织编程语言所提
    供的命令和函数是何等的重要。
      考虑到版面的原因,那近百行的代码我就不具体举例了,下
    面的这些代码是我自行组织编写的,如有雷同,则纯属巧合:
     代码一、
    FUNCTION Rmbzh
    1. PARA nDhsj
    2. rmbxx=allt(str(nDhsj,12,2))
    3. lszs=allt(str(int(nDhsj)))
    4. cd0=len(lszs)
    5. dws0=''元拾佰千万拾佰千亿''
    6. sh0=''壹贰叁肆伍陆柒捌玖零''
    7. rmbdx=''''
    8. cd1=cd0
    9. for I=1 to cd0
    10.   lspd=right(lszs,cd1)
    11.   if val(lspd)=0
    12.    rmbdx=rmbdx+iif(cd1>4,''万元'',''元'')
    13.    exit
    14.   endi
    15.   ss=int(val(subs(lszs,I,1)))
    16.   if ss#0
    17.     rem0=SUBSTRC(sh0,ss,1)+SUBSTRC(dws0,cd1,1)
    18.   else
    19.     rem0=iif(I#cd0,''零'',''元'')
    20.   endi
    21.   rmbdx=rmbdx+rem0
    22.   cd1=cd1-1
    23. endf
    24. do while atc(''零零'',rmbdx)>0
    25.   cc=10-atc(''零零'',rmbdx)
    26.   rmbdx=strtr(rmbdx,''零零'',SUBSTRC(dws0,cc,1),1,1)
    27.   rmbdx=strtr(rmbdx,''零零'',''零'',1,1)
    28.   rmbdx=strtr(rmbdx,''零零'','''',1,1)
    29. endd
    30. lsxs=allt(str(nDhsj,12,2))
    31. lsxs=right(lsxs,2)
    32. if val(lsxs)#0
    33.   ss=int(val(subs(lsxs,1,1)))
    34.   rem0=SUBSTRC(sh0,ss,1)+''角''
    35.   rmbdx=rmbdx+rem0
    36.   ss=int(val(subs(lsxs,2,1)))
    37.   rem0=iif(ss=0,''整'',SUBSTRC(sh0,ss,1)+''分'')
    38.   rmbdx=rmbdx+rem0
    39. else
    40.   rmbdx=rmbdx+''整''
    41. endi
    42. Retu rmbdx
      这组代码是从纯数字的角度去考虑如何转换的,所以显得不
    够简洁, 比如第3行和第31行,分别把整数部分和小数部分加以
    分开,各自进行转换,就显的没有这个必要,但它也有可取之处,
    比如:
     1.充分利用了系统提供的函数,尤其是SUBSTRC()这个双字节
    函数。
     2.它运行的结果可以达到完全口语化的汉语金额,如:
    12300.00元,其运行的结果是:壹万贰千叁佰元整,完全符合支
    票类填写方式。但却不符合填充类方式。

     代码二、
    FUNCTION Rmbzh
    1. PARA nDhsj, nDW   &&nDW如果等于1,表示要金额单位
    2. nDzs=strt(allt(str(nDhsj,15,2)),".","") &&把小数点去掉
    3. hzdx="零壹贰叁肆伍陆柒捌玖"
    4. cDW="分角元拾佰仟万拾佰仟亿拾佰仟"
    5. rmbdx=""
    6. nCd=len(nDzs)
    7. for i=1 to len(nDzs)
    8.   NumS=substrc(hzdx,int(val(subs(nDzs,i,1))+1),1)
    9.   nDWs=iif(nDW=1,substrc(cDW,nCd,1),spac(2))
    10.  rmbdx=rmbdx+NumS+nDwS
    11.  nCd=nCd-1
    12. endfor
    13. Retu rmbdx
     这个代码就是在我网上提供下载的那个实例,可以看出它非常简洁,
    编程线路清醒,第7行和第8行分别是数字转换和单位转换,不仅简单
    明了,而且还可根据需要选择是否需要金额单位,但也有缺点,就是
    不能象上例那样做到完全口语化,我之所以把它作为实例供下载,原
    因就在于其清晰的思路和简洁的代码组织形式。
      那么这组代码还可以“精简”(其实应该叫合并)吗?答案是:
    当然可以。

     代码三、
    FUNCTION Rmbzh
    1. PARA nDhsj, nDW   &&nDW如果等于1,表示要金额单位
    2. nDzs=strt(allt(str(nDhsj,15,2)),".","")
    3. hzdx="零壹贰叁肆伍陆柒捌玖分角元拾佰仟万拾佰仟亿拾佰仟"
    4. rmbdx=""
    5. for i=len(nDzs) to 1 step -1
    6. NumS=substrc(hzdx,2*val(subs(nDzs,len(nDzs)-i+1,1))+1,1)
    7. nDws=iif(nDW=1,substrc(hzdx,i+10,1),space(2))
    8. rmbdx=rmbdx+NumS+nDwS
    9. endfor
    10. Retu rmbdx
     可以看出这组代码又比上一组少了三行代码,而其最终运行的结果
    是一样的,但它所带来的副作用是:代码不直观明了,不细细查看,
    一时难以明白,尤其是第6行和第7行中substrc()中的参数需经过多
    次运算方可得知,这对今后的维护带来了不便,我一般不采用这种写
    法。如果硬是要再合并的话,那这组代码还可以继续合并,比如可以
    把6-8行的代码合并为1行。

      从上面的这几这几组代码我们不难看出,同一种运行目的,可以
    有各种不同的代码组成和表现形式,也可以体现每个程序员各自不同
    的编程风格,但不管如何,提高程序的运行效率是每个程序员所共同
    追求的。
      如果您有一定的汇编知识,可以把第二组代码和第三组代码编译
    成可执行程序后,进行反汇编,这时您就会发现它们的汇编结果几乎
    是完全相同的,也就是说它们在运行时仍然把您浓缩在一行中的源代
    码分开,一条指令再一条指令地执行的,并不是按您源代码中的意愿,
    一行代码就一条指令,因而这种“合并”,对提高运行速度和效率没
    任何作用。既然如此,一味追求VFP源代码的“精简” 就显的毫无意
    义了,反而给自己带来维护的不便。所以不管如何写代码,直观清晰
    的编程思路和尽可能地提高运行效率才是我们所提倡的编程风格。
      我谈了这么多所谓的体会,并不是说我写的代码就是高效率和完
    全合理的,我只是想从另一个角度来谈谈如何在学习和掌握面向对象
    编程的过程中,认识和重视这些最基本的知识,只有这样才不会浪费
    VFP为我们提供的这些非常丰富的命令和函数。
      自办了这个[编程心得],我收到了许多编程爱好者的来信,希望
    我继续写下去,可能是由于我的水平有限,还真有些感到骑虎难下,
    所以每期的主题显得很凌乱,还望各位理解。如果大家觉得这个栏目
    对您的编程有所帮助的话,那我会继续努力的。
      我期待着您的批评和建议。

  • 0
    相关文章