关闭

来自Craig Boyd很棒的工具

标签: 工具加密解密encryptionwindowslibrary
3000人阅读 评论(0) 收藏 举报
分类:
发布日期:FoxTalk 2.0 四月
 
来自Craig Boyd很棒的工具
作者:Doug Hennig 翻译:Sunny
Craig Boyd(克雷格.博伊德)为VFP开发人员创作一些很棒的工具。这个月,Doug Hennig分析Craig加密函数库及分割条和进度条控件。
Craig BoydVFP组别中最突出的一位新的微软最有价值专家。他有一个非常有趣的博客(www.sweetpotatosoftware.com/SPSBlog),,是SednaX的发起人和其中一位管理人员,SednaX (www.gotdotnet.com/codegallery/codegallery.aspx?id=0826d7a6-1dab-4a71-8e70-f2170c3c1661),是一个专注于扩展VFP的社会区网站,给VFP开发人员发布了许多很棒的程序。使我不变地惊讶的不但是他创作程序的数量并慷慨地向大家发表了,而且创造性地实现了他的想法。这篇文章标记我身为FoxTalk作家的10周年纪念,开始新的一个系列,看看Craig已经创作了的一些工具。
加密函数库
在我在2006年一月份FoxTalk 2.0的文章“基于角色安全,第二部份”我简要地讨论了CraigVFPEncryption.FLL,一个向VFP开发人员提供了加密和解密函数的库文件。这个月,我们将更靠近一点的看它。你可以在www.sweetpotatosoftware.com/files/vfpencryption.zip下载这个库文件。(译者注:VFPEncryption.FLL是有两个版本的,http://www.sweetpotatosoftware.com/files/vfpencryption.zip是用Visual Studio 2005编译,需要C++ 8.0 运行时MSVCR80.DLLhttp://www.sweetpotatosoftware.com/files/vfpencryption71.zip是用Visual Studio 2003 编译,需要 C++ 7.1运行时MSVCR71.DLLVFP9带有MSVCR71.DLL。)
VFPEncryption.FLL是很简易使用的:SET LIBRARY TO VFPEncryption.FLL,和调用它的五个函数中的一个。
Encrypt(cString, cKey[, nType[, nMode]])加密指定的字符串。我会在后面详述各个参数。
Decrypt(cString, cKey[, nType[, nMode]])解密指定的字符串。
EncryptFile(cSourceFileName, cTargetFileName, cKey[, nType[, nMode]])加密指定文件,创建目标文件的结果为函数返回值。(两个文件名要指完整的路径)
DecryptFile(cSourceFileName, cTargetFileName, cKey[, nType[, nMode]])解密指定的文件到目标文件。
Hash(cString[, nHashType])获得指定的字符串的hash值。Hash是单向加密程序,没有方法解密的。它是经常用于密码,储存初始密码的hash,然后当用户登录时,输入的密码的hash值和储存的hash值进行比较。Hash的值的好处是不同于其他(加密)机制,没有能够被泄密的私人密匙。
如下是参数的说明:
cKey是用加密和解密的密匙。很明显,解密时,你必须提供用来加密字符串或文件相同的密匙。密匙根据不同的加密类型需要特定的长度。
nType加密的类型。VFPEncryption.FLL支持6种加密类型。0AES128,要求16个字符的密匙,1AES192,要求24个字符的密匙,2(默认)AES256,要求32个字符的密匙,4Blowfish,要求56个字符的密匙,8TEA,要求语16个字符的密匙,或者1024RC4,这种情况密匙可以任意长度。
nMode加密的模式,指定0(默认)电子源码书(ECB)(网摘:密码块操作的一种模式,其主要特点为每一种可能存在的纯文本内容都拥有固定的密文与之相对应,而且反之亦然。换言之,相同的纯文本内容总会被转化成相同的密文),1是密码块连接(CBC)(网摘:密码块运算的一种模式,密码块中一系列的二进制代码利用整个数据块中的密钥加密成单元或数据块。密码块链接使用了广为人知的固定长度的初始微量),还有2是密文反馈(CFB)(网摘:一种密码块操作模式。与密码块链接模式相对,它对一定数位大小的密码块纯文本进行一次性加密,有时候需要对一些纯文本数据值进行逐一加密并传输,这时密文反馈就是一种有效的方法。)如果使用RC4加密,就会忽略该参数据的值。
nHashType使用hash函数的类型,指定1SHA1(也叫做SHA160),2SHA2563SHA3844(默认)是SHA5125MD56RIPEMD128,或者7RIPEMD256
如果你不懂得不同的加密类型和模式,不用担心,我真的没有关于这一方面的一个线索,这是我喜欢VFPEncryption.FLL的主要原因。TestVFPEncryption.PRG是一个示范使用这个函数库的小程序。
set library to VFPEncryption.FLL
* Test encrypting and decrypting a string.
lcString    = 'This is pretty cool stuff!'
lcKey       = padr('This is a secret key phrase.', 32)
 && padded to the length needed by the default
 && encryption type
lcEncrypted = Encrypt(lcString, lcKey)
wait window lcEncrypted
wait window Decrypt(lcEncrypted, lcKey)
* Test encrypting and decrypting a file.
EncryptFile(fullpath('TestVFPEncryption.prg'), ;
 fullpath('EncryptedFile.prg'), lcKey)
modify file EncryptedFile.prg
DecryptFile(fullpath('EncryptedFile.prg'), ;
 fullpath('DecryptedFile.prg'), lcKey)
modify file DecryptedFile.prg
* Test hashing a string.
wait window Hash(lcString)
分割控件
分割条是很有趣的控件:它们本身真的没有可视的界面,却能让你们在两个或更多其他控件之间通过调节一个的尺寸,而改变其他控件的相关尺寸。分割条在Windows应用系统的许多地方里出现,在Windows的资源管理器,能使用分割条调节左右窗格的尺寸。分割条可以是水平的(左右调整对象)或垂直的(上下调整对象),和可以在同一个视窗(表单)使用分割条的两种类型。
19997FoxTalk我的专栏中,“Splitting Up is Hard to Do”,我介绍的一个VFP分割条类,SFSplitter,和具体的子类用于水平(SFSplitterH)和垂直(SFSplitterV)的分割。它们是相当的复杂类:它们自动地添加另外一个类,SFSpliterCover,到它们的父对象和使用OLE拖放实现分割条的移动。添加一个分割条到表单要拖放适当的分割条类到表单和设置相同的属性,表明了控件的名受移动的分割条影响。虽然这个类十分困难地去创建,但我已经成功在许多项目使用和不但心存在的复杂性。
去年夏天,Craig在他的博客中发布一个不同实现方法的分割条类,我必须承认我是怀疑的。在Splitter.VCX里仅仅只有一个单独的Splitter类,它只有一个属性用来设置垂直,指定分割条是否是垂直的或水平的-而且不是很多的代码。它是假设每个可视控制是左右(垂直分割的情况)或上下(水平分割的情况)的,当移动分割条时,分割条被影响,(这是)一个合理的假设,尽管你可以放置字符串“DoN't_MoVe_SpLiT”入Tag的任何控件的会被忽略。
我们去看看它是如何工作的,然后钻研它的代码。从Craig的网站下载www.sweetpotatosoftware.com/files/splitter.zip,解压到一个目录,并执行do form splitter。这是示例的表单,如图1所示,有三个编辑框和两个分割条,一个水平和另一个垂直。上下移动水平分割条和留意三个编辑框被适当地改变尺寸。左右移垂直分割条,下面两个编辑必然被调整了。
1
现在编辑这个表单,注意除了适当直改变尺寸和定位外,只是常规地改变两个分割条控件的属性分别是Anchor(因些它们响应表单的尺寸变化)和Vertical(指示如何分割的动作)。
MousePointer属性设成“9-Size WE”,但在Init方法中,如果Vertical.f.把它改为“7-Size NS”,因此,移动鼠标到控件上时将指针转换成适当的形状,明显使用户知道它是分割条控件。MouseDown事件记录鼠标当前的XY坐标(依赖Vertical的设置记录X还是Y)到MouseDownAt自定义属性。MouseUpMouseLeave都设置这个属性为0
实际的工作是在MouseMoveMove里,由于版面原因我不在这里展示这些代码,但会详细说明它们。
MouseMove,当鼠标被移到在控件上面时激发,激发时确保鼠标左键是按下和MouseDownAt是大于0,如果鼠标在另一个控件上按下然后移到分割条的上面,这就要阻止任何事发生。如果鼠标移动(它当前的XY坐标不与MouseDownAt不相同),只要它不是太靠近表单的边缘时,程序就计算它被移动了多少,(是否太靠近表单的边缘)取决于自定义属性MinimumSizeMouseMove调用Move方法去做实正的移动和重置MouseDownAt到新的位置。MinimumSize默认是40所以控件不能变得如此小,使用你说见不到它们或使用它们,但有必要时可以把它设置一个不同的值。
Move方法是做受分割条影响的而移动所有控件和分割条本身的卑劣(dirty)行为。它是从判断MouseDownAt不是0才开始,然后锁定屏幕,那么对象的移动在全部被移动完之前, 不表现出来,计算鼠标移动的距离,和遍历它父容器中的控件,忽略任何Tag属性为“DoN't_MoVe_SpLiT”的控件,因为是非可视控件。代码首先保存控件的Anchor属性值后设为0,这是必需的否则这个控件在下次表单被改变尺寸时不能无完全显示。如果分割条是垂直的,控件是在分割条的左边或右边,如果是在分割条的右边,代码会调整控件宽度和Left属性。如果分割条是水平的,代码做控制它的上面和下面做类似处理。然后恢复控件的Anchor属性。在处理父容器的所有控件后,保存分割条的Anchor属性,然后把分割条移到它的新位置,再恢复它Anchor。最后解锁屏幕。
如果你想以编程方式移动分割条,设置MouseDownAt为一个非零值和调用Move方法。它能这样使用的,例如,恢复分割条到上次运行地表单的位置。例如,你可以在表单Init中用像一下面的代码,lnTop的值用作水平分割条的Top属性。
with This.Splitter
   .MouseDownAt = .Top
   .Move(.Left, lnTop, .Width, .Height)
endwith
它就是这样,正如我前面说的,在这类里没有太多的代码,它比几年前介绍的分割条类简单的多,和更容易使用。然而,我是个过分讲究的人,我决定创建它子类去改变它的一个处理。Splitter假设两边的控件最小尺寸相同。可是,有很多时候是一边必须比另一边大的,例如当在变得十分窄小的边上有一个列表框,但在另一边上的标签的容器和文本框,那样应该不是吧。
SFSplitter.VCXSFSplitter是分割条的子类,它带有两个新属性:nMinimumSize1,它包含了分割条左边或上面的控件的最小尺寸,和nMinimumSize2,它包含了分割条右边或下面的控件的最小尺寸。如果在它们默认值0离开它们时Init设置它们为适当的值。我然后覆盖MouseMove去使用这些属性并非MinimumSizeDo form SFSplitter,看我的子类是如何处理的。留意分割条在它们移动里不是对称,在边上的组件能够比另一个大,因为我设置了nMinimumSize1nMinimumSize2为不同的值。这个表单在Init里也改变了水平分割条的初始位置用来展示如何工作的。

进度条控件


进度条控件有时会调用温度计控件,当运行时间长的时候给用户提供反馈运行情况。Visual FoxPro已经长期含了一个ActiveX控件,微软的ProgressBar控件,可以添加到一个表单来提供这类型的反馈。可是,这个控件呈现下降趋势,它不得不要发布和注册MSCONCTL.OCX。同时,因为它是的旧控件,你会在其他应用中见到它没有现代外观而象典型的进度条。
在发布分割条控件仅一个星期后,Craig发布了他的进度条控件,ProgressBarEx.VCX里的ProgressBar。它是百分这一百VFP代码,所以没有ActiveX发布的担心。你也可以在图2里看到,它看起来象一个标准的Windows Xp的进度条,完全由色彩的梯度和一个可选的百份比标签。
 
2
 
下载www.sweetpotatosoftware.com/files/progressbarex.zip获得Craig的进度条控件。运行(压缩包)中的Example表单,在微调器中输入一个百份数值,看一下它是如何工作的。这三条进度条展示了它能表现的不同方式。
让我们来看一下Craig是如何实现他的进度条的。在ProgressBarEx.VCX里有两个类:PBBar,它是表现在进度条中单独的色块,和ProgressBar进度条的本身。
ProgressBar有几个决定它外观的属性:
BarColor进度条的颜色,当选择1是红色,2(默认)是绿色,和平是蓝色。
Bars进度条的色块数。数值越大,色块就越细。
Min进度条的最小值,默认是0
Max进度条的最大值,默认是100
Percentage当前完成的百份比。
ShowPercentage当是.t.时,在进度条中显示百份数。
SolidBar–.t.时显示实心,.f.时(默认)显示为一个个的色块。
Value进度条的当前值,你不必要指定百份比数值。例如,如果你的程序是处理1249条记录,就设置Max1249Value就是正在处理的记录号。
ProgressBarInit方法实例化Bars属性指定数量的PBBar实例,但没有设置它们的Visible属性设为.t.,所以它们最初是没有显示的。如果ShowPercentage.t.它也会添加一个标签到控件。Value属性有个Assign方法,用来计算有多少色块要显示,并设置那些色块对象的Visible属性为.t.,如果ShowPercentage.t.也要更新标签的标题。Percentage属性有一个Access方法,根据MinMax,和Value的值计算完成的百份比。
做出这个象Winows XP控件的进度条真不可思议的是PBBar类。它的Init接受逐个色块的颜色,宽度和高度三个参数(通过ProgressBar传递,当它实例化这些对象时)。为了显示一个色块,Init实例化了一系列Line对象,一个Line对像对应进度条的高度的一个像素。这些线用不同的颜色画,从中间的深色调到上下的较浅色调,做出一个过度的效果。同时,PBBar设置线的DrawMode属性为“14-Merge Pen Not”。这才让百份比的标签用正确的颜色显示出来,即使它部份地或者完全地覆盖了色块。
要使用CraigProgressBar类,简单地把它拖到表单上,根据需要设置属性,和在处理循环里设Value为一个合理值。然而,你可能想在与从开始处理过程的同一个表单中显示进度,并非使用单独的表单显示一些事情的进度。例如,我喜欢用一些类型表单的状态栏,它会在状态栏的一个面板中很好地显示进度条。我用的是Rick StrahlwwStatusBar控件而不是ActiveX微软的StatusBar控件,同样原因,Craig的进度条比ActiveX控件更好的,看看www.west-wind.com/presentations/wwstatusbar/wwstatusbar.asp,这是描述这个类的文章和下载源代码的链接。
ProgressBar有一个小小的问题,它要在Init中做所有的设置。这种方式的问题是它要求属性在属性窗口里设置好需要的值。如果你用编程方式实例化了这个类,Init事件在你有机会设置属性之前激发。所以,我创建了一个ProgressBar的子类,SFProgressBar.VCX中的SFProgressBar。我把ProgressBarInit里的代码复制到一个叫做SetupProgressBar的新方法里,并在Init里加了一个注释,所以当这个类实例化时没有事情发生。因为我懒和更合适地避免必须要手动调用SetupProgressBar,所以我添加了一个叫lSetup的自定义属性,默认值为.f.,和在SetupProgressBar的结尾设它为.t.。然后,我用下面的代码覆盖Value_Assign
lparameters tuNewVal
* Set up the progress bar if it hasn't been done.
if not This.lSetup
 This.SetupProgressBar()
endif not This.lSetup
* If the value is 0, let's be invisible. Otherwise,
* ensure we can be seen.
This.Visible = tuNewVal <> 0
dodefault(tuNewVal)
这保证了Value第一次获得设置时,进度条被完全地设置。我确定当Value0时进度条不可见,其他值才可见,所以这段代码是这样处理的。
我也建了一个wwStatusBarhttp://www.west-wind.com/presentations/wwStatusBar/wwStatusBar.zip)的子类,在SFStatusBar.VCX里叫SFStatusBar。这个类的Init方法实例化SFProgressBar为表单的ProgressBar属性,增加它一个Panel自定义属性,用指明的进度条在状态的那个面板显示,和用了BINDEVENT(),所以当这个属性被改变时,新方法PutProgressBarInPanel被激发。我也加了调用Resize用来克服wwStatusBar的一个问题,当表单第一次显示时,由于它的Resize方法,它不能完整显示,这样设置是绑定到表单的Resize事件。如表单没有改变尺寸,状态栏适当地没被调整尺寸。
This.NewObject('ProgressBar', 'SFProgressBar', ;
 'SFProgressBar.vcx')
addproperty(This.ProgressBar, 'Panel', 1)
bindevent(This.ProgressBar, 'Panel', This, ;
 'PutProgressBarInPanel', 1)
dodefault()
This.Resize()
看在运行中的SFStatusBar,执行SFProgress表单我单击“Start Process”按钮,如图3所示,进度条显示在状态栏的第二个面板里。
3
这个表单在Init里有下面的代码,在状态栏里创建一对面板和把进度条放入面板2里。
with This.oStatus
 .AddPanel('Ready', 300, .T., 0)
 .AddPanel('', 200, .F., 1)
 .RenderPanels()
 .ProgressBar.Panel = 2
endwith
按钮的Click方法里用一个伪循环来示范这个进度条。
* Have status panel 1 indicate what we're doing.
Thisform.oStatus.UpdatePanel(1, 'Processing...')
* Perform a loop and show the progress.
for lnI = 1 to 100
 Thisform.oStatus.ProgressBar.Value = lnI
 inkey(0.02, 'H')
next lnI
* Reset the progress bar back to 0 and update status
* panel 1.
Thisform.oStatus.ProgressBar.Value = 0
Thisform.oStatus.UpdatePanel(1, 'Ready')
总结
这个月,我们看了Craig Boyd慷慨捐赠给VFP社区的三个工具:一个加密函数库及分割条和进度条控件。下个月,我们将看的控件是基于VFP的日历,滚动条和任务面板。
 
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:30883次
    • 积分:437
    • 等级:
    • 排名:千里之外
    • 原创:5篇
    • 转载:0篇
    • 译文:6篇
    • 评论:12条
    文章分类