首先,做为一个从Windows下转过来的开发人员,许多时候,我们喜欢用PostMessage来触发一些异步执行的代码,但遗憾的是,FMX做为EMB的跨平台库的基础,只提供了SendMessage方法,却没有提供PostMessage方法。 那我们确实需要PostMessage怎么办?我因为用到了,所以研究了下,编写了一
月度归档: 2014年10月
在Andriod程序中获取外置SD卡根目录
我们知道,Andriod是基于Linux的,所以正常的存贮设备都被挂载到/mnt目录下,我们查找SD卡根目录就是要在下面找到那个卡是外置的SD卡,但遗憾的是,目前没有一种标准的方法来做到这一点(包括Andriod本身)。下面我为大家提供了一个函数来完成这一功能: [crayon-62c6b44c7ccd99162983
Delphi 2007 在IDE环境中无法调试程序解决方法
今天在调试程序是,D2007突然弹出几个错误对话框(类似如图1所示),然后也没仔细看,全部点了”Yes”,发现还是会继续弹,就全部点了”No”。然后就发生问题了。 【问题描述】 在Delphi2007中,Run菜单中的Run、Pause、Reset等功能永远是灰色的,工具
XE7编译Android程序时CreateAndriodMainfestFile失败的解决办法
如果你在编译Android时出现下面的错误提示,那么恭喜你,遇到了Delphi/C++ Builder编译器的一个弱智的Bug:
1 2 3 4 5 6 7 |
[MSBuild Error] The "CreateAndroidManifestFile" task failed unexpectedly. System.UnauthorizedAccessException: Access to the path '\..\..\AndroidManifest.template.xml' is denied. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite) at Borland.Build.Tasks.Shared.CreateAndroidManifestFile.genManifestFile() at Borland.Build.Tasks.Shared.CreateAndroidManifestFile.Execute() at Microsoft.Build.BuildEngine.TaskEngine.ExecuteInstantiatedTask(EngineProxy engineProxy, ItemBucket bucket, TaskExecutionMode howToExecuteTask, ITask task, Boolean& taskResult) |
问题发生的原因是你程序的输出目录没有在当前目录的两级子目录下,正常是Android\Debug或Android\Releas
QXML更新-修正了MoveTo移动到一个没有子结点的结点时出错的问题
【问题描述】 由于TQXMLNode的FItems成员是按需创建的,而在MoveTo函数实现时未检查目标父结点的FItems成员是否已创建,直接添加造成AccessVolation错误。 修改代码加入对FItems是否已经分配的检查,以解决此问题。 【严重程度】 高 【更新级别】 建议 【特别感谢】 新心晨曦
QJson与RapidJson性能的简单对比测试
盒子上一位朋友想知道QJson和C++编写的RapidJson之间的性能对比情况,限于精力,我只是简单的测试了下加载一个大的Json文件来对比解析性能(Demos\Delphi\VCL\QJson\Preferences.txt,文件大小:9.81MB),但做测试大家都知道与测试样本的关系很大,这里只对这一个测试用例负
QMsgPack更新-修正了移动节点时未检查自己是否是目标的父结点问题
【问题描述】 新增加的函数MoveTo在移动结点时,如果错误的将目标结点设置为自己的子结点,程序未报错但执行结果是错的。本更新解决这一问题,并会在发生这一情况时抛出异常,提示用户不能将自己移动到自己的子结点下。 【严重程度】 中等 【更新级别】 推荐
QJSON更新-修正了移动节点时未检查自己是否是目标的父结点问题
【问题描述】 新增加的函数MoveTo在移动结点时,如果错误的将目标结点设置为自己的子结点,程序未报错但执行结果是错的。本更新解决这一问题,并会在发生这一情况时抛出异常,提示用户不能将自己移动到自己的子结点下。 【严重程序】 中等 【更新级别】 推荐
QXML 更新 – 修正了移动节点时未检查自己是否是目标的父结点问题
【问题描述】 新增加的函数MoveTo在移动结点时,如果错误的将目标结点设置为自己的子结点,程序未报错但执行结果是错的。本更新解决这一问题,并会在发生这一情况时抛出异常,提示用户不能将自己移动到自己的子结点下。 【严重程序】 中等 【更新级别】 推荐
QMapSymbols更新-修正了2007+Win7/8环境下退出时出错的问题
【问题描述】 该问题是由于退出时,调用了DisableDeadLockChecker函数,而该函数并未检查当前是否已经启用了死锁检查造成的。 【更新级别】 建议更新 【特别感谢】 火鸟
QWorker更新-修正了在2007下无法编译的问题
【问题描述】 新版的QWorker由于下列原因造成QWorker无法在2007下编译: 1、部分匿名函数没有加入条件编译控制,而2007并不支持匿名函数。 2、Delay函数的全局作业函数版本被错误的包含到了条件编译{$IFDEF UNICODE}{$ENDIF}之间。 3、QString单元调用的Interlocke
QMsgPack更新-增加Remove、Detach、AttachTo、MoveTo函数及允许重命名
【更新内容】 1、新增Remove函数移除指定的子结点,与Delete的区别在于Remove并不会释放子结点,而只是将其从父结点中移除而已。
1 2 3 4 5 |
/// <summary>将指定索引的子结点移除</summary> /// <param name="AItemIndex">要移除的子结点索引</param> /// <returns>返回被移除的子结点,如果指定的索引不存在,返回nil</returns> /// <remarks>被移除的子结点需要用户自己手工释放</remarks> function Remove(AItemIndex: Integer): TQMsgPack; overload; virtual; |
2、新增Detach函数将自己从父结点中移除自身,相当于调用Parent.Remove(Self) [crayo
QJson更新-增加Remove、Detach、AttachTo、MoveTo函数及允许重命名
【更新内容】 1、新增Remove函数移除指定的子结点,与Delete的区别在于Remove并不会释放子结点,而只是将其从父结点中移除而已。
1 2 3 4 5 |
/// <summary>将指定索引的子结点移除</summary> /// <param name="AItemIndex">要移除的子结点索引</param> /// <returns>返回被移除的子结点,如果指定的索引不存在,返回nil</returns> /// <remarks>被移除的子结点需要用户自己手工释放</remarks> function Remove(AItemIndex: Integer): TQJson; overload; virtual; |
2、新增Detach函数将自己从父结点中移除自身,相当于调用Parent.Remove(Self) [crayo
QXML更新-新增Remove/Detach/AttachTo/MoveTo函数
【更新内容】 1、新增Remove函数移除指定的子结点,与Delete的区别在于Remove并不会释放子结点,而只是将其从父结点中移除而已。
1 2 3 4 5 6 7 8 9 10 11 |
/// <summary>移除指定索引的结点</summary> /// <param name="AIndex">要移除的结点索引</param> /// <returns>返回被移除的结点</returns> /// <remarks> /// 1、如果指定索引的结点不存在,则抛出EOutRange异常 /// 2、被移除的结点需要用户自行释放 /// </remarks> function Remove(AIndex: Integer): TQXMLNode; overload; virtual; /// <summary>移除指定的子结点</summary> /// <param name="AIndex">要移除的结点</param> procedure Remove(ANode: TQXMLNode); overload; |
2、新增Detach函数将自己从父结点中移除自身,相当于调用Parent.Remove(Self) [crayo
QWorker更新-正式加入TQJobExtData扩展方式,已兼容移动平台
【问题描述】 上次更新增加的TQJobExtData扩展数据方式,未进行移动平台相关条件编译选项的设置,造成移动平台无法编译。修改加入相关条件编译选项,目前已兼容移动平台。 【严重级别】 中 【更新级别】 可选 【特别感谢】 恢弘
QLog更新-新增TCP协议支持
【更新内容】 TQLogSocketWriter新增TCP协议的支持,通过UseTCP属性控制是否使用TCP协议,默认为UDP协议。 【更新级别】 可选
QWorker更新-修改了作业返回值为一个具体作业句柄
【更新内容】 修改Post、Delay、Wait、At、LongtimeJob的返回值类型,由原来的布尔值(Boolean)改为64位整数。返回的64位整数是对应于具体作业的句柄,在需要清理该作业时,可以直接当作参数传递给Workers.Clear函数,以更高效的清除单独作业。在投寄失败时,返回值为0. 由于此项变更,
QWorker更新-新增基于作业过程的初始化和释放方法
【更新内容】 新增了一个TQJobExtData对象类型以辅助用户来创建一个自动释放的对象实例,它有匿名版本,在支持匿名函数的Delphi 2009以上程序中,可以更方便直观的编写初始化和释放过程。 一、构造函数的声明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
constructor Create(AData: Pointer; AOnFree: TQExtFreeEvent); overload; constructor Create(AOnInit: TQExtInitEvent;AOnFree: TQExtFreeEvent); overload; constructor Create(const Value: Int64); overload; constructor Create(const Value: Integer); overload; constructor Create(const Value: Boolean); overload; constructor Create(const Value: Double); overload; constructor CreateAsDateTime(const Value: TDateTime); overload; constructor Create(const S: QStringW); overload; {$IFNDEF NEXTGEN} constructor Create(const S: AnsiString); overload; {$ENDIF} {$IFDEF UNICODE} constructor Create(AData: Pointer; AOnFree: TQExtFreeEventA); overload; constructor Create(AOnInit: TQExtInitEventA;AOnFree: TQExtFreeEventA); overload; {$ENDIF} |
1、非匿名函数版本 第一种形式的声
QDAC新增QCNDate单元,处理阴阳历之间的换算
该单元可以将1901-2050年间的农历日期与阳历日期之间做任意转换并提供了很多辅助函数,以帮助大家在做日程类应用时,进行相关处理。在Demos\Delphi\VCL下提供了一个Demo来演示这个用法,截图如下: 函数列表如下:
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
/// <summary> /// 将指定的农历年月日编码为一个TCnDate变量 /// </summary> /// <params> /// <param name="Y">农历年份,取值范围为1901-2050 </param> /// <param name="M">农历月份,负数代表是闰月</param> /// <param name="D">农历日数,取值范围为1-30</param> /// </params> /// <returns>返回编码后日期</returns> function CnDate(Y: Word; M, D: Shortint): TCnDate; inline; /// <summary>将指定的日期转换为农历日期</summary> /// <params> /// <param name=“ADate">阳历日期</param> /// </params> /// <returns>返回转换后的日期</returns> function ToCnDate(ADate: TDateTime): TCnDate; overload; /// <summary>将指定的日期转换为农历日期</summary> /// <params> /// <param name=“yyyy">阳历年份</param> /// <param name="mm">阳历月份</param> /// <param name="dd">阳历日</param> /// </params> /// <returns>返回转换后的日期</returns> function ToCnDate(yyyy, mm, dd: Word): TCnDate; overload; /// <summary>将指定农历日期转换为阳历日期</summary> /// <params> /// <param name="ADate">阴历日期</param> /// </params> /// <returns>返回转换后的阳历日期</returns> function ToEnDate(ADate: TCnDate): TDateTime; /// <summary>获取指定阳历日期的农历年份</summary> /// <params> /// <param name="ADate">阳历日期</param> /// </params> /// <returns>返回指定阳历日期的农历年份</returns> function CnYearOf(ADate: TDateTime): Smallint; overload; /// <summary>获取指定农历日期的年份的天干地支名称</summary> /// <params> /// <param name="ADate">阴历日期</param> /// </params> /// <returns>返回天干地支名称,如"甲午"</reutrns> function CnYearName(ADate: TCnDate): QStringW; overload; /// <summary>获取指定阳历日期对应的农历年份的天干地支名称</summary> /// <params> /// <param name="ADate">阴历日期</param> /// </params> /// <returns>返回天干地支名称,如"甲午"</reutrns> function CnYearName(ADate: TDateTime): QStringW; overload; /// <summary>获取指定阳历日期对应的月份数</summary> /// <params> /// <param name="ADate">阳历日期</param> /// </params> /// <returns>返回月份数,取值范围为1-12,-12~-1,负数代表是闰月</returns> function CnMonthOf(ADate: TDateTime): Shortint; overload; /// <summary>获取指定农历日期对应的月份名称</summary> /// <params> /// <param name="ADate">农历日期</param> /// </params> /// <returns>返回农历月份名称,如“腊月”</param> function CnMonthName(ADate: TCnDate): QStringW; overload; /// <summary>获取指定阳历日期对应农历日期对应的月份名称</summary> /// <params> /// <param name="ADate">农历日期</param> /// </params> /// <returns>返回农历月份名称,如“腊月”</param> function CnMonthName(ADate: TDateTime): QStringW; overload; /// <summary>获取指定农历年月的天数</summary> /// <params> /// <param name="Y">农历年份</param> /// <param name="M">农历月份,负数代表闰月</param> /// </params> /// <returns>返回指定农历年月的天数</returns> function CnMonthDays(Y: Word; M: Shortint): Byte; /// <summary>获取指定阳历日期的农历日</summary> /// <params> /// <param name="ADate">阳历日期</param> /// </params> /// <returns>返回指定的农历日</returns> function CnDayOf(ADate: TDateTime): Shortint; overload; /// <summary>获取指定农历日期的中文名称</summary> /// <params> /// <param name="ADate">农历日期</param> /// </params> /// <returns>返回指定日期的日的中文名称</returns> function CnDayName(ADate: TCnDate): QStringW; overload; /// <summary>获取指定阳历日期对应农历日期日的中文名称</summary> /// <params> /// <param name="ADate">阳历日期</param> /// </params> /// <returns>返回指定日期的日的中文名称</returns> function CnDayName(ADate: TDateTime): QStringW; overload; /// <summary>获取指定小时的时刻名称</summary> /// <params> /// <param name="AHour">小时数,取值范围0-23</param> /// </params> /// <returns>返回中文的小时对应的时刻名称(子、丑等)</returns> function CnHourName(AHour: Byte): QStringW; overload; /// <summary>获取指定的农历日期的属相名称</summary> /// <params> /// <param name="ADate">农历日期</param> /// </params> /// <returns>返回指定的农历年份对应的属相名称</returns> function CnAnimalOf(ADate: TCnDate): QStringW; overload; /// <summary>获取指定的阳历日期的属相名称</summary> /// <params> /// <param name="ADate">阳历日期</param> /// </params> /// <returns>返回指定的阳历年份对应的属相名称</returns> function CnAnimalOf(ADate: TDateTime): QStringW; overload; /// <summary>获取指定年份相应节气对应的阳历日期</summary> /// <params> /// <param name="AYear">农历年份</param> /// <param name="AName">节气名称</param> /// </params> /// <returns>返回对应的阳历日期</returns> function DateOfCnSolarTerm(AYear: Smallint; AName: QStringW) : TDateTime; overload; /// <summary>获取指定阳历日期对应的节气序号</summary> /// <params> /// <param name="AYear">阳历年份</param> /// <param name="AMonth">阳历月份</param> /// <param name="ADay">阳历日</param> /// </params> /// <returns>返回节气序列,如果不是任何节气,返回0</returns> function CnSolarTerm(AYear, AMonth, ADay: Word): Shortint; overload; /// <summary>获取指定农历日期对应的节气序号</summary> /// <params> /// <param name="AYear">农历年份</param> /// <param name="AMonth">农历月份</param> /// <param name="ADay">农历日</param> /// </params> /// <returns>返回节气序列,如果不是任何节气,返回0</returns> function CnSolarTerm(ADate: TCnDate): Shortint; overload; /// <summary>获取指定阳历日期对应的节气序号</summary> /// <params> /// <param name="ADate">阳历日期</param> /// </params> /// <returns>返回节气序列,如果不是任何节气,返回0</returns> function CnSolarTerm(ADate: TDateTime): Shortint; overload; /// <summary>获取指定农历日期对应的节气名称</summary> /// <params> /// <param name="ADate">农历日期</param> /// </params> /// <returns>返回节气名称,如果不属于任何节气,返回空字符串</returns> function CnSolarTermName(ADate: TCnDate): QStringW; overload; /// <summary>获取指定阳历日期对应的节气名称</summary> /// <params> /// <param name="ADate">阳历日期</param> /// </params> /// <returns>返回节气名称,如果不属于任何节气,返回空字符串</returns> function CnSolarTermName(ADate: TDateTime): QStringW; overload; /// <summary>获取指定日期在相应的农历年份中的周次</summary> /// <params> /// <param name="ADate">阳历日期</param> /// </params> /// <returns>返回周次</returns> function CnWeeksInYear(const ADate: TDate): Byte; /// <summary>增加指定的农历的年数</summary> /// <params> /// <param name="ADate">当前日期</param> /// <param name="ADelta">增量</param> /// </params> /// <returns>返回增加或减少(负增量)的年数后的农历日期</returns> function CnIncYear(ADate: TCnDate; ADelta: Integer = 1): TCnDate; /// <summary>增加指定的农历的月数</summary> /// <params> /// <param name="ADate">当前日期</param> /// <param name="ADelta">增量</param> /// </params> /// <returns>返回增加或减少(负增量)的月数后的农历日期</returns> function CnIncMonth(ADate: TCnDate; ADelta: Integer = 1): TCnDate; /// <summary>增加指定的农历的天数</summary> /// <params> /// <param name="ADate">当前日期</param> /// <param name="ADelta">增量</param> /// </params> /// <returns>返回增加或减少(负增量)的月数后的农历日期</returns> function CnIncDay(ADate: TCnDate; ADelta: Integer = 1): TCnDate; |
在Andriod程序中输出日志到Windows的QLogServer查看
大家知道日志是我们调试程序的一种重要方式,QDAC的QLog提供了一种异步的日志记录方式,以尽量减少到系统系统性能的影响。而且QLog支持Syslog协议输出,可以将日志输出给其它的syslogd兼容的日志查看器。当然为了方便大家,QDAC实现了一个自己的QLogServer,使用标准的UDP协议514端口来记录日志。