控件设计(共7篇)
控件设计 篇1
控件, 作为用户界面一个非常核心的因素, 其程序设计是非常重要的。一个优秀的控件, 不但要考虑其美观, 操作便捷, 更要考虑其渲染效率, 方便换肤, 自适应屏幕分辨率以及为某些定制化功能提供非常方便的方案。
1 控件外观
无论内部代码如何, 用户界面的控件最终是将展示给用户的。用户体验的好坏, 将直接影响用户对这个程序的感觉, 所以一个用户界面的控件外观, 是非常重要的因素。对于控件的外观设计, 自从用户界面诞生以来, 就一直在被改进。
例如从win32的矩形按钮, 到win xp的圆角矩形按钮再到win8的图标式可触摸按钮, 界面的设计师在想方设法美化控件, 给用户带来更好的感觉。但是由于显示技术的局限性, 控件的设计大都局限于二维的图案设计。而随着3D技术的迅猛发展, 设计和制作3D的控件, 无疑能极大地给最终用户带来全新的用户体验, 并且在产品设计上, 3D控件的设计自由度无疑会比二维设计更大。可以说, 随着3D显示技术的不断普及, 3D控件也会得到很大的发展。
2 控件操作性
控件, 作为人机交互一个非常重要的接入点, 用户体验中, 操作性非常重要。用户会非常乐意接受简单易懂的操作方式。从人机交互的发展历史来看, 最早是由指示灯和机械开关组成的操纵界面, 然后发展到终端和键盘组成的字符界面, 再到多种输入设备和光栅图形显示设备构成的图形用户界面。不同的界面, 对控件的操作性要求也是不同的。在现在图形用户界面中, 控件的操作方式可以分成两种:映射操作和全屏操作。
所谓映射操作模式, 就是指用户所操作的东西和屏幕显示的东西, 是有一定映射关系的, 比如键盘或者遥控器。用户按下了一个按钮, 屏幕上面的控件并不知道用户当前正在操作哪一个控件, 需要在程序内部定义一系列映射的关系。如果用户按下了键盘上面右边这个按钮, 那么控件的普遍行为就应该使自己失去焦点, 随后使这个右边的控件来获得焦点。而在程序控制之外的控件, 用户是无法对它们进行操作的。除了键盘, 传统的摇杆, 正在发展中的手势或者语音, 都是映射的操作模式。
鼠标或者触摸屏, 则是全屏操作模式。用户通过自己的手指, 或者是鼠标, 可以随意的操作屏幕上面显示的任意一个控件。相比映射操作模式, 它的特点是使用简单。因为它所见即所得的特性, 在执行简单操作的时候, 它的使用比映射的模式要方便。但是如果某个界面功能非常复杂, 例如需要通过许多组合快捷键进行一系列操作的话, 那么它不如映射模式功能那么强大。
由于现在大部分人机交互, 是基于屏幕显示的, 而现在的屏幕受显示技术和制作工艺的制约, 在控件的操作方面, 也会得到一定的限制。而如果控件3D化了之后, 相应的操作行为也将得到丰富。但是总的来说, 简单易用, 是控件操作性的一个必要条件。而在控件设计编写的过程中, 上面两种模式的编写, 以及这两种模式切换的考虑都是非常有必要的。
3 控件的重用性
从开发者的角度来讲, 如果用户界面上面有一点点改动就需要重新开发一个新的控件的话, 无疑说明了已有的控件没有很好的重用性。
要满足控件的重用性, 首先要在代码功能上面满足所需的要求。如果控件的需求超出了控件的要求, 那么就意味着该控件有很大可能是没有办法重用的。对于比较常见的控件, 比方说普通按钮来讲, 大家都对其功能非常了解, 那么在开发此类按钮的时候, 就要尽可能多地把按钮所具备的功能全部都完善。
除此之外, 界面逻辑分离也会极大程度地提升控件的重用性。比方说, 控件的界面和图形元素通过第三方通用格式的文件来定义, 控件程序做无差异化的解析和渲染, 这样控件的重用性可以得到非常大的保障。在功能相同界面不同的情况下, 只要更换第三方格式的文件而不需要重新编译程序;而相对, 如果是界面相同, 但是应用平台不同的话, 那么只需要用不同的语言实现相同的控件解析功能即可实现。
4 控件的扩展性
随着时代的发展, 人们对于控件的要求也越来越高。一些简单的控件, 往往不能满足现在一些复杂界面的操作。而随着用户界面的不断丰富, 不同显示终端, 不同操作方式的控件也日益增多。以此, 控件的扩展性成为了一个比较重要的功能。
而在当前的需求下面, 用户的控件需要考虑以下的扩展性:
(1) 换肤。这并不是一个新的需求, 但是方便的换肤对于控件来讲, 具有着事半功倍的效果。如果能对一个用户界面, 在美工设计好之后, 仅仅更换一些素材文件和样式文件而不需要更改程序的话, 这样的软件开发效率会非常高。
(2) 不同的操作方式。虽然很多情况下, 在一种特定的操作系统下面, 用户会使用特定的操作方式, 但是如果能让用户自由地在不同的操作方式下面选择的话, 无疑具有相当大的吸引性。而在控件设计的初步就考虑其不同的操作方式的话, 其成本是最低的。
(3) 不同的渲染方式。二维控件目前还是主流的控件。但是视觉3D的魅力是二维画面无法比拟的。随着视觉3D越来越流行, 如果控件本身支持多种模式渲染的话, 是令人振奋的。试想一下, 面对一套用户界面, 用户可以定制个性化的界面, 又能选择不同的操作模式, 还能方便地在二维、三维等多种渲染模式下面使用界面, 这样的用户体验是非常优秀的。
Delphi自定义控件设计 篇2
关键词:控件,自定义控件,Delphi控件
Delphi语言受众多程序员追捧,主要原因之一就是它有很多第三方的控件可供使用。很多资深的Delphi程序员都把自己积累的函数、过程等设计成控件,以方便使用,提高开发效率。
本文通过一个只允许输入数字、并且可以设置输入值范围和小数点位数的编辑框控件的设计,详细介绍了控件的实现方法。该控件继承自edit控件,控件单元名称为NumEdit,控件类名称为TNumEdit。控件的实现主要分为4个阶段:
(1)建立控件原型。
(2)设计控件功能代码。
(3)设计控件图标。
(4)安装发布控件。
下面对这四个阶段进行详细讲解。
1 建立控件原型
可以通过Delphi向导建立控件原型。通过Delphi菜单“File-New-Other”打开“New Items”对话框,然后在New属性页中选择“Component”,点击“OK”,弹出“New Component”对话框,在该对话框中设置控件的基本信息,如图1。
Ancestor type:选择控件要继承的类,选择“TEdit(StdC-trls)”。
Class Name:要创建的控件的类名称,我们设置为“TNumEdit”。
Palette Page:该自定义控件发布后将要停靠的控件面板。
Unit file name:该控件代码存放路径。
设置好上面信息后,点“OK”按钮,向导自动生成最原始的控件代码,如下:
到目前为止,控件TNumEdit已经具备了Tedit编辑框的所有功能,下面就可以在这个基础上设计需求的功能了。
2 设计控件功能
(1)只允许输入数字。
(2)可以设置输入范围,即可以设置输入数字的最小、最大值。
(3)可以设置输入数字的小数点位数。
基于上面需求,控件需要做如下几个方面处理:
(1)继承控件接收的按键事件,如果按的不是数字键直接返回。
(2)增加控件可以接收的最大值Max、最小值属性Min。
(3)增加控件小数点设置的属性dotnum。
(4)响应控件焦点离开消息(cm_exit),在这里处理控件中录入的内容,使其大于Min、小于Max且小数点位数等于dotnum。
下面结合该控件代码,通过代码的注释详细地讲解处理过程。
3 设计控件图标
Delphi控件要使用一个图标显示在Delphi的控件面板上供开发者使用(由上面设计可知,该控件要显示在Delphi控件面板的samples面板上),控件的图标有如下要求(注意图标文件名和图标名称的区别,下面有讲述):
(1)图标文件名称为dcr(后缀名为dcr)格式,该类文件可认为是图标的容器,其中可以包含多个图标。
(2)图标文件名要与控件单元的文件名一致,如该控件的图标文件名应该为NumEdit.dcr。
(3)图标名称要与控件类名称一致。如本控件的图标名称应该为TNumEdit。
(4)图标文件要与控件单元文件位于同一目录下,这样发布控件时候才能关联到一块。
下面通过用Delphi自带的工具image editor设计本控件的图标来介绍控件图标的设计,步骤如下:
(1)通过Delphi的菜单“tools-image editor”打开图标编辑工具。
(2)通过file-new-component resource file(.dcr)建立一个图标文件。把它保存在NumEdit.pas相同目录下,名称为:NumEdit.dcr。此时image-editor如图2所示。
(3)在图2中,鼠标右键点“Contents”,然后在弹出的菜单中选择“new-Bitmap”打开“Bitmap Properties”框,设置属性后点“OK”即可创建一个默认名称为“bitmap1”的位图,把其名称修改为“TNumEdit”,并双击打开,然后通过画笔等工具设计该位图,示意如图3所示。
设计位图根据自己的喜好,这里做简单的设计,设计好后保存即可。至此,该控件对应的图标已经设计好。
4 安装发布控件
目前已经完成了控件的设计,该控件包含两个文件,代码文件NumEdit.pas和图标文件NumEdit.dcr。下面介绍如何把该控件安装到Delphi的控件面板上供开发者使用,步骤如下:
(1)把这两个文件拷贝到指定目录下,对于自定义控件,作为一种好的开发习惯,一般在Delphi安装目录下建立custom目录并把自定义控件拷贝过去。这里也建立customnumedit目录,然后把该控件的文件拷贝到该目录下,如下:
(2)在Delphi库中增加该控件的路径。通过菜单:
“tools-environment-options”打开“environment-options”对话框,选择“library”属性页,然后单击“library path”后的选项按钮打开“Directories”对话框,在该对话框中手工录入或者通过选项按钮把控件路径填写进去,如图4所示。
点击“Add”按钮,点击“OK”,回到“environment-options”对话框,再点击“OK”完成库文件路径添加。
(3)控件安装。通过前两步的处理,就可以安装控件了,通过菜单“Component-Install Component”打开控件安装对话框,点击“into existing package”属性页中的“unit file name”后的“Browse”按钮,选中要安装的控件文件NumEdit.pas,然后点“OK”按钮即可。系统提示是否编译,选择编译后便可以把该控件安装到Delphi的控件面板,如图5所示。
至此已经完成了一个控件从最开始的需求分析到最终发布使用的全部过程。
控件设计 篇3
ASP.NET Web服务器控件分为以下4类:HTML服务器控件,Web服务器控件不仅包括窗体控件(例如按钮和文本框),而且还包括特殊用途的控件,验证控件,用户控件作为ASP.NET网页创建的控件。
2 控件技术
2.1. NET框架
.NET框架是一个多语言组件开发和执行环境,它提供了一个跨语言的统一编程环境。.NET框架的目的是便于开发人员更容易地建立Web应用程序和Web服务,使得Internet上的各应用程序之间,可以使用Web服务进行沟通。
2.2 ASP.NET
ASP的全称为Active Server Pages(中文译名为活动服务器页面),ASP.NET是一个已编译的、基于.NET的环境,可以用任何与.NET兼容的语言(包括Visual Basic.NET、C#和JScript.NET)开发应用程序。另外,任何ASP.NET应用程序都可以使用整个.NET框架。开发人员可以方便地获得这些技术的优点,其中包括托管的公共语言运行库环境、类型安全、继承等。
2.3 ASP.NET Web服务器控件的生命周期
ASP.NET Web页面运行时,此页面将经历一个生命周期,在生命周期中将执行一系列处理步骤。这些步骤包括初始化、实例化控件、还原和维护状态、运行事件处理程序代码以及进行呈现。
控件的生命周期是创建服务器控件最重要的概念,在掌握服务器控件生命周期的过程中,要特别注意有关服务器控件状态的相关内容。控件的生命周期何时保存控件和恢复其状态;何时与页面及其他控件之间进行交互;何时执行重要的处理逻辑;在各个阶段,控件可使用哪些信息、保持哪些数据、控件呈现时处于哪种状态以及何时输出显示标记文本等。
3 设计概念与处理流程
通常的数据库业务处理往往会涉及到主从表的操作,因此规定主表的处理逻辑主要通过MMPAGE的Page_Load事件触发处理,子表的处理逻辑通过子表控件(MMData Grid控件)的事件来触发处理。
在MM.Web Controls Public Class.vb文件中定义了所有公用的结构,这些结构类型如下:
3.1 环境变量
Public Enum DEFAULTVALUES
NULL'不使用环境变量
USERID/USERNAME'默认当前用户ID/用户名
DEPTID/DEPTNAME'默认当前用户的部门ID/部门名称
TODAY/NOW'系统日期/时间,格式为[YYYY-MM-DD HH:mm:SS]
End Enum
3.2 表单显示模式
Public Enum DISPLAYMODES
EDITMODE'编辑状态
SHOWMODE'显示状态
End Enum
3.3 标识控件的读取属性
Public Enum READWRITES
READWRITE'可读写
ONLYREAD'只读
ONLYWRITE'只写
End Enum
4 数据处理类控件
4.1 MMDATASET
描述:
该控件为SQL语句处理控件。业务数据主表的字段名就是“MMID”,业务数据子表除了具有“MMID”字段与主表关联外,子表主键字段名为子表名+“_MMID”。
方法:
MAKEMSSQL
方法算法:
DIM SQLSTRING AS STRING
//用于记录返回值(SQL语句)
IF SQLTYPE=1 THEN//判断表名为TABLENAME的业务//表,根据TABLENAME和FIELDNAME以及相关属性,生成//SQL语句,赋值给SQLSTRING。
RETURN SQLSTRING
ELSE IF SQLTYPE=2 THEN//插入数据
IF ISMAINTABLE THEN//生成Insert SQL语句,并赋值给//SQLSTRING。
RETURN SQLSTRING
ELSE//枚举CHILDCONTROLS中所有控件。
RETURN SQLSTRING
END IF
ELSE IF SQLTYPE=3 THEN//更新数据
IF ISMAINTABLE THEN//生成Update SQL语句,并赋值给//SQLSTRING。
RETURN SQLSTRING
ELSE//生成Update TABLENAME表的SQL语句,并赋值//给SQLSTRING。
RETURN SQLSTRING
END IF
ELSE IF SQLTYPE=4 THEN//删除数据
IF ISMAINTABLE THEN THEN//生成删除主表记录的SQL//语句,并赋值给SQLSTRING。
RETURN SQLSTRING
ELSE//生成删除子表记录的SQL语句,并赋值给SQL//STRING
RETURN SQLSTRING
END IF
ELSE IF SQLTYPE=5 THEN//查询数据
IF ISMAINTABLE THEN//生成主表的Select语句,赋值//给SQLSTRING。
ELSE//生成子表的Select语句,并赋值给SQLSTRING。
END IF
RETURN SQLSTRING
ELSE IF SQLTYPE=6 THEN//生成子表编辑时单纪录的//Select语句,并赋值给SQLSTRING。
RETURN SQLSTRING
ELSE IF SQLTYPE=7 THEN//COPY业务子表的数据
IF NOT ISMAINTABLE THEN
SQLSTRING=INSERT ME.TABLENAME
SELECT NULL,ME.GUID,CHINLDCONTROL.FIELDEN-NAME[]FROM ME.TABLENAME WHERE MMID=ME.MMID
MMID=0
END IF
END IF
结束枚举
4.2 MMPROVIDER
描述:
微软SQL语句执行控件
方法:
(1)MAKETABLE//创建表单中业务表
方法算法:
遍历CHILDCONTROLS数组中的MMDATASET对象,调用每一个MMDATASET对象的MAKEMSSQL(1),生成创建数据表的SQL,执行SQL
(2)UPDATEDATA//更新数据表的数据
方法算法:
IF TABLENAME=””THEN
遍历CHILDCONTROLS数组中的MMDATASET对象,调用每一个MMDATASET对象的MAKEMSSQL(5),生成执行SQL然后,调用MMDATASET的SETCONTROLES(DATASET)
ELSE
遍历CHILDCONTROLS数组,找出TABLENAME相同的MMDATASET对象
IF IFGet ARecord=TRUE THEN
调用该MMDATASET对象的MAKEMSSQL(6),生成查询数据表的SQL,
ELSE
调用该MMDATASET对象的MAKEMSSQL(5),生成查询数据表的SQL,
END IF
执行SQL,然后调用MMDATASET的SETCONTROLES(DATASET)
END IF
(3)DELETEDATA//对多条需要删除的记录
方法算法:
IF MMID!=0 THEN//存在主表记录
IF TABLENAME=””THEN//调用其MAKEMSSQL(4),//并执行Delete SQL。
ELSE//找到表名为TABLENAME的对象,调用其//MAKEMSSQL(4),执行Delete SQL。
END IF
ELSEIF MMID=0 THEN//不存在主表记录
IF TABLENAME<>””THEN//找到表名为TABLENAME的对//象,调用其MAKEMSSQL(4),执行Delete SQL
END IF
END IF
(4)GETDJBH(ADJID)AS STRING
//生成单据编号,并返回
方法算法:
开始遍历CHILDCONTROLS
IF CHILDCONTROL.ISMAINTABLE=TRUE THEN
RETURN Exe SQL(DJ_AUTOBH(ADJID,CHILDCONTROL.DJBHHEADER))
END IF
结束遍历
5 结语
文中对ASP.NET平台、控件开发相关技术进行了资料收集与讨论,认为开发一套通用的数据表操作控件是具有现实意义与商业价值的,提出利用可视化开发工具设计并开发出一套ASP.NET平台上运行的控件,该套控件运行情况良好,极大地降低了软件系统的开发和维护的工作量,并且充分地保证软件系统的质量。
参考文献
[1]吴冰,黄文达.ASP.NET服务器控件开发.计算机与现代化,2008,(4),125-126.
[2]郑健.庖丁解牛:纵向切入ASP.NET3.5控件和组件开发技术[M].电子工业出版社,2009.
基于VBA的控件类设计与应用 篇4
用VBA设计程序时,插入用户窗体,在窗体上添加同类型的控件,这些控件不经特殊处理是不能有相同的事件过程,有10个控件,则需要设计10个事件过程,有100个控件,则需要设计100个过程;如果这些控件有相同或相似的事件过程体,一个过程的个别地方修改,其它相同的事件过程不能自动修改,不能一改多改,这样设计程序效率较低,而且也不符合算法设计的核心(用循环、递归实现算法)[1]。
例0.1有命令按钮名为cmd1和cmd2,它们的标题分别是“单击命令按钮1”和“单击命令按钮2”,单击它们显示相应标题,则需两个事件过程:
如果类似命令按钮较多,设计起来是比较麻烦的。解决的方法有控件类化和集合化,由于面向对象程序设计采用类,我们这里主要讨论同类控件的类化方法和应用。
1 控件类设计方法
类是将相似对象的相同特征抽象出来,如属性和操作,而对象是这个类的实例,类也可理解为对象模板[2,3,4,5,6]。经实践发现,同类控件可抽象的特征有控件名、序号和事件过程等,VBA中类代码保存在类模块、窗体模块等中。
在例0.1中,类抽象如下表
进入VBE,插入类模块cbC,输入类模块代码:
插入窗体frmUser,添加两个命令按钮(控件名为cmd1、cmd2,标题为“单击命令按钮1”和“单击命令按钮2”),输入窗体模块代码:
属性初始化采用间接方法。
结果为
2 控件连动设计
案例2.1窗体上有四个复选按钮,每次单击只能选中其中一个,同时用一个标签的背景色变为红色表示此操作的结果。
单击chk1、chk2、chk3、chk4中之一,其中只有一个被选中,同时标签lb1背景色变为红色。
进入VBE,插入类模块chkC,输入类模块代码:
插入窗体frms,添加如表2中的其它控件,输入窗体模块代码:
属性初始化采用了直接方法。
运行结果为:
3 结论
通过控件类化使同类控件相同的事件过程集成为一个,从而可对多个控件循环处理,实现了控件组的连动,体现了算法设计的核心,提高了代码的可读性和可维护性。这样做的意义在于,为基于VBA的Word试题模板的设计打下基础。Word试题模板是绿色软件,不需安装,在局域网中进行简单设置,可实现多人、简便的考试。
摘要:在设计基于VBA的Word试题模板时,发现在VBE环境下无控件数组,使得同类控件只能有分开的不同的事件过程,导致编程效率低。本文通过类设计实现同类控件具有相同的事件过程。在控件类的设计过程中,从类的概念和实践出发,得出控件可类化的一些属性和事件过程,对类属性的初始化采用了直接和间接的两种方法,给出了利用复选按钮进行单项选择的关键技术代码。
关键词:控件类,控件可类化的特征,属性初始化方法
参考文献
[1]吕国英,任瑞征.算法设计与应用[M].北京:清华大学出版社,2008.
[2]吴晓琴.浅析面向对象程序设计特点[J].安徽大学学报(自然科学版),2002,26(3):33-37.
[3]郑向伟,李刚,张家重.面向对象和结构程序设计的分析与比较[J].山东师大学报(自然科学版),1997,12(1):26-29.
[4]陈其安,邱林.面向对象程序设计的方法和实践[J].重庆工学院学报,14(5):78-83.
[5]邹岚,葛艳玲,朱峰.Visual Basic程序设计实训教程[M].北京:科学出版社,2005.
控件设计 篇5
关键词:VB6.0,Winsock,UDP,TCP/IP,文件服务器
文件共享是文件服务器的基本功能, 在局域网中利用windows自带的共享功能可以方便的实现这一功能, 但其安全问题更加致命。很多局域网特别是连接到互联网的局域网都尽量避免开启windows自带的文件共享功能。因此在很多局域网系统中需要重新开发文件服务程序。
通过VB6.0利用winsock控件编写网络程序不需调用底层api, 能快速搭建自己的网络应用程序。而服务器程序最重要一点是同时处理同一类事物, 如文件服务器可能同时要与2个以上的用户传送文件数据, 在windows机器上多线程是个很好的处理手段。不过直到VB6.0仍没有能支持多线程开发。因此为了使自己的VB程序能够实现多线程将是一件十分痛苦的事情, 且程序稳定性差。为了实现同时与众多客户端通信, 笔者参阅众多例程, 终于找到一个简单稳定的解决方法, 下面详细介绍之。
1、Winsock控件
Winsock控件采用的是客户机/服务器模式 (Client/Server, 简称C/S) 。此模型包括客户机和服务器应用程序。客户应用程序向服务器应用程序提出请求服务, 服务器程序侦听到了客户的请求后对客户的请求作出适当的响应, 即对客户提供服务。
1.1 服务器程序的开发模式
(1) 服务器程序要先设置侦听端口, 即LocalPort属性。该值可设为其它程序没用过的四位整数。 (2) 将服务器设置成侦听状态, 即用Listen方法侦听, 使服务器始终处于等待客户连接请求的状态。 (3) 当客户机程序发出连接请求后, 将触发服务器程序的ConnetionRequest事件, 该事件得到RequestID参数。 (4) 服务器程序接受客户机程序RequestID请求后, 服务器程序就可以使用SendData方法向客户机发送数据了。 (5) 当服务器程序接收到数据时, 会产生DataArrival事件。在该事件中可以使用GetData方法接收数据。
1.2 客户机程序的开发模式
(1) 客户程序要先设置RemoteHost属性, 用来指向服务器的主机名或IP地址。 (2) 设置Remoteport属性, 用来指向服务器程序的侦听端口号。 (3) 服务器接受了上述连接请求后, 客户机程序将产生Connect事件。在该事件中编写“与服务器连接”的程序。 (4) 连接成功后, 就可用SendData方法向服务器发送数据了。 (5) 当客户机程序接收到数据时, 会产生DataArrival事件, 在该事件中编写程序, 用GetData方法接收数据。
1.3 Winsock控件采用的协议
Winsock控件采用TCP/IP或UDP协议进行通信。协议是指通信双方约定的通信规则, 即通信所使用的语言。TCP/IP协议用于传送容量大、安全性高的数据文件。设计时需要将Winsock控件的Protocol属性设置为sckTCPProtocol。UDP (用户数据文报协议) 适用于需要分别与很多下属通信、数据量小的情况。设计时需要将Winsock控件的Protocol属性设置为sckUDPProtocol。
2、文件服务通信协议设计
此处开发的文件服务器提供文件下载、文件上传、文件删除三个基本功能, 客户端对文件的操作权限和操作记录通过建立数据库管理。在服务器上一直运行一个主程序, 主程序 (main.exe) 负责在UDP协议下监听客户端的连接请求, 根据请求内容shell一个文件服务程序 (fileSV.exe) ;之后fileSV.exe与客户端采用TCP/IP协议反向连接;连接成功后由fileSV.exe为客户端提供文件服务。UDP协议不需面向连接, main.exe就可以实现与众多客户端通信;fileSV.exe采用面向连接的TCP/IP协议, 确保文件传输的安全性和大容量传输。客户端与服务器连接过程设计如图1。
服务器的fileSV.exe有2个winsock控件, winsock_info负责传送文件信息、各种文件操作协议;winsock_send负责传送文件数据。客户端的winsock1控件的用途与服务器的winsock_info相同, winsock2负责用UDP协议向服务器发送连接数据, winsock3与服务器的winsock_send相同。
客户端的winscok2用UDP协议向服务器发送的数据为字符型数据, 格式为“客户机IP:winsock1监听端口”, 如发送数据为“192.168.156.2:5034”。main.exe获得这个数据后采用“shell app.path&fileSV.exe 192.168.156.2:5034”这句程序运行一个fileSV.exe以实现与客户端的连接。
winsock_info主要传送操作信息, 操作信息定义为字符型数据, 格式为“AAA&内容”, 其中AAA为操作符, 内容为操作符的扩充。操作符定义如表1。如向客户端发送winsock_send的监听端口 (2594) , 发送内容为:“PPP2594”。
fileSV.exe与客户段连接成功后, 客户端上传文件的操作流程为: (1) 客户端winsock 1发送“SF N&文件路径”如“SFN123456test.dat”; (2) fileSV.exe的winsock_info收到操作请求, 先检查文件是否存在, 如文件存在向客户端winsock1发送“FIN&文件大小”, 文件不存在向客户端winsock1发送“FNO&文件路径”; (3) 客户端winsock1收到“FIN&文件大小”可以提示覆盖文件或者取消传送;取消直接发送“END”结束会话;收到“FNO&文件路径”将直接上传。上传文件将向fileSV.exe发送“SFS”, 表示准备传送文件开始; (4) fileSV.exe收到“SFS”后打开文件写操作, 并向客户段发送“SOK”; (5) 客户端winsock1收到“SOK”后启动上传文件过程, 由winsock 3向fileSV.exe发送文件; (6) fileSV.exe的winsock_send负责接收数据然后将数据写到文件; (7) 文件发送结束后客户端winsock1发送“SFE”; (8) fileSV.exe收到“SFE”后, 关闭写文件, 向客户端winsock1发送“END”并退出程序; (9) 客户端接收到“END”后退出程序。
客户端下载文件的操作流程为: (1) 客户端winsock1发送“GFN&文件路径”; (2) fileSV.exe的winsock_info收到操作请求, 先检查文件是否存在, 如文件存在向客户端winsock1发送“FIN&文件大小”, 文件不存在向客户端winsock1发送“FNO&文件路径”; (3) 客户端winsock1收到“FNO&文件路径”可以提示文件不存在, 直接发送“END”结束会话, 收到“FIN&文件大小”将打开写文件操作, 然后向fileSV.exe发送“SFS”, 表示准备传送文件开始; (4) fileSV.exe收到“SFS”后打开文件, 并通过winsock_send连接向客户发送文件; (5) 客户端winsock3负责接收数据然后将数据写到文件; (6) 文件发送结束后, fileSV.exe通过winsock_info向客户端winsock1发送“SFE”; (7) 客户端收到“SFE”后, 关闭写文件, 向fileSV.exe发送“END”并退出程序; (8) fileSV.exe接收到“END”后退出程序。
客户端删除文件的操作流程为: (1) 客户端winsock1发送“DFN&文件路径”; (2) fileSV.exe的winsock_info收到操作请求, 先检查文件是否存在, 如文件存在向客户端winsock1发送“FIN&文件大小”, 文件不存在向客户端winsock1发送“FNO&文件路径”; (3) 客户端winsock1收到“FNO&文件路径”可以提示文件不存在, 直接发送“END”结束会话, 收到“FIN&文件大小”, 然后向fileSV.exe发送“DEL”, 表示确认删除文件; (4) fileSV.exe收到“DEL”后删除文件, 删除成功向客户段发送“DSE”, 删除失败向客户段发送“DFA”; (5) 客户端收到“DSE”或“DFA”后, 做相应提示, 向fileSV.exe发送“END”并退出程序; (6) fileSV.exe接收到“END”后退出程序。
3、程序实例设计
3.1 main.exe设计
3.1.1 程序界面设计
(1) 创建一个“标准的EXE”工程。选中“工程”菜单的“部件”选项, 在控件中找到Microsoft Winsock Control并将其选中。若没找到, 可找到安装盘并安装其中的Mswinsck.cab压缩包。
(2) 在窗体上添加Winsock控件, 名称为Wck_Server。
3.1.2 代码设计
在代码设计窗口中编辑相应的事件过程中设计代码, 并成功编译程序并命名为main.exe。
3.2 fileSV.exe设计
3.2.1 程序界面设计
(1) 创建一个“标准的EXE”工程。Form.visible设置为faulse
(2) 在窗体上添加两个Winsock控件, 名称分别为WckInfo和WckSend
(3) 在窗体上添加三个timer控件, 名称分别为timer1、timer2、timer3
Timer1定时10s, 程序运行开始10s后如果服务器连接客户端没有成功则fileSV.exe退出;Timer2定时10s, WckInfo连接成功10s后如果客户端与服务器WckSend没有连接则fileSV.exe退出。其代码限于篇幅不详细给出。
3.2.2 代码设计
在代码设计窗口中编辑相应的事件过程中设计代码, 如检查文件是否存在、开始发送文件、开始接收文件、删除文件的处理代码, 这些代码限于篇幅没有给出, 如有需要可以联系笔者。然后成功编译程序并命名为fileSV.exe。将fileSV.exe与main.exe至于同一目录, 完成服务器端程序设计。
客户端程序设计可以参考fileSV.exe源程序和文件服务器协议设计, 客户段至少需要3个winsock控件, 可按需添加其它控件和功能代码。
4、结语
笔者开发的程序运行在100台计算机左右的局域网络, 程序运行稳定, fileSV.exe进程最高时同时有50个, 服务器依然稳定运行, 数据传送高速可靠。满足了中小局域网文件共享的安全性、可控性要求。通过本文的这种思路可利用VB6.0开发出更多中小型服务器应用。
本文技术要点总结如下: (1) 使用Winsock.bind方法时, Winsock.LocalPort要先设置, bind方法使用后, Listen方法不能再使用。 (2) 使用Listen方法时, Winsock的LocalPort不要设置, 由windows系统分配端口, 避免设置的端口被其它程序使用而出错。 (3) 通过winsock一次传送的数据不能太大, 大文件传送需要分成多部分传送。 (4) 把服务器功能模块化, 由独立程序去完成, 主程序只负责调用, 程序间通信可采用command命令、注册表或者共享文件等方式, 这样可避免VB6.0单线程的烦恼。
参考文献
[1]刘世峰.Visual Basic 6.0程序设计教程 (第一版) [M].北京:中央广播电视大学出版社, 2004.
[2]杨聪.Visual Basic 6.0程序设计案例教程[M].北京:中国人民大学出版社, 2009.1.
[3]安剑, 孙秀梅.Visual Basic数据库系统开发自学手册.北京:人民邮电出版社, 2008.3.
控件设计 篇6
信息管理系统中特别是ERP系统中的大多数数据是分层的,例如单位的人员管理从上到下是分级组织,产品的装配和结构也是分层分级组织的。为了形象而生动地显示数据,方便用户对资源数据的访问控制操作,往往采用无限伸展树型结构形式。在Asp.netWeb应用时,利用TreeView显示静态的数据树很简单,要想动态显示无限数据树时,TreeView就必须和数据库结合起来,将数据树中的数据按一定的规律存放在数据库中,然后TreeView用通用代码访问数据库中相应的表后显示出来。当树状数据改变时,只需更新存放该数据的表即可,不同类型的数据存放在不同的表中,例如:部门人员信息表、产品信息表(不同产品存放在不同表)等。本文将根据笔者在开发管理系统的实践经验,向读者介绍如何利用微软提供的TreeView子控件和递归算法实现动态获取数据树的用户控件。
1 环境配置
本WEB例程使用ASP.NET技术实现,后台数据库拟采用SQLServer2000系统,应安装:
(1)WindowsXP Professional+IIS6.0;
(2)Microsoft.NET Frameworks SDK3.5;
(3)SQLEXPRESS Server2005。
2 数据库表设计(通用数据库表的结构设计)
表名:DepartMent
3 代码编写
3.1 通用访问数据库代码
3.2 数据树用户控件代码如下
3.3 代码分析
数据树用户控件可读写的属性TableName(表名),IdColumn(id号),NameColumn(结点名),ParentIdColumn(上一级id号),RootIDs(根结点的id,可以指定不止一个根结点),RootNames(根结点的Name,可以指定不止一个根结点).属性的对应关系为TableName与数据库中的表名相应,IdColumn与数据库中的表中的字段id相应,NameColumn与数据库中的表中的字段Name相应,Parent Id Column与数据库中的表中字段ParentId相应,为了与外界通信定义了一个事件CodeSelected,参数为selectedId(选择数据项的id通过属性Value获得),方法private void tree(TreeNode parentNode,int ID)是生成数据树的递归程序,当发生CodeSelected事件时必须重绘(利用ReDraw())。属性Path返回所选节点中文路径名。
4 用户控件使用
(1)在包含ASP.NET网页中,创建一个@Register指令,其中包括:TagPrefix属性将前缀与用户控件相关联。此前缀将包括在用户控件元素的开始标记中。TagName属性将名称与用户控件相关联。此名称将包括在用户控件元素的开始标记中。Src属性定义包括的用户控件文件的虚拟路径,Src属性值既可以是相对路径,也可以是从应用程序的根目录到用户控件源文件的绝对路径。为灵活使用,建议使用相对路径。代字号(~)表示应用程序的根目录。用户控件不能位于App_Code目录中。示例如下:
(2)在网页主体中,请在form元素内部声明用户控件元素。
(3)(可选)如果用户控件公开公共属性,请以声明方式设置这些属性。
4 功能测试
打开浏览器通过网址访问该WEB测试页,结果如图1所示。
用鼠标可以展开或折叠目录树。当选某一节点时,可返回该节点的标识及对应部门、节点中文路径等信息,从而可供程序员使用。
总之,ASP.NET提供了一个基于WEB服务器端的功能强大、完善的编程环境。如果将上述代码连接到数据库的部分改成连接到服务器的文件系统,则可实现以目录树方式远程访问服务器文件系统的目的用户控件,使用时只要设置根目录就能像资源管理器一样使用。
参考文献
[1]Microsoft.C#程序设计语言[M].北京;高等教育出版社,2003.
[2]Scott Worley著.ASP.NET技术内幕.王文龙,刘湘宁译.北京:人民邮电出版社,2002.
控件设计 篇7
1 自定义控件——导航条的设计
1.1 总体结构
文中的导航条控件Navigate Tool Bar, 底层父控件是继承.NET自带的Panel控件, 相当于整个控件的容器, 可以存放多个主按钮, 每个主按钮下可以添加多个子按钮。结构如图1所示。其中, 主按钮在本文中称NaviPanel, 是继承自Panel的自定义控件, 有两部分组成:按钮区域和工作区域, 按钮区域是采用GDI+绘图[2]产生, 能实现和按钮同样的功能, 工作区域相当于子按钮的容器, 可以存放多个子按钮;子按钮控件是继承Button的自定义控件, 增加了一些原有控件所没有的属性。
1.2 自定义设计器
设计器在协助安排和配置组件、设计模式中为组件启用正确的行为方面起到了重要的作用。一些控件可能在设计模式中需要可视化提示, 以使配置更加容易, 如果不用设计器, 只能在运行时才能对组件启用正确的行为, 达不到理想效果。.NET框架2.0提供了一个强大而灵活的设计器主机基础架构, 具备了为处于设计模式中某种类型的组件提供自定义行为的功能。设计器提供逻辑的类, 该逻辑可以在设计时调整类型的外观或行为, 实现 System.ComponentModel.Design.IDesigner 接口, 通过 DesignerAttribute 与类型或类型成员关联。当创建了与设计器关联的组件或控件后, 设计器即可在设计时执行任务。
导航条的主要组成部分:主按钮和子按钮都是基于自定义的设计器来设计的。这里就以主按钮NaviPanel为例介绍子控件的设计。NaviPanel的类结构如图2所示, 作为主按钮的设计器NaviPanelDesigner, 是继承自ParentControlDesigner类, 它为包含子控件的控件设计器提供基类, 可在设计模式下扩展关联组件的行为, 也可在要扩展的控件中添加、移除、选择和排列子控件。例如, ParentControlDesigne类提供空的 IDesignerFilter 接口实现, 可以重写该实现的方法, 从而在设计时调整关联组件的属性 (Attribute) 、属性 (Property) 和事件。
完成主按钮的设计器NaviPanelDesigner之后, 将控件类NaviPanel和设计器关联起来, 实现了主按钮框架的设计, 对于主按钮中包含的数据集ChildButtonCollection将在下面进行详细介绍。
1.3 集合编辑器
所谓集合编辑器[3], 允许创建和编辑集合中的各个成员。在使用“属性”窗口并单击某个集合的属性字段中的按钮时, 所显示的对话框即为集合编辑器对话框。集合编辑器允许用户增加或删除项, 新的项被添加到“成员”列表的底部, 并被赋予一个默认的名称。若要编辑某一特定成员, 可在该列表中选择此成员, 然后使用右侧的“属性”网格进行更改, 可以编辑的特定属性取决于正在编辑的集合。集合编辑器中包含当前已定义的所有成员, 每项旁边的数字指示该项在集合中的位置, 可以对集合中的成员进行重新排序, 即在“成员”列表中选择一项, 然后单击向上或向下箭头将该项移动到需要的位置。在某些情况下, 当前成员的属性包含其他集合。这时, 可以为该集合打开“集合编辑器”对话框的嵌套版本, 如在导航条控件中存在编辑主按钮的集合编辑器, 而每个主按钮又对应一个子按钮的集合编辑器。主按钮的集合编辑器对话框如图3所示。
导航条控件是采用内置 CollectionEditor 用作属性编辑器, 用自定义的Collection数据集类来管理数据。从控件的整体框图, 如图1所示, 导航条可以包括多个主按钮, 而每个主按钮又可以包括多个子按钮, 所以对导航条控件来说有两个数据集类:包含所有主按钮信息的数据集NaviPanelCollection和每个主按钮所对应的子按钮数据集ChildButtonCollection, NaviPanelCollection和ChildButtonCollection都继承自IList、ICollection、IEnumerable接口。子按钮数据集ChildButtonCollection的类结构图, 如图4所示。对主按钮控件来说, 在主按钮控件类NaviPanel中定义一个ChildButtonCollection的属性, 指定此集合类ChildButtonCollection的集合编辑器为CollectionEditor, 即在主按钮中定义为ChildButtonCollection类的属性都会把CollectionEditor作为它的编辑器。
1.4 智能标记面板
智能标记功能使组件和控件能够为用户区分上下文的信息和命令。在Visual Studio 2005中, 可以将智能标记视为设计器谓词的替代技术, 它能够在智能标记面板[4]中显示智能标记项, 也可以在与组件或控件相关的快捷菜单中显示智能标记项, 在控件的生命周期内时钟保持可用。用户通过单击组件的智能标记符号 (◄) , 从智能标记面板中选择一种提供的操作来进行访问。
添加智能标记可以有两种方法:
(1) 直接在控件的设计器中重写Verbs属性, Verbs属性可以获取与设计器相关联的组件所支持的设计器谓词。因此, 只用将要添加的设计器谓词添加到Verbs中, 所返回的谓词将被添加到控件的快捷菜单。当选择其中一个谓词时, 将调用相应的事件处理程序。
(2) 从 DesignerActionList 基类生成一个派生类, 用派生类来填充智能标记面板, 此面板表示类似菜单的用户界面 (UI) 。
在导航条控件中采用的是第两种方法, 具体操作如下: (1) 在派生类重写GetSortedActionItems方法以返回从DesignerActionItem 派生的对象集合。DesignerActionItem为智能面板上的一项, 各项按照其类型显示在面板中, 操作列表的 GetSortedActionItems 方法, 可以实现按照在智能标记面板中显示的顺序返回属性和方法。 (2) 创建派生类后, 采用拉取模型将DesignerActionItem添加到控件, 即将派生类的实例添加到ComponentDesigner 类的 ActionLists 属性上。
2 结束语
自定义控件导航条采用内置 CollectionEditor 用作属性编辑器, 用自定义的Collection数据集类来管理数据, 使数据结构清晰, 便于管理。同时, 增加了智能标记面板选项, 使控件使用起来更直观、方便, 还存在很大的可扩展空间, 增加供用户选择的属性, 以满足不同用户的需求。
摘要:导航条控件的设计采用了内置Collection Editor用作属性编辑器, 用自定义的Collection数据集类组织数据结构, 其特点是数据结构清晰、简单直观、易于实现。导航条控件能有效的添加二级子项目, 增加了原有控件所不具备的属性, 使控件能有效、直观地和用户交互。
关键词:导航条,集合编辑器,数据结构
参考文献
[1]周鸣扬, 赵景亮.精通GDI+编程[M].北京:清华大学出版社, 2004.
[2]怀特.GDI+程序设计:使用C#创建自定义控件[M].杨浩, 张哲峰, 译.北京:清华大学出版社, 2002.
[3]郑健.庖丁解牛:纵向切入ASP.net3.5控件和组件开发技术[M].北京:电子工业出版社, 2009.