Delphi三层开发TClientDataSet的Delta妙用

Delphi三层开发TClientDataSet的Delta妙用
Delphi三层开发TClientDataSet的Delta妙用

Delphi三层开发小技巧:TClientDataSet的Delta妙用

Delphi做三层开发时,很多人都会在客户端放一个TClientDataSet,中间层远程数据模块就对应放一个TDataSetProvider,然后再连起来.其实这种方法很烦琐,而且程序痈肿不甘,不好维护.我们都知道TClientDataSet的Delta属性记录了数据的所有修改,应用它我们就可以方便的实现一个单表更新的通用方法.

首先,在中间层添加一个方法,就叫ApplyUpdates吧.方法定义如下:

function ApplyUpdates(const UpdateTable:String;Delta:Variant;out err:String):Boolean;

参数UpdateTable是指要更新的表名,Delta是指传过来的TClientDataSet的Delta属性,如果更新错误err返回错误的内容.下面实现这个方法,首先在DataModule上放一个Query,Query连上Connection,然后再放一个TDataSetProvider连Query.代码如下:

function TRoDm.ApplyUpdates(const UpdateTable:String;Delta:Variant;out err:String):Boolean;

const sql='select * from %s where 1<>1';

var sqlstr:string;

ErrCount:Integer;

begin

Result:=False;

sqlstr:=Format(sql,[UpdateTable]);

try

Conn.BeginTrans;

Query.Close;

Query.sql.text:=sqlstr;

Query.open;

Provider.ApplyUpdates(Delta,-1,ErrCount);

Result:=ErrCount=0;

if Result then

https://www.360docs.net/doc/78536134.html,mitTrans

else Conn.RollbackTrans;

except

on E:Exception do

begin

Conn.RollbackTrans;

err:=E.Message;

end;

end;

end;

到此,通用的更新方法已经完成了.不过客户端的ClientDataSet还不能查询显示数据,因此,还要写一个查询方法:

function QuerySQL(const sqlstr:string;out Data:Variant;out

err:String):Boolean;

参数sqlstr就是要持行的查询语句,Data返回查询结果,错误时err返回错误消息

QuerySQL实现代码如下:

function TRoDm.QuerySQL(const sqlstr:string;out Data:Variant;out err:String):Boolean;

begin

Result:=False;

try

Query.close;

Query.sql.text:=sqlstr;

Query.sql.Open;

Data:=Provider.Data;

Result:=True;

Except

on E:Exception do

err:=E.Message;

end;

end;

到这里,中间层的代码已经完了,客户端的调用就简单了.比如客户端有个数据模块DM,上面放一个DcomConnection或者SocketConnection,名叫Conn.例如,我们现在要做一个商品管理的功能,在窗体上放一个TClientDataSet叫Cds,放DataSource,DBGrid等,设置好相应的属性.然后在窗体创建(Create事件)时查

询回所有数据,代码如下:

const sql='select * from xxxx';

var Data:Variant;

err:String;

begin

if Dm.Conn.AppServer.QuerySQL(sql,Data,err) then

Cds.Data:=Data

else MessageBox(self.handle,pchar('查询数据出错:'+err),'错误

',MB_OK+MB_ICONERROR);

end;

然后还有"添加","修改","删除"按扭,代码都和我们平时操作一样,比如"添加"按扭的代码:

cds.append;

cds.fieldbyname('xxx').asinteger:=xxx;

//....

cds.post;

修改,删除也这样写.不过现在还有个小问题是,这个表的主键的生成问题,

这里我们不能用自增主键,要自己自己生成主键,这样你还得在中间层写一个中间层生成主键的方法,在"增加"按扭时生调用生成主键,然后再上面的操作.这里不再多说.

增删改完后,这时的数据还在客户端的内存里,想保存到远程的中间层服务器就要用到我们刚才的方法了,下面就是"保存"按扭下的代码:

var err:string;

begin

if cds.ChangeCount=0 then exit;//数据没改变就不用提交了

if Dm.Conn.AppServer.ApplyUpdates('xxx',cds.Delta,err) then//xxx

就是表名了

begin

MessageBox(self.handle,'保存成功!','提示

',MB_OK+MB_ICONINFORMATION);

cds.MergeChangeLog;//合并所有改变的数据

end else MessageBox(self.handle,pchar('保存出错:'+err),'错误

',MB_OK+MB_ICONERROR);

end;

到此,这篇文章也讲完了.用这个方法,那些单表的基础数据更新还可以写成一个祖先类,只要加一个取得更新表名的虚方法,比如:function

TableName:string;virtual;然后其后代只要override这个方法,返回各自的表名,其他的一句代码都不用写.

scktsrvr.exe是一个NT的服务程序,你用scktsrvr.exe -install安装之后,每次系统启动,它都会自动运行的。如果你的客户端用了socketconnection,每次连接应用服务器的时候,都需要通过scktsrvr.exe才能访问到你的应用服务器.

scktsrvr.exe -uninstall 即可卸载

51单片机集成开发系统MedWin

51单片机集成开发系统MedWin 一、安装Medwin 直接从万利公司网站上下载的MedWin不含汇编/编译/连接器,也不包含c51的函数和连结库。为此,我站将medwin 和其必须的附件一同打包,重新生成解压式安装文件MedWinSetup.exe。该文件在配套光盘中。 点击MedWinSetup.exe,即弹出安装对话框,请不要改变安装路径!点击“安装”程序会自动完成全部安装。 安装完后,桌面上会生成一个图标。点击该图标就开始启动Medwin开发系统,启动后在第一个弹出的对话框中选择“模拟仿真”: 接下来的设置仅在第一次启动时所必要的设置:

在“工作向导”对话框中选择“新建或打开一个文件”。 在打开文件对话框中可根据你的情况处理;若打开现有文件,就直接点击现有文件后再点击“打开”按钮;若你新建一个文件,请在“文件名(N):”框中键入你新文件的名字再点击“打开”按钮。需注意的是,新建的汇编程序其扩展名必须是ASM,c51程序扩展名必须是C。下面是已打开的MedWin环境快照。 在有些时候,可能会出现环境参数设置,请依下面方法设置。

工作目录我们设到C:\C51\Mypro下。 “编译/汇编/连接配置”应与下面设置一致。 二、MedWin的简单使用:

启动medwin,新建一个文件后就出现编辑窗,我们在就可以在这个窗中编写汇编或c原程序。 当编写完成后,应先保存。再按下图步骤产生烧写单片机用的hex文件。

先在工具栏中按“”按钮,主窗体下面会出现汇编或编译过程提示,若错误=0,就编译或汇编成功;若有错误,请以依提示逐个排除错误后再按“”按钮汇编或编译,直至错误=0,编译或汇编成功。 最后从菜单中点击“项目管理”下的“输出 Intel HEX 文件 (H)...”,在c:\c51\Mypro下就生成与原程序同名的hex文件。 下面我们用流水灯程序直接做一遍 将光盘中McuCai\liushun\的liu1.asm复制到c:\c51\Mypro目录中,取掉其只读属性。启动Medwin,打开 c:\c51\Mypro\liu1.asm 。 编辑窗中就是用汇编语言编写的流水灯程序。现在我们不要管他是什么意思,按下面步骤将这些汇编“符号”生成单片机需要的代码就行啦。 第一步,点击工具按钮“”生成Medwin调试代码;第二步,从菜单中点击“项目管理”下的“输出 Intel Hex 文件 (H)...”,

WebEx Recorder使用说明

WebEx Recorder:性能最好的录屏软件 你在寻找好用的录屏软件吗?商用级品质的WebEx Recorder就是一款优秀的录屏软件。WebEx Recorder可以录制全屏或指定窗口,可以设定是否包含声音,生成的文件体积极小且极清晰,录制过程占用资源很少。WebEx的最大优点是性能出众。WebEx 软件并不是个人开发或面向个人的小软件,而是完整的商业解决方案中包括的一款小工具。因此,它在效率和稳定性方面非常出色,称得上是善用佳软见过的录屏软件(包括几款共享软件)中性能最好的一款。例如,用WebEx Recorder全屏带声音录制1小时,生成的文件约25MB,且计算机仍工作流畅,无任何延缓。再如,包括微软、SAP在内的很多大公司,网络讲座经常采用WebEx平台。再如,有些录屏软件,时间太长的话会占用资源太大而失去响应,但WebEx不存在此情况。 1. WebEx Recorder 版权说明 WebEx Recorder不是免费软件,也不是共享软件,而是商业套件中的一个小工具。尽管从技术来讲,可以到主页下载,可以无限期应用,无任何注册提示或限制。但软件许可协议中规定:3.1 You may not: …… iii) utilize the Software for any purpose other than participation in a WebEx meeting or use of the WebEx services。 2. 下载安装WebEx Recorder 在官方下载 WebEx recorder v2.4,体积约 4271KB,安装后约 7MB。WebEx 安装后有三个快捷方式,包括 player、recorder、editor。但这并不意味着有3个独立程序:所谓的播放、录制、编辑其实对应同一个主程序,只是运行参数不同: ”D:\program files\WebEx\atauthor.exe” -PLAYER ”D:\program files\WebEx\atauthor.exe” ”D:\program files\WebEx\atauthor.exe”–EDITOR

DELPHI中如何调用API,可举例说明

DELPHI中如何调用API,可举例说明 第一部分Delphi知识1. 如果一个元件希望放到IDE的元件面板上,它必须从________类派生,如果一个元件能作为其它元件的容器,它必须从_____________类派生,如果一个元件在运行时可见,它必须从___________________类派生(A)TGraphicControl (B)TWinContr 1、rtl70.bpl是什么?有什么用? 2、delphi的Package相对dll有什么优点? 3、以下的记录(结构)变量在内存占多少字节?type a = packed record v1: Byte; v2: Word; v3: string[16]; v4: Double; v5: string; v6: TForm; end; 4、以下的写法是否正确?type a 1.您为什么选择软件开发这个行业?(30字左右简写); 2.如果有您解决不了的软件问题您会采取什么样的解决措施; 3.a.请您写出Object Pascal所支持的数据类型;b.请您写出Shl、Shr、Xor、Not 的数学表示法; 4.请您写出VCL结构层次(以TObject开始,最少五层);5 二.是非题(共20道)1.从主菜单上选择Project|Syntax Check 菜单选项,Delphi将编译从上次编译后有改动的任何单元,并报出遇到的错误。()2.Delphi的VCL对象有些是指针,从堆栈中分配空间,有些则不是。()3.粘贴时,如果作为容器的组件已被选择,

剪贴 一.选择题(共40道)1.用户开发程序时需要经常在窗体和编辑器窗口之间来回切换,可使用快捷键()。A、F12和F11 B、F12和F13 C、F12和Ctrl+F12 D、F12和Alt+F12 E、F12和Shift+F12 2.某函数如下:Function check(n,k:Integer):Integer; Var m:Integer; Beg 编程语言:delphi7.0或Vc++6.0 时间:4小时内环境:可参考帮助文档,但不能上网查资料1、编程查找指定目录下所有EXE 文件,并将其全路径存入Result.txt中,要求用递归。2、采用SOCKET(可用SOCKET API或delphi Socket控件)实现点对点传输大文件,要求不能掉

DELPHI Variant变量的使用技巧

DELPHI Variant变量的使用技巧。。。。。。 delphi 为了完全支持OLE,32位Delphi 增加了Variant 数据类型,本节将从宏观角度来分析这种数据类型。实际上,Variant类型对Pascal语言有普遍而深入的影响,Delphi 控件库中与OLE 无关的地方也使用到这种类型。 Variant变量没有类型 一般说来,你可以用Variant 变量存储任何数据类型,对它执行各种操作和类型转换。需要注意的是:这违反了Pascal 语言的一贯原则,有悖于良好的编程习惯。variant 变量的类型检查和计算在运行期间才进行,编译器不会提示代码中的潜在错误,这些错误在进一步测试中才能发现。总之,你可以认为包含variant变量的代码是解释性代码,正如解释性代码一样,许多操作直到执行时才能知道,这对代码运行速度会有很大的影响。 上面对Variant 类型的使用提出了警告,现在来看看Variant 类型究竟能干什么。基本上说,如果声明了一个variant 变量: var V: Variant; 你就可以把各种不同类型的值赋给它: V := 10; V := 'Hello, World'; V := 45.55; 一旦得到一个variant 值,你可以把它拷贝给任何兼容或不兼容的数据类型。如果你把值赋给不兼容的数据类型,Delphi 会力尽所能进行转换,无法转换则颁布一个运行时间错误。实际上,variant变量中不仅包含了数据还包含有类型信息,并允许一系列运行时间操作,这些操作很方便,但运行速度慢且安全性差。 见例VariTest,它是上面代码的扩展。窗体上有三个编辑框,一对按钮,第一个按钮的OnClick 事件代码如下: procedure TForm1.Button1Click(Sender: TObject); var V: Variant; begin V := 10; Edit1.Text := V; V := 'Hello, World';

delphi海康

type //HCNetSDK头文件类型声明Delphi改写 //基本数据类型声明 DWORD=LongWord; //WORD:Word; USHORT=Word; LONG=Longint; //BYTE=char ; //#define BOOL int UINT=Longword; LPVOID=Pointer; HANDLE=Pointer; LPDWORD=^LongWord; //typedef unsigned long long UINT64; //NET_DVR_Login_V30()参数结构 type LPNET_DVR_DEVICEINFO_V30=^NET_DVR_DEVICEINFO_V30; NET_DVR_DEVICEINFO_V30=Record sSerialNumber:array [0..SERIALNO_LEN-1] of BYTE ; //序列号 byAlarmInPortNum:BYTE ; //报警输入个数 byAlarmOutPortNum:BYTE ; //报警输出个数 byDiskNum:BYTE ; //硬盘个数 byDVRType:BYTE ; //设备类型, 1:DVR 2:ATM DVR 3:DVS ...... byChanNum:BYTE ; //模拟通道个数 byStartChan:BYTE ; //起始通道号,例如DVS-1,DVR - 1 byAudioChanNum:BYTE ; //语音通道数 byIPChanNum:BYTE ; //最大数字通道个数 byZeroChanNum:BYTE ; //零通道编码个数 //2010-01-16 byMainProto:BYTE ; //主码流传输协议类型 0-private, 1-rtsp bySubProto:BYTE ; //子码流传输协议类型0-private, 1-rtsp bySupport:BYTE ; //能力,位与结果为0表示不支持,1表示支持, //bySupport & 0x1, 表示是否支持智能搜索 //bySupport & 0x2, 表示是否支持备份 //bySupport & 0x4, 表示是否支持压缩参数能力获取 //bySupport & 0x8, 表示是否支持多网卡 //bySupport & 0x10, 表示支持远程SADP //bySupport & 0x20, 表示支持Raid卡功能 //bySupport & 0x40, 表示支持IPSAN 目录查找 //bySupport & 0x80, 表示支持rtp over rtsp bySupport1:BYTE ; // 能力集扩充,位与结果为0表示不支持,1表示支持 //bySupport1 & 0x1, 表示是否支持snmp v30 //bySupport1 & 0x2, 支持区分回放和下载 byRes1:BYTE ;

单片机开发与仿真软件keilc51的使用

单片机开发与仿真软件Keil C51的使用 一、Keil C51 操作入门 Keil C51 简介 Keil C51 是德国知名软件公司Keil(现已并入ARM 公司)开发的基于8051 内核的微控制器软件开发平台,是目前开发8051 内核单片机的主流工具。Keil 51支持汇编语言、C语言等各种开发语言。其中,uVision2集成开发环境包含项目管理、源代码编辑和强大的程序调试环境。uVision2调试器是一个强大的全特性调试器,允许用户在PC机上完全模拟目标程序、指令集和片内外围功能。 实验所用的是Keil C51 评估版。 Keil C51 的启动 双击桌面上的“Keil uVision2”图标,启动Keil C51程序,启动界面如图1所示。 图1 Keil C51的启动界面 建立第1 个Keil C51 程序 Keil C51 是一个功能很强大的软件,但是使用起来并不复杂。现在就通过建立一个简单的LED(发光二极管)闪烁发光的实例来初步掌握Keil C51的基本用法。硬件电路参见图2,单片机I/O 输出低电平可点亮LED。 图2 LED 闪烁发光电路 ●新建工程。执行Keil C51 软件的菜单“Project | N ew Project…”,弹出一个名 为“Create New Project”的对话框。先选择一个合适的文件夹准备来存放工程文件,比如“E:\Project\LedFlash”,其中“LedFlash”是新建的文件夹。建议:今后每新建一个工程都要在适当的磁盘位置新建一个文件夹用来保存工程文件,以方便管理,并养成良好的习惯。最后,为工程取名为“LedFlash”,并保存。参见图3。 图3 新建Keil C51 工程 ●选择CPU。紧接着,Keil C51 提示选择CPU 器件。8051 内核单片机最早是由鼎鼎 大名的Intel 公司发明的,后来其他厂商如Philips 、Atmel 、Winbond 等先后推出其兼容产品,并在8051 的基础上扩展了许多增强功能。在这里可以选择Philips 的第1 个器件“80/87C51”,该器件与Intel 的8051 完全兼容。参见图 4 。

Delphi文件操作

Delphi文件操作 变量的数据保存于内存中,随程序运行的结束而结束,若要使程序下次运行时能重复使用或给其他程序员使用,必须保存在文件中,Delphi存取文件的方式有4种,即传统的PASCAL方式、windows API文件句柄方式、VCL文件流方式、使用类方法方式。使用类方法方式比较简单,其他三种方式一般的步骤为: (1) 声明文件类型变量; (2) 给文件类型变量指定文件名; (3) 通过文件类型变量打开并且读写文件,必要时进行文件定位; (4) 关闭文件。 1、PASCAL方式访问文件 文件是由相同数据类型的数据元素组成的序列,文件可以分为三种类型:文本文件,类型文件,无类型文件。文本文件中每个数据元素就是一个字符,占有一个字节,并以回车换行符(#13#10)表示每行的结束;类型文件中每个数据元素的数据类型可以是整数、实型记录型等;无类型文件中每个数据元素是一个字节的二进制数。 文件和数组在形式上有些类似,但实质上有诸多不同,主要表现为以下三个方面:(1)数组的元素个数一般是固定的,而文件的长度一般是不定的、随即的; (2)数组元素总是放于内存中,而文件往往存于外存中; (3)数组以“数组名[下标]”的形式访问数组中的任意一个元素,而文件则需要通过文件变量来访问。 1)类型文件 例一、Button1按钮将记录数组XS[0..1]写入文件…Stu.dat?,Button2将…Stu.dat?读到记录变量X1,X2,然后用消息框输出。 TYPE Stu = Record Xh:integer; Xm:string[20]; END; Procedure TForm1.Buttonclick(Sender:TObject);//记录数组写入文件 Const xs:array[0..1] of Stu=((Xh:=405;xm:='张三'),(xh:=406,xm:='李四')); Var F:File of Stu; begin AssignFile(F,'Stu.dat');//关联文件 ReWrite(F);//打开方式(写) Write(F,xs[0],xs[1]);//将数组写到文件 CloseFile(F); end; procedure TForm1.Button2Click(Sender: TObject); Var F:File of Stu; x1,x2:Stu; begin AssignFile(F,'Stu.dat');

ClientDataSet的用法(转) - CNQCJ 的Delphi 博客 - 博客园

ClientDataSet的用法(转)- CNQCJ 的Delphi 博客- 博 客园 ClientDataSet的用法(转)TClientDataSet控件继承自TDataSet,其数据存储文件格式扩展名为 .cds,是基于文件型数据存储和操作的控件。该控件封装了对数据进行操作处理的接口和功能,而本身并不依赖上述几种数据库驱动程序,基本上能满足单机"瘦"数据库应用程序的需要。 1.TClientDataSet的基本属性和方法介绍 1).FieldDefs: 字段定义列表属性 开发者可通过单击属性编辑器中该属性编辑按钮,或在该控件上单击右键选择弹出菜单中的"Fields Editor"菜单进行字段编辑。设置完此属性后,实际上就相当于定义了表的结构;如果想装入已有的数据表的结构和数据,可通过单击右键选择弹出菜单中的"Assign Local Data"菜单,从弹出对话框中选取当前窗体中已与数据库连接好的数据集控件名 称即可(当前窗体中必须已放置好要套用的数据集控件并打开激活)。 使用注意: 对于自定义的字段名表,该属性编辑完后,该控件仍然无法打开。必须右键单击该控件,选择弹出菜单中的"Create DataSet"菜单,让该控件以上述编辑的字段列表为依据,创

建数据集后,才能够被激活打开和使用。否则,会出现类似"ClientDataSet1: Missing data provider or data packet."的错误(包括在运行期,运行期可调用该控件的CreateDataSet 方法,从而动态定义字段和表)。 2).FileName属性 说明:数据存储文件的名称。 因该控件是基于文件型的数据操作控件,因此,必须指定所操作的数据文件名称(默认扩展名称.cds),从而打开和激活该控件,进而进行数据编辑。 例1:利用此属性打开指定的.cds文件 var Path: string; begin Path := ExtractFilePath(Application.ExeName); //取得可执行文件路径 CDataSet1.FileName := Path + 'test.cds'; CDataSet1.Open; end; 3).CreateDataSet方法 说明:该方法以FieldDefs中的字段名表为结构建立数据集,常用来进行动态定义表。 例2:动态创建一具有姓名和年龄两个字段的数据集。

STC单片机开发系统的建立及使用

实验一:STC单片机开发系统的建立及使用 ——Keil μVision、Proteus软件的使用 ——单片机最小硬件系统搭建【实验目的】: (1)、学习、掌握和使用8051单片机开发软件KeilμVision的使用,在该开发平台的支持下,完成汇编语言程序的编写、调试等开发的过程。 (2)、掌握STC单片机最小硬件系统的原理,并使用面包板搭建STC单片机最小硬件系统;了解LY-51S单片机开发板的功能和使用方法;掌握STC单片机下载软件的使用方法。 (3)、学习、掌握Proteus仿真软件的使用方法,使用该软件搭建8051单片机电路,配合KeilμVision软件生成的代码,学习、调试单片机的硬件系统。 【实验仪器及材料】 PC计算机1台、直流稳压电源1台、LY-51S单片机开发板1块(含STC89C52RC 单片机)、30pF瓷片电容2只、10uF电解电容1只、10K电阻1只、330Ω电阻1只、LED发光二极管1只、12MHz石英晶振1只、面包板1块(含连线若干) 【实验原理/实验基础知识】 单片机最小硬件系统由时钟电路、复位电路、电源电路及单片机构成,任何单片机应用系统均是在最小系统的基础之上扩展而来。 STC单片机属于可以ISP编程的单片机,其ISP功能由单片机机的UART (Universal Asynchronous Receiver Transmitter通用异步收发器)实现,使用PC机的串行通信接口来下载程序。PC机的串行通信接口为RS-232逻辑电平,需要通过一个RS-232到TTL电平的转换芯片才能与单片机连接,也可以通过USB转串行接口芯片来连接单片机。 LY-51S单片机开发板为功能模块独立设计的开发板,板上带有RS232转TTL 电平芯片MAX232、USB转串口芯片PL2303,可以直接连接PC机RS232串口或PC机USB 接口。根据实验需求使用杜邦线连接开发板各功能模块。 【实验内容及步骤】: 1、认识LY-51S单片机开发板各功能部件

arecord 使用

arecord 使用 一.alsa-utils介绍 ALSA是kernel中的一个声音驱动程序.它包括alsa核心和其他声卡的驱动. alsa-utils是alsa的一个工具包,里面包含有声卡测试和音频编辑的工具.二.alsa-utils的安装 1.RPM包方式 Turbolinux 10.5,11版本已经包含有alsa-utils的rpm包,你可以直接安装: # rpm -ivh alsa-utils-xxx.rpm2.源码包方式 下载地址: https://www.360docs.net/doc/78536134.html,/main/index.php/Download

源码包安装方法: # tar zxvf alsa-utils-1.0.6.tar.gz # cd alsa-utils-1.0.6 # ./configure # make install三.alsa-utils工具的使用 alsa-utils包含的工具有: alsactl, aconnect, alsamixer, amidi, amixer, aplay, aplaymidi, arecord, arecordmidi, aseqnet, iecset, speaker-test1.alsactl的使用 alsactl用来对alsa声卡驱动进行一些高级的设置.系统中装有多个声卡,它也可以支持. 有时在音量控制面板无法调整的选项,可以使用alsactl来实现. alsactl可以将指定声卡的驱动程序设置信息保存到配置文件.或从配置文件中恢复指定

声卡的驱动程序的设置信息. alsactl格式: alsactl [options] [store|restore] 选项: -h, --help 打印帮助信息 -f, --file 指定使用的配置文件,默认为/etc/asound.state. Select the configuration file to use. The default is /etc/asound.state -F, --force 与恢复命令一起使用.表示最大限度的恢复设置值.

在DELPHI中如何实现打印功能

在DELPHI中提供了一个PRINTERS程序单元,它说明了一个TPRINTER对象,封装了WINDOWS打印工作和输出打印机之间的接口,并提供常用的属性和方法,其中画布CANVAS是一个非常有用的属性,它代表了当前打印文件的表面,是以图形方式来工作的,整个的打印输出工作仅仅是将你打印的内容输出到TPRINTER的属性CANVAS上,当全部的输出工作完成以后,打印对象(TPRINTER)把CANVAS的属性值送到打印机上去。 下面举例来说明如何通过DELPHI实现文本内容的打印。在DELPHI 中提供了PRINTDIALOG、PRINTERSETUPDIALOG两个控件允许我们进行打印机以及其他影响打印输出的选择,此外最重要的一点是要想实现打印功能必须在编译程序以前将PRINTERS加入到INTERFACE或者IMPLEMENTATION的UESE语句当中,因为PRINTER单元包括ASSIGNPRN和其他控制打印机的过程。 首先在FORM当中加入MEMO、PRINTDIALOG、PRINTERSETUPDIALOG和两个BUTTON控件,两个BUTTON的CAPTION分别为“打印设置”和“打印”。然后编写BUTTON的事件驱动程序(代码在下面),这个简单的例子中只要单击“打印”按钮时便可以在打印机上输出文件0S2.TXT,打印事件的清单如下: implementation

usesprinters; {$R*.DFM} procedureTForm1.BitBtn1Click(Sender:TObject); begin printersetupdialog1.execute;//选择输出的打印机以及其他打印控制选项 end; procedureTForm1.BitBtn2Click(Sender:TObject); var lines:integer; prntext:system.text; //将PRNTEXT声名为一个在SYSTEM程序单元当中定义的文本文件begin ifprintdialog1.executethen assignprn(prntext);//将PRNTEST分配给打印机 rewrite(prntext);//调用REWRITE函数,为输出打开已分配的文件printer.canvas.font:=memo1.font; //把当前MEMO1的字体指定给打印对象的CANVAS的字体属性forlines:=0tomemo1.lines.count-1do

单片机编程软件的基本使用

硬件实验报告 学生:张小强 学号:1252100210 指导老师:莫荣

实验一:单片机开发系统应用初步 ——基本I/O口赋值 1. 内容提要: 1)KEIL C软件对程序进行编译调试及烧录软件的使用方法。 2)单片机基本I/O口的驱动方式、特点等。 3)汇编语句的基本用法;对基本I/O口的赋值方法;程序的具体流程等。 2.实验目的及要求: 1) 课前预习好编程的基本知识。程序的基本概念、*.asm、*.c、*.hex、*.uv2 所表示的文件类型等。 2) 熟练掌握不同数据类型之间的相互转换,不同类型的数据在程序中的表示方 法等。 3)课前弄清楚单片机I/O口的基本驱动方式,理解何谓上拉及下拉方式,单片机驱动电流、灌入电流等概念。 4)复习数码管的相关知识,弄清数码管需显示某个字符应如何对其进行控制等。 ORG 0000H AJMP MAIN MAIN: MOV P0,#0FH JMP MAIN END 4.实验的实施: 1)实验前准备:基础知识的统计学习 A.程序:完成某种任务的计算机代码。 B.文件类型: *.asm:汇编语言编写的程序文件。 *.c: c语言编写的程序文件。 *.hex:机器语言文件,指通过*.asm、*.c等程序编译成功后转换而得到的hex文件。 *.uv2:表示keil c软件的工程文件。 C.对源程序的相关阐释:

ORG 0000H 定义程序起始地址 AJMP MAIN 直接跳到main(主程序) MAIN: MOV P0,#0FH 对p0口赋初值 JMP MAIN 跳转到main END 程序结束 2)通过keil c进行程序编译,生成正确的*.hex机器语言文件: A.打开keil c,建立工程文件: a.在主菜单下右键点击选中project 再点击New Project新建工程文件,弹出下面对话框: b选择保存位置,定义文件名,点击保存,弹出下面对话框

单片机c语言开发sbit使用方法

单片机C语音开发sbit使用方法·· 1.bit和sbit都是C51扩展的变量类型。 bit和int char之类的差不多,只不过char=8位, bit=1位而已。都是变量,编译器在编译过程中分配地址。除非你指定,否则这个地址是随机的。这个地址是整个可寻址空间,RAM+FLASH+扩展空间。bit只有0和1两种值,意义有点像Windows下VC中的BOOL。 sbit是对应可位寻址空间的一个位,可位寻址区:20H~2FH。一旦用了sbi xxx = REGE^6这样的定义,这个sbit量就确定地址了。sbit大部分是用在寄存器中的,方便对寄存器的某位进行操作的。 2.bit位标量 bit位标量是C51编译器的一种扩充数据类型,利用它可定义一个位标量,但不能定义位指针,也不能定义位数组。它的值是一个二进制位,不是0就是1,类似一些高级语言中的Boolean类型中的True和False。 3.sfr特殊功能寄存器 sfr也是一种扩充数据类型,点用一个内存单元,值域为0~255。利用它可以访问51单片机内部的所有特殊功能寄存器。如用sfr P1 = 0x90这一句定P1为P1端口在片内的寄存器,在后面的语句中我们用以用P1 = 255(对P1端口的所有引脚置高电平)之类的语句来操作特殊功能寄存器。 sfr P1 = 0x90; //定义P1 I/O 口,其地址90H sfr 关键定后面是一个要定义的名字,可任意选取,但要符合标识符的命名规则,名字最好有一定的含义如P1 口可以用P1 为名,这样程序会变的好读好多.等号后面必须是常数,不允许有带运算符的表达式,而且该常数必须在特殊功能寄存器的地址范围之内(80H-FFH),具体可查看附录中的相关表. sfr 是定义8 位的特殊功能寄存器而sfr16 则是用来定义16 位特殊功能寄存器, 如8052 的T2 定时器,可以定义为: sfr16 T2 = 0xCC; //这里定义8052 定时器2,地址为T2L=CCH,T2H=CDH

Delphi的EhLib控件的使用说明

EhLib控件的使用说明 一. DBGridEh组件: 1.属性。

2.使用统计栏功能 (1)设置统计栏行数,将DBGridEh.FooterRowCount := 1 (2)设置激活统计功能,将DBGridEh.SumList.Active := True; (3)选择所统计字段的统计方式,如将Columns[n].Footer.ValueType := vtSum; (4) 3.复杂标题. (1)标题行可设为2行以上高度,并可以为多列创建一个共同的父标题行。为实现这个效果,需在各个列标题属性中以“|”分隔父标题和子标题,如办公用品包括代码和名称两部分,具体属性设置如下: usemultititile=true; titlelines=2 DBGridEh.Columns[0].Title.Caption := '办公用品|代码'; DBGridEh.Columns[1].Title.Caption := '办公用品|名称'; (2)标题行显示图片 首先添加一个imagelist组件img1并在其中添加一组bmp,ico格式的图片。然后将DBGridEh的TitleImages设置为img1.最后在需要显示图片的列标题的imageindex中设置需要显示的img1中图片的序号。

4.实现DBGridEh 隔行分色显示 procedure TForm1.DBGridEh1GetCellParams(Sender: TObject; Column: TColumnEh; AFont: TFont; var Background: TColor; State: TGridDrawState); Begin if DBGridEh1.SumList.RecNo mod 2 = 1 then Background := $00FFC4C4 Else Background := $00FFDDDD; end; 5.DBGridEh 在某些条件下某行显示特定颜色 procedure TForm1.DBGridEh1GetCellParams(Sender: TObject; Column: TColumnEh; AFont: TFont; var Background: TColor; State: TGridDrawState); begin //在name 字段值为aaa 的行设置行背景色(ado 设置情况下)if ADOQuery1.FieldByName('name').AsString = 'aaa' then Background := $00FFC4C4 //在xm 字段值为Li ming 的行设置行背景色(bde 设置情况下)else if DBGridEh1.DataSource.DataSet.FieldByName('xm').AsString = 'Li ming' then Background := $00FFC4C4 Else Background := $00FFDDDD; end; 6.在dbgrideh中允许选择多行,如何知道哪些行被选中?是个BOOKMARK类型的属性。 SelectedRows: TBookmarkList procedure TForm1.Button1Click(Sender: TObject); var i, j: Integer; s: string; begin if DBGrid1.SelectedRows.Count>0 then with DBGrid1.DataSource.DataSet do for i:=0 to DBGrid1.SelectedRows.Count-1 do begin GotoBookmark(pointer(DBGrid1.SelectedRows.Items[i])); for j := 0 to FieldCount-1 do begin if (j>0) then s:=s+', '; s:=s+Fields[j].AsString; end; Listbox1.Items.Add(s); s:= '';

Delphi数据集介绍

第六章什么是数据集 Delphi 4中有四种类型的标准数据集构件,分别是TTable、TQuery、TStoredProc和TClientDataSet。这些数据集构件都是从一个共同的基类TDataSet继承下来的,其中,只有TClientDataSet是直接从TDataSet继承下来的,而TTable、TQuery、TStoredProc的直接上级是TDBDataSet,TDBDataSet的上级是TBDEDataSet,TBDEDataSet 的上级才是TDataSet。这几个类之间的继承关系可以用图6.1来表示。 图6.1 数据集的继承关系 TDataSet是所有数据集的抽象基类,它的大部分属性和方法是虚拟的或抽象的。所谓虚拟的方法,是指这些方法可以被派生类重载。所谓抽象的方法,是指这些方法只有声明,没有定义,派生类必须给出定义后才能调用这些方法,不同的派生类可以有不同的定义。 由于TDataSet中包含抽象的方法,您不能直接创建它的实例,否则会引起运行期错误。 如果从功能上划分,TDataSet的属性和方法可以分为这么几大块:打开和关闭数据集、浏览记录、编辑数据、书签管理、控制连接、访问字段、记录缓冲区管理、过滤、事件。6.1 打开和关闭数据集 在对数据集进行任何操作之前,首先要打开数据集。要打开数据集,可以把Active属性设为True,例如: CustTable.Active := True; 也可以调用Open函数,例如:CustQuery.Open; 要关闭数据集,可以把Active属性设为False或者调用Close函数。 6.2 数据集的状态 数据集的状态(State属性)决定了当前能够对数据集进行的操作,例如,当数据集已经关闭,它的状态是dsInactive,此时就不能访问数据集的任何数据。 6.2.1 State属性 State属性是只读的,下面列出了State属性可能的值: .dsInactive数据集已关闭,不能访问它的数据; .dsBrowse数据集已打开,可以浏览数据但不能修改数据; .dsEdit此时为编辑状态,可以修改数据; .dsInsert此时可以插入一条新的记录; .dsSetKey只适用于TTable和TClientDataSet,此时可以设置范围和键值,并且可以调用GotoKey函数; .dsCalcFields正在处理OnCalcFields事件(当字段需要指定一个值的时候促发的事件),此时不能修改非计算字段的值; .dsCurValue内部使用; .dsNewValue内部使用; .dsOldValue内部使用; .dsFilter正在进行过滤操作。 当一个数据集刚刚打开的时候,它的State属性被设为dsBrowse,以后,State属性的值会随着应用程序的操作自动变化。 要使数据集进入dsBrowse、dsEdit、dsInsert或dsSetKey状态,就得调用相应的方法。 例如,要使数据集CustTable进入dsInsert状态,程序示例如下: Procedure TForm1.InsertButtonClick(Sender: TObject); Begin CustTable.Insert;{进入dsInsert状态} AddressPromptDialog.ShowModal;

delphi中的record使用

在Delphi中的Record类型中,与之C语言对应的即是结构体类型(struct),也可能是为了符合C语言或C++程序员的习惯,对于它在Delphi中的应用存在的一些问题进行初步的说明。在Delphi中的记录体类型有两种方式定义 Type RecTest = record (packed) ID :integer; Name :string; Descript:string; end; 之两种类型的主要区别在于在内存中的存放,Packed是紧缩类型的,可以节省内存空间与存放的空间,但是它定义好了对应的长度,所以不太适合存放不定长的数据,如string类型的数据;同时在使用记录体类型时特别要注意的是使用记录体数组的情况,使用不当不仅仅会出现性能方面的问题,同时也会产生意想不到的错误。如 RecList arrary[0..100] of RecTest,如采用这样的定义的方面,会产生的问题有: 1.当用数组下标访问对应的记录体元素时,到后面的数据记录访问时间会越来越长,如RecList[89] ,它需要将RecTest中移动88个记录长度,由于RecTest是不定长的,所以每次移动的长度也可能不相同,所以导致定位数组中记录体时定位时间长

2.当对记录体进行赋值时,如果想默认或遗忘给某个变量赋值,则会产生比较严重的后果,当应用到该变量时,可能会读取到错误的数值如一定要使用记录体类型的,可以采用一些变通的方法,如采用数组指针,这样可以大幅提升性能,如针对前面的记录体数据情况,可以多定义一个指针变量,如下: PRecList = ^RecTest RecList arrary[0..100] of PRecList 这样定义相对的好处就是每次移动时,只需要移动记录指针的长度数即可,即在现有的windows系统中,只需要移动4位即可。 所以针对上面的问题,在程序开发中尽量少采用记录体类型,直接定义一个相应的类即可,定义一个相应的类处理的好处时,可以与面对对象的开发的方法相一致,只不过是比记录体多了创建与释放而已,但相应的初始化或方法、属性在类中很容易实现,同时对于程序的扩展类也很容易处理,记录体可能会比较麻烦,如在记录体中增加一个字段,那有可能整个程序都需要变化,但在对象中增加一个属性会显得非常方便,同时也容易对于对象中的属性内容进行初始化处理。另:在对不定长记录进行再分配空间时,如增加一个长度的空间,在系统中的处理是先开避一块内存地址保存当前内容再在此基础上加一个长度的地址长度,即在相应的内存中需要复制两个长度的地址后才能完成增加长度。 补充1: 1. 首先了解到record是可以限制field的范围的,而且定义枚举类型的。 type TDateRec = record Year: Integer;

Delphi中可能你不知道的内存泄露

Delphi中可能你不知道的内存泄露 Delphi中可能你不知道的内存泄露 时间:2011-9-3 15:37:12 点击: 1437 核心提示:为了提高string 的读写性能Delphi 采用了copy-on-write 机制进行内存管理。简单来说,在复制一个string 时并不是真的在内存中把原来string 的内容复制一 份到另...为了提高string 的读写性能Delphi 采用了 copy-on-write 机制进行内存管理。简单来说,在复制一个string 时并不是真的在内存中把原来string 的内容复制一 份到另外一个地址,而是把新的string 在内存映射表中指向同原string 相同的位置,并且把那块内存的引用计数加一。这样就省去了复制字符串的时间。只有当string 的内容发生变化的时候,才真正将改动的内容完整复制一份到新的地址,然后对原地址的引用计数减一,将新地址的引用计数设为一,最后将新string 在内存映射表中指向这个新的位置。当某个字符串内存块的引用计数为零了,这块内存就可以被其它程序使用了。注意:所有常量string 会在编译时率先分配内存,其引用计数不会在程序中变化,始终为-1。更详细的介绍,

可以参考『Pascal 精要』和『标准C++类std::string的内存共享和Copy-On-Write技术』。 内存泄漏的发现: 在检查内存泄漏时,无意发现了使用记录过程中产生的内存泄漏。请看如下代码: type TMyRec = record S: string; I: Integer; end; procedure Test; var ARec: TMyRec; begin FillChar(ARec, SizeOf(ARec), #0); ARec.S := 'abcd'; ARec.I := 1234; // ... FillChar(ARec, SizeOf(ARec), #0); //<--- A leak! // ... end; FillChar 的作用是对一个内存块进行连续赋值,内存泄漏出

怎样在delphi中备份access数据库

怎样在delphi中备份access数据库 发布人: formulas; 发布时间: 2006-12-15 ; 上次回复: 2007-3-27 11:38:01; 总计回复: 8人次 怎样在delphi中备份access数据库?小弟从没做过这方面的东西,所以不会做。用了一个savedialog 控件。也执行了savedialog.execute但我想备份的数据库my1.mdb还是没有成功备分到指定目录。希望各位大侠指点啊。 蓝冰(jrant) [等级:◆◆(初级)] (信誉值: 98) 回复于: 2005-9-28 17:23:09 Top 将my1.mdb文件直接另存为 遨游的人(gongda3124) [等级:◆(初级)] (信誉值: 100) 回复于: 2005-9-28 17:29:53 Top 老兄,你不是要我在windows下直接操作吧,我要求能在我自己编的软件中执行啊。 飞帆(flyjalor) [等级:◆(初级)] (信誉值: 100) 回复于: 2005-9-28 17:46:33 Top 赫赫,你程序中式不是用到数据库了?? 1。首先把数据库关闭!利用拷贝文件的api函数备份到其他地方 2。在其他地方建立好相同的数据文件,你利用程序从本库写到备份库里 遨游的人(gongda3124) [等级:◆(初级)] (信誉值: 100) 回复于: 2005-9-28 17:50:38 Top 楼上的大哥能不能详细些啊,你这样说了我也不会做啊,最好能给出个例子。 蹩脚的程序员(winxkm) [等级:◆◆◆(初级)] (信誉值: 99) 回复于: 2005-9-28 17:53:10 Top procedure Tfrm_main.FileCopy; var FromF, ToF: file; NumRead, NumWritten: Integer; Buf: array[1..2048] of Char; begin ProgressBar1.PartsComplete:=0; label1.Caption:='数据库备份过程中......' ; AssignFile(FromF, extractfilepath(application.EXEName)+'DB\data.roc'); Reset(FromF, 1);{ Record size = 1 } ProgressBar1.TotalParts:=sizeof(FromF); AssignFile(ToF, extractfilepath(application.EXEName)+'DB\backup\'+formatDateTime('yyyy-mm-dd',date)+'.roc');{ Open output file } Rewrite(ToF, 1);{ Record size = 1 } ProgressBar1.PartsComplete:=sizeof(ToF); repeat BlockRead(FromF, Buf, SizeOf(Buf), NumRead);

相关文档
最新文档