搜档网
当前位置:搜档网 › DELPHI中使用RTTI

DELPHI中使用RTTI

DELPHI中使用RTTI
DELPHI中使用RTTI

DELPHI中使用RTTI

运行期类型信息(RTTI)是一种语言特征,能使应用程序在运行时得到关于对象的信息。RTTI 是Delphi的组件能够融合到IDE中的关键。它在IDE中不仅仅是一个纯学术的过程。

由于对象都是从TObject继承下来的,因此,对象都包含一个指向它们的RTTI的指针以及几个内建的方法。下面的表列出了TObject的一些方法,用这些方法能获得某个对象实例的信息。

第一部分:关于as 和is

Object Pascal提供了两个运算符as和is,用它们通过RTTI能对对象进行比较和强制类型转换。

关键字as是类型转换的一种新的形式。它能把一个基层的对象强制类型转换成它的派生类,如果转换不合法就产生一个异常。假定有一个过程,想让它能够传递任何类型的对象,它应该这样定义:

Procedure Foo(AnObject :Tobject);

在这个过程如果要对AnObject进行操作,要把它转换为一个派生对象。假定把AnObject看成是一个TEdit派生类型,并想要改变它所包含的文本,用下列代码:(AnObject as Tedit).text := 'wudi_1982';

能用比较运算符来判断两个对象是否是相兼容的类型,用is运算符把一个未知的对象和一个已知类型或实例进行比较,确定这个未知对象的属性和行为。例如,在对(AnObject 进行强制类型转换前,确定(AnObject 和TEdit是否指针兼容:

if (AnObject is Tedit) then

Tedit(AnObjject).text := 'wudi_1982';

注意在这个例子中不要再使用as进行强制类型转换,这是因为它要大量使用RTTI,另外还因为,在第一行已经判断Foo就是TEdit,可以通过在第2行进行指针转换来优化。

这两个操作符最典型的应用我想应该是在程序需要的部分清空窗体上所有edit的text属性

procedure TForm1.ClearEdit(Acontrl: TWinControl);

var

i : integer;

begin

for i := 0 to Acontrl.ControlCount-1 do

begin

if Acontrl.Controls[i] is TEdit then

((Acontrl.Controls[i]) as TEdit).Text := '';

if Acontrl.Controls[i] is TCustomControl then

ClearEdit( (Acontrl.Controls[i] as TCustomControl))

end;

end;

第二部分:RTTI

上文中已经多次提到了RTTI,但好像并没有看到RTTI出现。那么RTTI是如何表现自己的

呢?你将发现,RTTI至少在两个地方对你有用。第一个地方是DELPHI的IDE,这在前面已提到过。通过RTTI,IDE就会知道你正在使用的对象和组件的任何事情。实际上,不只是RTTI,但为了这个讨论,我们只谈RTTI方面。其实上面的as,is操作都间接的使用了RTTI。

还是用个例子来演示吧。在观看此例子之时,建议你看看typinfo.pas中的内容(DELPHI安装目录下\source\rtl\common\TypInfo.pas);

下面的例子主要分为两部分,界面上半部分,主要演示通过rtti来显示用户选择类型的信息。(有3个TListBox)。

下面的部分主要通过RTTI来完成通过配置信息对控件进行属性的赋值操作,这里将演示文本类型和事件类型的赋值。

窗体文件如下:代码如下:

object Form1: TForm1

Left = 150

Top = 161

Width = 639

Height = 372

Caption = 'Form1'

Color = clBtnFace

Font.Charset = DEFAULT_CHARSET

Font.Color = clWindowText

Font.Height = -11

https://www.sodocs.net/doc/0e4450724.html, = 'Tahoma'

Font.Style = []

OldCreateOrder = False

OnCreate = FormCreate

PixelsPerInch = 96

TextHeight = 13

object Panel1: TPanel

Left = 0

Top = 0

Width = 631

Height = 185

Align = alTop

TabOrder = 0

object GroupBox1: TGroupBox

Left = 1

Top = 1

Width = 185

Height = 183

Align = alLeft

Caption = '在这里选择要查看类型的信息'

TabOrder = 0

object ListBox1: TListBox

Left = 2

Top = 15

Width = 181

Height = 166

Align = alClient

ItemHeight = 13

TabOrder = 0

OnClick = ListBox1Click

end

end

object GroupBox2: TGroupBox

Left = 368

Top = 1

Width = 262

Height = 183

Align = alRight

Caption = '属性信息'

TabOrder = 1

object ListBox3: TListBox

Left = 2

Top = 15

Width = 258

Height = 166

Align = alClient

ItemHeight = 13

TabOrder = 0

end

end

object GroupBox3: TGroupBox

Left = 186

Top = 1

Width = 182

Height = 183

Align = alClient

Caption = '基本信息'

TabOrder = 2

object ListBox2: TListBox

Left = 2

Top = 15

Width = 178

Height = 166

Align = alClient

ItemHeight = 13

TabOrder = 0

end

end

end

object TPanel

Left = 0

Top = 185

Width = 631

Height = 157

Align = alClient

TabOrder = 1

object Panel2: TPanel

Left = 1

Top = 1

Width = 230

Height = 155

Align = alLeft

TabOrder = 0

object Label2: TLabel

Left = 10

Top = 8

Width = 84

Height = 13

Caption = '要修改的控件名'

end

object Label3: TLabel

Left = 8

Top = 32

Width = 72

Height = 13

Caption = '修改的属性名'

end

object Label4: TLabel

Left = 8

Top = 64

Width = 72

Height = 13

Caption = '将属性修改为'

end

object edComName: TEdit

Left = 104

Top = 5

Width = 78

Height = 21

TabOrder = 0

Text = 'label1'

end

object edPproName: TEdit

Left = 104

Top = 32

Width = 81

Height = 21

TabOrder = 1

Text = 'caption'

end

object edValue: TEdit

Left = 104

Top = 56

Width = 81

Height = 21

TabOrder = 2

Text = '12345'

end

object btnInit: TButton

Left = 8

Top = 104

Width = 75

Height = 25

Caption = '初始化'

TabOrder = 3

OnClick = btnInitClick

end

object btnModify: TButton

Left = 104

Top = 104

Width = 75

Height = 25

Caption = '修改'

TabOrder = 4

OnClick = btnModifyClick

end

end

object Panel3: TPanel

Left = 231

Top = 1

Width = 399

Height = 155

Align = alClient

TabOrder = 1

object GroupBox4: TGroupBox

Left = 1

Top = 1

Width = 397

Height = 153

Align = alClient

Caption = '被修改的控件'

TabOrder = 0

object Label1: TLabel

Left = 16

Top = 32

Width = 28

Height = 13

Caption = 'label1'

end

object BitBtn1: TBitBtn

Left = 8

Top = 64

Width = 75

Height = 25

Caption = 'BitBtn1'

TabOrder = 0

end

end

end

end

end

{

作者:wudi_1982

联系方式:wudi_1982@https://www.sodocs.net/doc/0e4450724.html,

转载请注明出处

}

unit main;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,

Forms,

Dialogs,typinfo, StdCtrls, ExtCtrls, Buttons;

type

InsertCom = record

Name : string; //要修改属性的组件名

PproName : string;//要修改控件的属性名

MethodName :string;//要修改or添加给控件的事件名

text : string; //属性值,这里修改的是string类型的数值

end;

TForm1 = class(TForm)

Panel1: TPanel;

GroupBox1: TGroupBox;

ListBox1: TListBox;

GroupBox2: TGroupBox;

GroupBox3: TGroupBox;

ListBox2: TListBox;

ListBox3: TListBox;

Panel2: TPanel;

edComName: TEdit;

Label2: TLabel;

Label3: TLabel;

edPproName: TEdit;

Label4: TLabel;

edValue: TEdit;

Panel3: TPanel;

btnInit: TButton;

btnModify: TButton;

GroupBox4: TGroupBox;

Label1: TLabel;

BitBtn1: TBitBtn;

procedure FormCreate(Sender: TObject);

procedure ListBox1Click(Sender: TObject);

procedure btnInitClick(Sender: TObject);

procedure btnModifyClick(Sender: TObject);

private

TestCom : InsertCom;

procedure MyClick(Sender : TObject); //给控件添加onclick事件

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

function CreateClass(const AClassName : string):TObject;//根据名字生成

var

tm : TObject;

t : TFormClass;

begin

t := TFormClass(FindClass(AClassName));

tm := t.Create(nil);

Result := tm;

end;

procedure GetBaseClassInfo(AClass : TObject;AStrings : TStrings); //获

得类型的基本信息

var

classTypeInfo : PTypeInfo;

ClassDataInfo : PTypeData;

begin

classTypeInfo := AClass.ClassInfo;

ClassDataInfo := GetTypeData(classTypeInfo);

with AStrings do

begin

Add(Format('name is :%s',[https://www.sodocs.net/doc/0e4450724.html,]));

Add(format('type kind is :%s',[GetEnumName(TypeInfo

(TTypeKind),integer(classTypeInfo.Kind))]));

Add(Format('in : %s',[ClassDataInfo.UnitName]));

end;

end;

procedure GetBaseClassPro(AClass : TObject;Astrings : TStrings); //获

得属性信息

var

NumPro : integer; //用来记录事件属性的个数

Pplst : PPropList; //存放属性列表

Classtypeinfo : PTypeInfo;

classDataInfo: PTypeData;

i : integer;

begin

Classtypeinfo := AClass.ClassInfo;

classDataInfo := GetTypeData(Classtypeinfo);

if classDataInfo.PropCount <> 0 then

begin

//分配空间

GetMem(Pplst,sizeof(PpropInfo)*classDataInfo.PropCount);

try

//获得属性信息到pplst

GetPropInfos(AClass.ClassInfo,Pplst);

for I := 0 to classDataInfo.PropCount - 1 do

begin

if Pplst[i]^.PropType^.Kind <> tkMethod then

//这里过滤掉了事件属性

Astrings.Add(Format('%s:%s',[Pplst[i]^.Name,Pplst[i]

^.PropType^.Name]));

end;

//获得事件属性

NumPro := GetPropList(AClass.ClassInfo,[tkMethod],Pplst);

if NumPro <> 0 then

begin

//给列表添加一些标志

Astrings.Add('');

Astrings.Add('-----------EVENT-----------');

Astrings.Add('');

for i := 0 to NumPro - 1 do//获得事件属性的列表

Astrings.Add(Format('%s:%s',[Pplst[i]^.Name,Pplst[i]

^.PropType^.Name]));

end;

FreeMem(Pplst,sizeof(PpropInfo)*classDataInfo.PropCount);

end;

end;

end;

procedure TForm1.btnInitClick(Sender: TObject);

begin

//修改label1的caption属性为12345

https://www.sodocs.net/doc/0e4450724.html, := edComName.Text;

TestCom.PproName := edPproName.Text;

TestCom.text := edValue.Text;

TestCom.MethodName := 'OnClick';

btnModify.Enabled := true;

end;

procedure TForm1.btnModifyClick(Sender: TObject);

var

pp : PPropInfo;

obj : TComponent;

a : TMethod;

tm : TNotifyEvent;

begin

obj := FindComponent(https://www.sodocs.net/doc/0e4450724.html,);//通过名字查找此控件

if not Assigned(obj) then exit; //如果没有则退出

//通过getPropInfo获得指定控件的属性信息,注意,这里只能获得那些公开

pp := GetPropInfo(obj.ClassInfo,TestCom.PproName);

if Assigned(pp) then

begin

//根据kind判断类型是否为string类型

case pp^.PropType^.Kind of

//这里使用setStrProp来为string类型的属性赋值,对起来类型的赋值

,请参考TypInfo.pas

tkString,tkLString,tkWString : SetStrProp

(obj,TestCom.PproName,TestCom.text);

end;

//给要修改的控件添加onClick事件,

pp := GetPropInfo(obj.ClassInfo,TestCom.MethodName);

if Assigned(pp) then

begin

if pp^.PropType^.Kind = tkMethod then

begin

tm := MyClick;

//Tmethod的code为函数地址,你也可以通过MethodAddress方法获得

a.Code := @tm;

a.Data := Self;

//对时间赋值

SetMethodProp(obj,TestCom.MethodName,a);

end;

end;

end;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

btnModify.Enabled := false;

//给listbox1添加一些类型的类名

with ListBox1.Items do

begin

Add('TApplication');

Add('TEdit');

Add('TButton');

Add('Tmemo');

Add('TForm');

end;

end;

procedure TForm1.ListBox1Click(Sender: TObject);

var

t : TObject;

begin

//当在类型列表中选择一个类型并用鼠标单击后,分别得到它的属性信息和

基本信息

ListBox2.Clear;

ListBox3.Clear;

t := CreateClass(ListBox1.Items[ListBox1.ItemIndex]);

try

GetBaseClassInfo(t,ListBox2.Items);

GetBaseClassPro(t,ListBox3.Items);

finally

t.Free;

end;

end;

procedure TForm1.MyClick(Sender: TObject);

begin

//给指定控件添加的一个方法

ShowMessage('wudi_1982');

end;

initialization

//初始化的时候注册

RegisterClasses([TApplication,TButton,TEdit,TMemo,TForm]);

end.

注:示例程序在winxp+D7以及turbo delphi+winxp下测试通过。Borland文档中不包含将来也许会有版本变化的功能。当使用如RTTI等无文档说明的功能时,就不能保证你的程序可以完全移植到Delphi的未来版本。转载请注明出处!

程序效果图如下:

编译、运行程序,你可以通过点击左上角列表框中的类型,获得他们的信息。而在窗体的下部,主要演示了通过读取配置信息来对控件的属性赋值(例程中的配置信息是通过edit输入的,可以在实际运用中改成从配置文件读取)。当使用下半部分功能时,在默认情况下,点击初始化按钮,然后点击修改,你会发现label1的caption变成了12345,并在在鼠标点击的时候会弹出一个对话框,你可以尝试把第一个edit的内容改成bitbtn1试试。

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 ;

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:动态创建一具有姓名和年龄两个字段的数据集。

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.sodocs.net/doc/0e4450724.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

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);

DELPHI HOOK函数建立键盘鼠标动作记录与回放

内容:很多的教学软件或系统监视软件可以自动记录回放用户的输入文字或点击按钮等操作操作,这个功能的实现是使用 了Windows的Hook函数。 Windows提供API函数SetwindowsHookEx来建立一个Hook,通过这个函数可以将一个程序添加到Hook链中监视Windows 消息,函数语法为: SetWindowsHookEx(idHook: Integer; lpfn: TFNHookProc; hmod: HINST; dwThreadId: DWORD) 其中参数idHook指定建立的监视函数类型。通过Windows MSDN帮助可以看到,SetwindowsHookEx函数提供15种不同 的消息监视类型,在这里我们将使用WH_JOURNALRECORD和WH_JOURNALPLAYBACK来监视键盘和鼠标操作。参数lpfn指定消 息函数,在相应的消息产生后,系统会调用该函数并将消息值传递给该函数供处理。函数的一般形式为: Hookproc (code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall; 其中code为系统指示标记,wParam和lParam为附加参数,根据不同的消息监视类型而不同。只要在程序中建立这样 一个函数再通过SetwindowsHookEx函数将它加入到消息监视链中就可以处理消息了。 在不需要监视系统消息时需要调用提供UnHookWindowsHookEx来解除对消息的监视。WH_JOURNALRECORD和WH_JOURNALPLAYBACK类型是两种相反的Hook类型,前者获得鼠标、键盘动作消息,后者回放鼠 标键盘消息。所以在程序中我们需要建立两个消息函数,一个用于纪录鼠标键盘操作并保存到一个数组中,另一个用于 将保存的操作返给系统回放。 下面来建立程序,在Delphi中建立一个工程,在Form1上添加3个按钮用于程序操作。另外再添加一个按钮控件和一 个Edit控件用于验证操作。 下面是Form1的全部代码 unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Edit1: TEdit; Button4: TButton; procedure FormCreate(Sender: TObject);

在delphi中关于文件拷贝、删除、移动、改名等SHFileOperation的详细用法

关于SHFileOperation的详细用法 type _SHFILEOPSTRUCTA = packed record Wnd: HWND; wFunc: UINT; pFrom: PAnsiChar; pTo: PAnsiChar; fFlags: FILEOP_FLAGS; fAnyOperationsAborted: BOOL; hNameMappings: Pointer; lpszProgressTitle: PAnsiChar; { only used if FOF_SIMPLEPROGRESS } end; hwnd:用来显示操作状态的对话框句柄。例中是form1的句柄 wFunc:执行的操作。可以是以下各值:(例中是FO_COPY) FO_COPY:拷贝pfrom域中指定的(目录,例中是'c:\a')到pto中指定的位置(例中为'c:\b') FO_DELET:删除pfrom中指定的文件. (pTo不用) FO_MOVE:移动PFrom中指定的文件到pto中指定的位置。 FO_RENAME:给PFrom中指定的文件改名。 pFrom:指定一个或多个源文件名的缓冲区地址。多个名字必须用NULL分隔。名字列表必须用两个NULL (nil,'\0')来结束。 pTo:目标文件或目录名缓冲区地址。如果fFlags域指定FOF_MULTIDESTFILES,缓冲区可以包含多个目标文件名。多个名字必须用NULL分隔。名字列表必须用两个NULL(nil,'\0') fFlags :控制操作的标志,可以是以下各值组合: FOF_ALLOWUNDO:保留Undo信息,如果pFrom没有包含全的绝对的路径或文件名此值忽略。 FOF_CONFIRMMOUSE:没有实现. FOF_FILESONLY:只有文件名使用通配符时(*.*)才对文件操作。 FOF_MULTIDESTFILES: pTo域指一定了多个目标文件.(一个对就一个源文件) 而不是指定一个目录来存放所有源文件 FOF_NOCONFIRMA TION:所有显示的对话框全部选择yes to all FOF_NOCONFIRMMKDIR: 如果需要创建一个新目录不确认。 FOF_NOCOPYSECURITYATTRIBS: 4.71. Microsoft® Windows NT® only. 安全属性不复制. FOF_NOERRORUI:发生错误时不提供用户接口。 FOF_RENAMEONCOLLISION: move,copy,rename操作时如目标文件存在,给操作的文件另起一个名字。 FOF_SILENT:不显示进度对话框 FOF_SIMPLEPROGRESS:显示进度对话框但不显示文件名。 FOF_WANTMAPPINGHANDLE:如果指定了FOF_RENAMEONCOLLISION 当任何文件改名时将填写hNameMappings 域 fAnyOperationsAborted:当用户在完成前取消任何文件操作时赋值TRUE,否则FALSE. hNameMappings:一个包含SHNAMEMAPPING结构数组的文件名映射对象句柄. 每一个(SHNAMEMAPPING)结构包括一个旧的或新的目录名为了每一个移动的复制的改名的文件。这个域仅在fFlags域包括FOF_WANTMAPPINGHANDLES标志时使用。句柄必须使用SHFreeNameMappings来释放(用完后)

DELPHI中关于ADOQUERY使用方法

Delphi中关于ADOQuery的使用方法:查询、插入、删除、修改(转) procedure TForm1.Button1Click(Sender:TObject); begin ADOQuery.Close; ADOQuery.SQL.Clear; ADOQuery.SQL.Add('select*from YourTABLE where查询条件'); ADOQuery.Open; //插入记录 procedure TForm1.Button2Click(Sender:TObject); begin ADOQuery.Close; ADOQuery.SQL.Clear; ADOQuery.SQL.Text:='insert into YourTABLE(字段1,字段2)values(:字段1,:字段2)'; //ADOQuery.SQL.Add('insert into YourTABLE values(:字段1)'); ADOQuery.Parameters.ParamByName('字段1').Value:=trim(Edit1.Text); ADOQuery.Parameters.ParamByName('字段2').Value:=trim(Edit2.Text); ADOQuery.ExecSQL; end; //删除记录 procedure TForm1.Button3Click(Sender:TObject); begin ADOQuery.Close; ADOQuery.SQL.Clear; ADOQuery.SQL.Text:='Delete from YourTABLE where字段3=:字段3'; //这里没有添加where的条件判断,实际使用时,注意添加判断 //ADOQuery.SQL.Add('Delete from NEW_TABLE where字段3=:字段3'); ADOQuery.Parameters.ParamByName('字段3').Value:=trim(Edit3.Text); ADOQuery.ExecSQL; //删除记录也可用DeleteRecords()函数 procedure DeleteRecords(AffectRecords:TAffectRecords=arAll); 这个函数有一个参数:AffectRecords可以取如下的值:

相关主题