我之前从未使用过Foxpro。你可以将以下Foxpro代码转换为c#,以便我能理解逻辑。我主要对密码逻辑感兴趣。什么是spac()? can_p是存储用户名密码的.dbf文件。但密码以数字存储在多个列(k1,k2 ... k12)中。我想系统会从密码中计算出这12个数字并进入那里。
proc can_01
set colo to w/
@10,18 clea to 17,60
@10,18 to 17,60 doub
set colo to n/w
@10,34 say ' LOG IN '
set colo to w/
@12,20 say 'Enter Name.......'
@13,20 say 'Counter..........'
usr=spac(18)
cntr='*'
x=1
do whil .t.
set colo to n/w
@22,0
@22,0 say ;
'Enter user name <CR>-Exit <ESC>-Abort '
set colo to n/w,w+/bg
@12,38 get usr pict '!!!!!!!!!!!!!!!!!'
read
set colo to n/w
if read()=12 .or. usr=' ' .or. x>3
@22,0
@22,0 say 'Log In aborted..Press any key..'
??chr(7)
do can_011
read
quit
endi
x=x+1
use can_p
set exac on
loca for user=trim(usr)
set exac off
@22,0
if eof()
@22,0 say 'User '+usr+' does not exists..Press any key..'
??chr(7)
use
read
else
exit
endi
endd
do whil .t.
@22,0 say ;
'Enter Counter No <CR>-EXIT <ESC>-Abort'
@13,38 get cntr pict '!'
read
@22,0
if read()=12
do can_011
quit
endi
if trim(usr)='BABU M' .and. cntr='*'
exit
endi
if .not. cntr$'ABCD'
@22,0 say 'Incorrect Counter..Re-enter..'
??chr(7)+chr(7)
loop
endi
exit
endd
scntr=cntr
x=1
do whil .t.
set colo to n/w
@22,0
@22,0 say ;
'Enter Password <CR> - Exit <ESC> - Abort '
set colo to w/
@14,20 say 'Enter PASSWORD :-'
set cons off
@14,38 say ''
acce to ps
set cons on
cps=chr(k8+9)+chr(k4+7)+chr(k5-31)+chr(k1+13)+chr(k3-19)+;
chr(k7-35)+chr(k2-27)+chr(k6+1)+chr(k11-6)+chr(k10+6);
+chr(k12+11)+chr(k9-5)
set colo to n/w
@22,0
set exac on
if cps<>ps
@22,0 say 'Incorrect PASSWORD !! Press any key ..'
??chr(7)
read
x=x+1
if read()=12 .or. x>3
do can_011
quit
endi
else
exit
endi
endd
@22,0
@22,0 say 'Please Wait..'
set exac off
if user#'JV'
if .not. (counter=scntr .and. active)
@22,0 say 'Counter not activated...Access denied..Return to system..'
??chr(7)+chr(7)+chr(7)+chr(7)
do can_011
quit
endi
endi
xr=recn()
loca for counter=scntr .and. li .and. recn()<>xr
if found()
@22,0 say 'Counter already Logged-In by User '+user+;
'..Return to system..'
??chr(7)+chr(7)+chr(7)+chr(7)
do can_011
quit
endi
go xr
repl active with .t.,li with .t.,lidt with date(),litm with time()
unlo
do can_011
set colo to w/n,w+/g
retu
答案 0 :(得分:0)
虽然我可以写一个C#WinForms和WPF来做这件事,但我会尝试从Foxpro的角度解释一下......请注意......这看起来像是所有的代码的反编译版本foxpro关键字只显示4个字符,而不是完整且更易理解的命令。此外,这是看起来像是在VFP甚至存在之前编写的代码......就像旧的DOS时代一样,回到...... 1989天......
&& "Proc" is short for Procedure (or Func for Function) much like method in C#,
public Can_01()
{ do things here... }
proc can_01
&& "SET COLO" = Set Color to
set colo to w/
&& @x,y to x2,y2 does basic drawing, such as clear screen ( via CLEA TO = "clear to" )
&& from a DOS world of 24x80 as this appears to reflect, then draw a double border (via DOUB)
@10,18 clea to 17,60
@10,18 to 17,60 doub
&& change "COLO"r again
set colo to n/w
&& At given x/y coordinate (10,34), show a string for "LOG IN",
@10,34 say ' LOG IN '
&& another color change
set colo to w/
&& at x,y, show string label for respective
@12,20 say 'Enter Name.......'
@13,20 say 'Counter..........'
&& create variable "usr" and set it equal to 18 spaces
usr=spac(18)
&& create var "cntr" and default it to a single "*"
cntr='*'
&& create var "x" and set to 1
x=1
&& Loop... do while true -- continues until and "ENDDO"
&& in C#... while( true ) { do things... }
do whil .t.
&& more coloring and showing fixed-spacing label to the screen
&& to give user indicator of allowed input of <CR> carriage return to exit
&& or escape key to abort, but still show a label and more coloring.
set colo to n/w
@22,0
@22,0 say ;
'Enter user name <CR>-Exit <ESC>-Abort '
set colo to n/w,w+/bg
&& @/Get is actually getting user input from given x,y coordinate.
&& the "pict" is a picture clause like an input format string. "!" means
&& convert entered characters to upper case, and only allow as many characters
&& as there are "!" in the picture mask.
&& put whatever is typed into the variable "usr"
@12,38 get usr pict '!!!!!!!!!!!!!!!!!'
&& stop and wait for user input until they hit enter or escape
read
&& more color changing
set colo to n/w
&& read() or "ReadKey()" checks input length, that otherwise is the same as mask--
&& redundant. OR the user name is all spaces OR the x counter is now past 3rd attempt
if read()=12 .or. usr=' ' .or. x>3
&& show to screen login aborted
@22,0
@22,0 say 'Log In aborted..Press any key..'
&& send a DOS "beep" to the user
??chr(7)
&& do another procedure or function called "can_011" ( I guess is some "cancel" process)
do can_011
&& read will basically wait for confirmation via simple message of "Press any key..."
read
&& quit entire application
quit
endi
&& user did provide input, increase the attempted login counter x=x+1
x=x+1
&& open the table called "CAN_P"
use can_p
&& set exact matching on... to prevent things like finding "Tom" = "Tom "
set exac on
&& try to "LOCATE" for the specific user entered exists within the table
&& but trimming the value entered by the user ( C# string.Trim() )
loca for user=trim(usr)
&& turn exact matching back off
set exac off
@22,0
&& if EOF() (end of file) is reached, we did not find the user
if eof()
&& show message to user at x,y position
@22,0 say 'User '+usr+' does not exists..Press any key..'
&& another DOS bell
??chr(7)
&& close the "CAN_P" table
use
&& wait for user to press a key to try via next loop
read
else
&& we found the record in the table, exit the do/while loop
exit
endi
endd && end of the do/while loop
&& another do while true...
&& almost identical in content, but asking for some "cntr" variable.
&& almost same display, showing counter attempts and prompting
do whil .t.
@22,0 say ;
'Enter Counter No <CR>-EXIT <ESC>-Abort'
&& prompt user for a value to put into the "cntr" variable, single character
@13,38 get cntr pict '!'
&& read input
read
@22,0
if read()=12
&& again, forcing itself out via "CAN_011" procedure somewhere else
do can_011
quit
endi
&& if the user name is equal to "BABU M" and t he cntr = "*", exit the do/while loop
if trim(usr)='BABU M' .and. cntr='*'
exit
endi
&& "$" in VFP is like "contains" in C#
&& in C#... string myLongString = "testing for some value to look for";
&& string myLongString.Contains( " val" );
&&
&& in this case, 'cntr" is a single character value. and if it is NOT
&& and "A", "B", "C" or "D", tell user incorrect and re-enter
if .not. cntr$'ABCD'
@22,0 say 'Incorrect Counter..Re-enter..'
&& oooo.... two DOS beeps
??chr(7)+chr(7)
&& continue the do/while loop
loop
endi
&& leaky-boat technique... we got this far, must have had a good value,
&& exit the do/while loop
exit
endd && end of the do/while loop
&& new variable "SCntr" = whatever "cntr" is
scntr=cntr
&& reset "x" var back to 1
x=1
&& another do/while loop
do whil .t.
&& more color, and show label to user to enter password
set colo to n/w
@22,0
@22,0 say ;
'Enter Password <CR> - Exit <ESC> - Abort '
set colo to w/
@14,20 say 'Enter PASSWORD :-'
&& set console OFF so nobody can see what is being typed...
set cons off
@14,38 say ''
&& "Accept" keyboard entry to a variable "ps"
acce to ps
&& turn console back on to allow seeing typing again
set cons on
&& I don't know where the "K8", "K4", "K5", etc are... I SUSPECT they
&& are in the user's login table as some sort of mask to compare against
&& "CHR()" is to get ASCII character equivalent based on a numeric value.
&& ex: CHR(32) = ASCII 32 = space character... CHR(65) = "A", CHR(66)="B", etc...
&& so the programmer was building a variable "CPS" by adding a bunch of single
&& characters of the value of "K8" + 9 and getting its ASCII value, then adding
&& the next character, and next until all characters processed into one long string
cps=chr(k8+9)+chr(k4+7)+chr(k5-31)+chr(k1+13)+chr(k3-19)+;
chr(k7-35)+chr(k2-27)+chr(k6+1)+chr(k11-6)+chr(k10+6);
+chr(k12+11)+chr(k9-5)
&& more coloring
set colo to n/w
@22,0
&& another exact test
set exac on
&& if the data entered and "computed string" via "cps" is NOT the same
&& as what I suspect is "ps" a column in the CAN_P table (login table)
if cps<>ps
&& show message of incorrect password
@22,0 say 'Incorrect PASSWORD !! Press any key ..'
&& another bell
??chr(7)
&& wait for user to hit a key
read
&& add 1 to the "x" counter for failed attempts / abort
x=x+1
&& is user aborting, or exceeded 3 login attempts
if read()=12 .or. x > 3
&& do the cancel procedure thing again
do can_011
&& quit the app
quit
endi
else
&& valid password, EXIT the DO/WHILE loop
exit
endi
endd && end of the do/while loop
&& more display status
@22,0
@22,0 say 'Please Wait..'
set exac off
&& "#" is same as <> (not equal to)
&& if the user is NOT "JV"
if user#'JV'
&& more simple boolean check... I assume checking if user is "Active"
&& based on column in the login table
if .not. (counter=scntr .and. active)
@22,0 say 'Counter not activated...Access denied..Return to system..'
&& wow... seriously... 4 dos BEEPs, canel process and quit application
?? chr(7)+chr(7)+chr(7)+chr(7)
do can_011
quit
endi
endi
&& create var "xr" and preserve whatever the "record number" is in the user table
xr=recn()
&& while still in the login table, try to "LOCATE" for the given condition
&& based on respective variables and their counterpart in the table.
&& HOWEVER, look for value and the record is NOT the one we stored in "xr" above
loca for counter=scntr .and. li .and. recn() <> xr
if found()
&& nag user that the person is already logged in message, 4 bells, cancel, quit app
@22,0 say 'Counter already Logged-In by User '+user+;
'..Return to system..'
??chr(7)+chr(7)+chr(7)+chr(7)
do can_011
quit
endi
&& go back to the originally found record
go xr
&& replace the actual record with status of active = true,
&& lidt (I suspect login date with current date() (C# DateTime.Now is closest)
&& litm = just the time portion
repl active with .t.,li with .t.,lidt with date(),litm with time()
&& unlock the record
unlo
&& do the "CAN_011" procedure thing
do can_011
&& colors
set colo to w/n,w+/g
&& done with this routine, just return to whoever called it.
retu