关于TField.DataSize的坑

从其它平台迁移而来 在从数据库中查询数据时,有时需要事先取得字段内容的大小,再根据情况进行处理。 对于ADO之类返回TField类型的,可以使用DataSize属性,但是!!!这里有很深的坑!!!。 首先看如下代码: 1 2 3 4 if ADOQuery.FieldByName('Test').DataSize > 3 then {处理1} else {处理2}; 按预想,当Test字段里的数据超过3B时,应该执行处理1的代码,但事实上无论该内容长短,都是执行处理2的代码,WHY? 扒一下Delphi的源码就明白了。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 function TField....

2019-07-11 20:03:00 · 3 分钟 · 慢步道人

Delphi安全结束线程

从其它平台迁移而来 在开发过程中,不可避免的要用到多线程,而线程的同步、释放等又可能引入新的问题,不过网上已有许多资料,这里重点说下我使用的方法。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 type TMyThread = class(TThread) protected procedure Execute; override; public constructor Create(...); destructor Destroy; override; //使用 reintroduce 关键字可以明确通知编译器屏蔽父类的同名方法而使用自己的方法。 procedure Free; reintroduce; end; constructor TMyThread.Create(...); begin { 在这里创建相关对象,可以省去先挂起线程再恢复的操作 } inherited Create; end; destructor TMyThread....

2019-04-28 19:13:48 · 1 分钟 · 慢步道人

关于窗口置屏的那个坑

从其它平台迁移而来 在开发多屏应用程序的时候,经常需要把某个窗口置到某个屏上的某个位置。以下是一个Delphi写的置屏方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 procedure ShowInMonitor(Sender: TObject; AIndex: Integer; ALeft: Integer = 0; ATop: Integer = 0); var lM: TMonitor; begin if Sender is TControl then begin if AIndex > Screen.MonitorCount - 1 then begin AIndex := 0; end; lM := Screen.Monitors[AIndex]; (Sender as TControl).Left := lM.Left + ALeft; (Sender as TControl).Top := lM.Top + ATop; end; end; Sender是需要置屏的窗口;AIndex是置屏的目标屏号,从0开始;ALeft是水平偏移量,ATop是垂直偏移量,默认均为0,即在目标屏的左上角。...

2019-03-01 16:16:46 · 1 分钟 · 慢步道人

DBGridEh显示、编辑标记字段

从其它平台迁移而来 在用Delphi开发数据库应用过程中,经常需要用到DBBrid来显示或编辑数据库表,但相对于IDE自带的DBBrid,DBGridEh显然要更好用一些(cxDBGrid也同样好使,这里只对DBGridEh进行说明)。 在数据库表结构设计时,通常会习惯使用整型字段来存储如男、女、已修改、已删除、已作废等具有标记性的信息,好处是占存储空间小且可扩展性强,缺点是显示方式不友好,但是,使用DBGridEh的一些设置可以弥补这个缺陷。 假设数据库里的表T_Demo里有一个表示性别的字段Sex,其用0表示男,1表示女,2表示未知,用DBGridEh显示时仍为0、1、2,十分不友好。这时只要做一点美化即可。 在DBGridEh的对应列的KeyList属性里分别加入0、1、2三个数字,每个数字一行,用代码实现的话就是: 1 2 3 4 5 //这里假设第一列就是性别,以下代码相同 DBGridEh.Columns[0].KeyList.Clear; DBGridEh.Columns[0].KeyList.Append('0'); DBGridEh.Columns[0].KeyList.Append('1'); DBGridEh.Columns[0].KeyList.Append('2'); 在DBGridEh的对应列的PickList属性里分别加入男、女、未知三行,用代码实现是: 1 2 3 4 DBGridEh.Columns[0].PickList.Clear; DBGridEh.Columns[0].PickList.Append('男'); DBGridEh.Columns[0].PickList.Append('女'); DBGridEh.Columns[0].PickList.Append('未知'); 这样,原先显示为0、1、2的性别就变成了男、女、未知。也可以加上图片来进一步美化。 放置一个TImagList控件,并命名为ilSex,然后分别添加三个图片,比如像卫生间的男、女图片和问号,注意添加后图片对应的索引,否则会张冠李戴。 在DBGridEh的ImagList属性里关联ilSex,并且设置ShowImageAndText属性为True,用代码是: 1 2 DBGridEh.ImagList := ilSex; DBGridEh.ShowImageAndText := True; 这样,性别这一列就有图片有文字,比0、1、2要友好很多,而且在编辑的时候也可以直接下拉进行选择来实现性别的录入。

2019-01-25 11:37:40 · 1 分钟 · 慢步道人

TClientDataSet的使用以及遇到的坑

从其它平台迁移而来 在Delphi未加入FireDAC之前,似乎是没有内存表控件的(也许有,可能我不知道吧),但是可以用TClientDataSet控件来做内存表使用,即使有了FireDAC可以使用TFDMemTable,我还是觉得TClientDataSet更好用一些。 做内存表使用 创建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 with ClientDataSet do begin Close; //定义字段 with FieldDefs do begin Clear; Add('Field1', ftInteger, 0, False); Add('Field2', ftString, 0, False); ...... end; //创建结构 CreateDataSet; Open; end; 排序 在定义字段后,创建结构前,也可以指定排序字段。 1 IndexFieldNames := 'Field1'; 做缓存使用 需要结合TDataSetProvider来使用。以下示例以使用ADO组件为例。 拉取数据 方法1 TDBGrid->TDataSource->TClientDataSet->TDataSetProvider->TADOQuery->TADOConnection 1 2 3 4 5 6 7 ClientDataSet.ProviderName := DataSetProvider.Name; //设计器里设置过就不需要了 with ClientDataSet do begin Close; CommandText:='select * from T_Table'; Open; end; 方法2 TDBGrid->TDataSource...

2019-01-12 14:43:15 · 1 分钟 · 慢步道人

使用海康威视SDK的那些坑

从其它平台迁移而来 由于工作需要,项目中有使用到海康威视的产品,不可避免的就要使用海康的SDK进行二次开发。开发过程中磕磕绊绊的,踩了不少坑,这里做一个简单的记录,算是给健忘的自己提个醒吧。 Delphi版本的接口 Gitee地址 首先,自己一直使用Delphi进行开发,然而海康官方只提供了C/C++的接口和示例,无奈只能自己改写了。改写完的部分已经上传,希望能有人共同来完善。 由于Delphi商业使用的限制,现已转到Lazarus,全面拥抱开源。 坑 播放声音 预览时播放声音,回放时播放声音,甚至使用播放库播放已下载的视频时播放声音,这些对于前端摄像头自带麦克的场景肯定是刚需(另接麦克的情况暂未测试),然而按照官方SDK文档和示例代码写出的程序死活就是没有声音,这样的情况似乎不少人都遇到过,但是,好像并没有见谁把解决方法公开过。 其实,这个问题特别简单,只需要把HCNetSDKCom目录下的OpenAL32.dll拷贝到PlayCtrl.dll所在的目录下就可以了。这下就明白了吧,没有声音的原因其实就是使用NET_DVR_OpenSound调了PlayCtrl.dll,而PlayCtrl.dll又调了OpenAL32.dll来播放声音,但是由于PlayCtrl.dll没有找到OpenAL32.dll所以没有声音,而且这个有问题的返回值也并没有一层层的返回给NET_DVR_OpenSound函数,结果就是函数返回调用成功了,但就是死活没声音。 PlayCtrl.dll不是PlayCtrl.dll 使用海康SDK进行二次开发的,一般也会使用到海康的播放库,但是有一个问题是需要注意的,那就是SDK里的PlayCtrl.dll并不是播放库里的PlayCtrl.dll。虽然它们长得一样,名字也一样,但它们的本质却是完全不一样的,是不能互相替代的!有兴趣的朋友可以使用eXeScope详细查看。

2019-01-02 16:29:46 · 1 分钟 · 慢步道人

Delphi自定义图形控件的自定义字体属性在设计期报错的解决办法

从其它平台迁移而来 背景 自定义一个图形控件(继承自TGraphicControl类),需要在不同区域显示不同字体的内容,此时会需要在设计器中加入多个字体,方法是在控件的published区增加对应的字体属性即可(使用Ctrl+Shift+C可快速生成),如: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 TMyGraphicControl = class(GraphicControl) private FText1Font: TFont; FText2Font: TFont; procedure SetText1Font(const Value: TFont); procedure SetText2Font(const Value: TFont); protected procedure Paint; override; public { public declarations } published property Text1Font:TFont read FText1Font write SetText1Font; property Text2Font:TFont read FText2Font write SetText2Font; end; 这样就可以在设计器里像使用原生控件一样使用自己的控件了。 问题 但是,如果在设计期选择了弹出字体对话框进行设置字体,IDE就会报错(大意是读或写某个地址异常),而在运行期则正常! 原因 对比查看Delphi自带的控件源码,终于找到了原因。 1 2 3 4 5 6 7 8 9 10 //Delphi TControl类设置字体属性的方法 procedure TControl....

2018-10-02 02:40:14 · 1 分钟 · 慢步道人

Delphi版本号对照表

从其它平台迁移而来 Conditional VER Product Product Version Package Version VER330 Delphi / C++Builder XE10.3 Rio 26 260 VER320 Delphi / C++Builder XE10.2 Tokyo 25 250 VER310 Delphi / C++Builder XE10.1 Berlin 24 240 VER300 Delphi / C++Builder XE10 Seattle 23 230 VER290 Delphi / C++Builder XE8 22 220 VER280 Delphi / C++Builder XE7 21 210 VER270 Delphi / C++Builder XE6 20 200 VER260 Delphi / C++Builder XE5 19 190 VER250 Delphi / C++Builder XE4 18 180 VER240 Delphi / C++Builder XE3 17 170 VER230 Delphi / C++Builder XE2 16 160 VER220 Delphi / C++Builder XE 15 150 VER210 Delphi / C++Builder 2010 14 140 VER200 Delphi / C++Builder 2009 12 120 VER190 Delphi 2007 for ....

2018-08-12 15:52:38 · 2 分钟 · 慢步道人

使用FireDAC的TFDQuery查询Firebird遇到的坑

从其它平台迁移而来 这几天被Prepare这个东西搞死了,虽然用它解决了目前的问题,但是完全不知道为什么,如有大侠知道还望指教,不胜感激! 首先,说下开发环境: win10 x64(1709 [10.0.16299.125])+Delphi XE7 up1(自带FireDAC)+Firebird 3.0.2.32703_0(数据库字符集使用UTF8) 问题一:中文模糊查询 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var CompanyType: Integer FDQuery1.Close; FDQuery1.SQL.Text := 'SELECT * FROM companyinfo ' + 'WHERE (tag = 0) AND (companytype = :companytype) AND ' + '((companyname LIKE :Text) OR (pym LIKE :Text))' + ' ORDER BY TIMES DESC'; //FDQuery1.Prepare; //写在这里会报错,提示如下,大致意思是: //数据库 companytype 字段是SmallInt类型,却赋了一个Integer类型的值 {--------------------------- [FireDAC][Phys][FB]-338....

2018-01-03 01:43:02 · 2 分钟 · 慢步道人

cxGrid基本用法小记

从其它平台迁移而来 汉化 在DevExpress选项卡找到TcxLocalizer控件放到窗体上,为了通用,我是放到DataModule窗体上。 准备好汉化的资源文件或配置文件(我使用的是后者),在DataModule的Create事件里写上如下代码 1 2 3 4 5 6 7 with cxLocalizer1 do begin StorageType := lstIni; LoadFromFile(IniPath + 'DevChs.ini'); locale := 2052; Active := True; end; 在有cxGrid或其实Dev控件的单元引用DataModule单元。 更改视觉样式 在DevExpress选项卡找到TcxLookAndFeelController控件放到DataModule窗体上。 在有cxGrid或其它Dev控件的单元引用DataModule单元。 在要更改视觉样式的代码段里设置TcxLookAndFeelController控件的Kind属性和NativeStyle属性。 让cxGrid的数据以斑马线的方式显示,即奇偶行分别使用不同样式 在DevExpress选项卡找到TcxStyleRepository控件放到DataModule窗体上。 双击cxStyleRepository控件,打开如下窗口,点Add添加两个样式,并命名。 分别在属性中设置不同的样式,颜色、字体、字号、字体颜色等。 在有cxGrid的单元中引用DataModule单元。 选中cxGrid的cxGridDBTableView,展开Styles,分别关联ContentEven和ContentOdd。 另外也可设置Header、Selection和Inactive。Header改变的是表头的样式,Selection改变的是当前选择行的样式,Inactive改变的是cxGrid失去焦点时当前选择行的样式。 不显示分组框 设置cxGridDBTableView的OptionsView下的GroupByBox属性为False。 显示合计等脚注 设置cxGridDBTableView的OptionsView下的Footer属性为True。 点cxGrid的Customize...按钮,弹出对话框,选择Summary标签页,在Footer子标签页中点Add增加合计项目。 选择增加的项目,在属性中设置关联的列、字段名等属性。 设置行号 增加一列,不关联数据库字段,设置好属性。 在该列的OnGetDataText事件中写如下代码: 1 AText := IntToStr(ARecordIndex + 1); 编辑完成前光标不能离开当前行 在cxGridDBTableView的OnCanFocusRecord事件中写入类似以下的代码: 1 AAllow := DbState in [dsBrowse]; 只读 设置cxGridDBTableView.OptionsData.Editing属性为False。 选择整行 设置cxGridDBTableView.OptionsSelection.CellSelect属性为False。

2017-11-25 20:41:33 · 1 分钟 · 慢步道人