<?xml version="1.0" encoding="gb2312"?>
<rss version="2.0">
<channel>
<title><![CDATA[碧水航工作室]]></title>
        <image>
        <title>http://hi.baidu.com</title>
        <link>http://hi.baidu.com</link>
        <url>http://img.baidu.com/img/logo-hi.gif</url>
        </image>
<description><![CDATA[专注IT软件技术！]]></description>
<link>http://hi.baidu.com/tintinsoft</link>
<language>zh-cn</language>
<generator>www.baidu.com</generator>
<ttl>5</ttl>


<item>
        <title><![CDATA[TValue 复杂参数应用]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/95230516b521e11e4b90a7c7.html]]></link>
        <description><![CDATA[
		
		<p>TValue大概是新RTTI最重要最抽象的类！说他复杂，因为他是新版的万能变体类型，但比 Variant类型多带了RTTI类型信息。</p><p>在执行方法中，遇到复杂的参数类型（比如 record ）必须带上RTTI类型信息。</p><p>例子如下：</p><p>type<br />&nbsp; <strong>TMsgInfo&nbsp;</strong>=&nbsp; record<br />&nbsp;&nbsp;&nbsp; MsgInfo:string;<br />&nbsp;&nbsp;&nbsp; MsgID:Integer;<br />&nbsp; end;<br />&nbsp; TForm1 = class(TForm)<br />&nbsp;&nbsp;&nbsp; Button1: TButton;<br />&nbsp;&nbsp;&nbsp; procedure Button1Click(Sender: TObject);<br />&nbsp; private<br />&nbsp;&nbsp;&nbsp; { Private declarations }<br />&nbsp; public<br />&nbsp;&nbsp;&nbsp;<strong>procedure ShowMsg(MsgInfo:TMsgInfo);<br /></strong>&nbsp; end;</p><p>&nbsp;</p><p>procedure TForm1.<strong>ShowMsg</strong>(MsgInfo: TMsgInfo);<br />begin<br />&nbsp; ShowMessageFmt('ID:%d Msg:%s',[MsgInfo.MsgID,MsgInfo.MsgInfo]);<br />end;</p><p>&nbsp;</p><p>RTTI 执行调用：</p><p>procedure TForm1.Button1Click(Sender: TObject);<br />var<br />&nbsp; RT:TRttiType;<br />&nbsp; RM:TRttiMethod;<br />&nbsp; MsgInfo:TMsgInfo;<br />&nbsp; Value:TValue;<br />begin<br />&nbsp; RT := TRttiContext.Create.GetType(TypeInfo(TForm1));</p><p>&nbsp; RM := RT.GetMethod('ShowMsg');<br />&nbsp; if RM&lt;&gt;nil then<br />&nbsp; begin<br />&nbsp;&nbsp;&nbsp; MsgInfo.MsgID := 100000;<br />&nbsp;&nbsp;&nbsp; MsgInfo.MsgInfo := 'SEWGWEG';</p><p>&nbsp;&nbsp; // 构造 TValue 复杂参数</p><p>&nbsp;&nbsp;&nbsp; TValue.<strong>Make</strong>(@MsgInfo,<strong>TypeInfo</strong>(TMsgInfo),Value);<br />&nbsp;&nbsp;&nbsp; RM.Invoke(self,[Value]);<br />&nbsp; end;<br />end;</p> <a href="http://hi.baidu.com/tintinsoft/blog/item/95230516b521e11e4b90a7c7.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/95230516b521e11e4b90a7c7.html#comment">查看评论</a>]]></description>
        <pubDate>2012-02-23  17:45</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/95230516b521e11e4b90a7c7.html</guid>
</item>

<item>
        <title><![CDATA[丢人的CSDN]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/addc8a8ec8c854e4503d9247.html]]></link>
        <description><![CDATA[
		
		<p>CSDN 数据库被黑客公布泄露，2000万注册用户密码因为明文而泄露。多少程序员在CSDN的积分和博客都受影响！</p><p>丢人的CSDN，就这么点技术和管理水平，还号称中国程序员大本营!</p><p>鄙视！！！下面图片是群里发布的！</p><p><span><img src="http://hiphotos.baidu.com/tintinsoft/pic/item/dddeba8a87d6277f05b8007428381f30e824fc30.jpg" small="0" /></span><br /></p> <a href="http://hi.baidu.com/tintinsoft/blog/item/addc8a8ec8c854e4503d9247.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/addc8a8ec8c854e4503d9247.html#comment">查看评论</a>]]></description>
        <pubDate>2011-12-21  17:40</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/addc8a8ec8c854e4503d9247.html</guid>
</item>

<item>
        <title><![CDATA[诡异的匿名方法动态绑定事件！]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/365e9b0b35d2a922b0351d62.html]]></link>
        <description><![CDATA[
		
		<p>总有一些Delphi老粉丝，经常口出狂言：D7以来delphi都没什么进步，所以一直在用D7！</p>
<p>因为程序员具有一种深入骨髓的惰性，与年龄日益增长，懒惰和保守遮住了delphi在细节上无微不至的进步！</p>
<p>&nbsp;</p>
<p>关于动态绑定事件，老版本当然也可以实现，一个是实现相同的参数名称，直接赋值；另外一个是用TMethod.Code和TMethod.data动态绑定事件，也许还有其他方法，但是，D7是不能用匿名方法来动态绑定事件。Delphi XE 完美实现了匿名方法来动态绑定事件，而匿名方法和事件一起绑定，在程序代码上感觉是一体的；当然，如果匿名方法很长，可以单独声明！</p>
<p>下面请看动态绑定 TEdit.OnChage事件：</p>
<p>///动态绑定 Tedit事件<br />&nbsp; @edt1.OnChange :=<br />&nbsp;&nbsp; pPointer(Cardinal(pPointer(<br />&nbsp;&nbsp;&nbsp;&nbsp; procedure (sender: tObject)<br />&nbsp;&nbsp;&nbsp;&nbsp; begin<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((sender as TEdit).Owner as TForm).Caption :=<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (sender as TEdit).Text;<br />&nbsp;&nbsp;&nbsp;&nbsp; end )^ ) + $0C)^;</p>
<p>&nbsp;</p>
<p>//复杂点事件参数，比如窗体的OnQuery事件</p>
<p>@Self.OnCloseQuery :=<br />&nbsp;&nbsp;&nbsp; pPointer(Cardinal(pPointer(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; procedure (Sender: TObject; var CanClose: Boolean)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CanClose := Application.MessageBox('你确定要关闭主窗口吗？','关闭提示',MB_OKCANCEL+MB_ICONQUESTION) = IDOK;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end )^ ) + $0C)^;</p>
<p>运行效果图：</p>
<p><span><img src="http://hiphotos.baidu.com/tintinsoft/pic/item/50a41909e8502fa163d98691.jpg" small="0" /></span><br /></p> <a href="http://hi.baidu.com/tintinsoft/blog/item/365e9b0b35d2a922b0351d62.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/365e9b0b35d2a922b0351d62.html#comment">查看评论</a>]]></description>
        <pubDate>2011-09-29  11:05</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/365e9b0b35d2a922b0351d62.html</guid>
</item>

<item>
        <title><![CDATA[CIS SMTP 发邮件之解决中文乱码问题]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/26069611072b331d203f2eda.html]]></link>
        <description><![CDATA[
		
		<p>CIS 是一套很不错的商业internet组件，简单强大易用。需要注意的是，有一个开源版本的ICS，和它命名非常相似！</p>
<p>其中有个CIS SMTP 发送邮件的例子，发送中文邮件，乱码很厉害！</p>
<p><span><img src="http://hiphotos.baidu.com/tintinsoft/pic/item/dd093c7e91d79a672a388a2c.jpg" small="0" /></span></p>
<p><span>其实只要指定编码格式，<strong>黑体</strong>的部分，中文乱码即可解决！</span></p><span>
<p><span>uses clEncoder;</span></p></span>
<p>&nbsp;</p>
<p>procedure TForm1.btnSendClick(Sender: TObject);<br />begin<br />&nbsp; if (clSmtp1.Active) then Exit;</p>
<p>&nbsp; clSmtp1.Server := edtServer.Text;<br />&nbsp; clSmtp1.Port := StrToInt(edtPort.Text);</p>
<p>&nbsp; clSmtp1.UserName := edtUser.Text;<br />&nbsp; clSmtp1.Password := edtPassword.Text;</p>
<p>&nbsp; if cbUseTLS.Checked then<br />&nbsp; begin<br />&nbsp;&nbsp;&nbsp; clSmtp1.UseTLS := ctAutomatic;<br />&nbsp; end else<br />&nbsp; begin<br />&nbsp;&nbsp;&nbsp; clSmtp1.UseTLS := ctNone;<br />&nbsp; end;</p>
<p>&nbsp; clSmtp1.Open();<br />&nbsp; try<br />&nbsp;&nbsp;&nbsp; <strong>clMailMessage1.CharSet := 'UTF-8';</strong>//请注意，，UTF-8写法很混乱，如果写成 UTF8，那是很杯具！<br />&nbsp;&nbsp;&nbsp; <strong>clMailMessage1.Encoding :=&nbsp; cmBase64;</strong> //加密方式</p>
<p>&nbsp;&nbsp;&nbsp; clMailMessage1.BuildMessage( memBody.Text, '');<br />&nbsp;&nbsp;&nbsp; clMailMessage1.From.FullAddress := edtFrom.Text;<br />&nbsp;&nbsp;&nbsp; clMailMessage1.ToList.EmailAddresses := edtTo.Text;<br />&nbsp;&nbsp;&nbsp; clMailMessage1.Subject := edtSubject.Text;</p>
<p>&nbsp;&nbsp;&nbsp; clSmtp1.Send(clMailMessage1);</p>
<p>&nbsp;&nbsp;&nbsp; ShowMessage('The message was sent successfully.');<br />&nbsp; finally<br />&nbsp;&nbsp;&nbsp; clSmtp1.Close();<br />&nbsp; end;<br />end;</p>
<p>&nbsp;</p>
<p>运行示例图：</p>
<p><span><img src="http://hiphotos.baidu.com/tintinsoft/pic/item/63cda81ab16366768718bfe6.jpg" small="0" /></span><br /></p>
<p>在foxmail浏览邮件，正常显示：</p>
<p><span><img src="http://hiphotos.baidu.com/tintinsoft/pic/item/c4f01c093870815fe82488fc.jpg" small="0" /></span><br /></p> <a href="http://hi.baidu.com/tintinsoft/blog/item/26069611072b331d203f2eda.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/26069611072b331d203f2eda.html#comment">查看评论</a>]]></description>
        <pubDate>2011-09-25  16:41</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/26069611072b331d203f2eda.html</guid>
</item>

<item>
        <title><![CDATA[delphi XE2 RTTI  研究之 TRttiIndexedProperty！]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/f20ce61e5b4cb811314e1517.html]]></link>
        <description><![CDATA[
		
		<p>无论你承认或否定，狂欢或轻视，XE2发布是一个具有里程碑的意义，其重要性仅亚于 Delphi 1 ！</p>
<p>Delphi XE2 不仅带来一个全新的 2D/3D UI 框架，跨平台IOS，其他方面的改进也是不容小视，比如 RTTI的日趋完善。新版本的XE2支持了 TRttiIndexedProperty 和 加强RTL的反射（支持WIN32/WIN64/MAC）！</p>
<p>&nbsp;</p>
<p>Delphi有一种特殊的属性值，叫索引属性，常见的 TCollection 类的 Items[Index] 就是索引属性，在D2010/XE版本中，常常为RTTI 不能反射此属性而抱憾和愤青！今天，XE2版本终于可以反射此属性了。比如针对TDBGrid.TDBGridColumns 凭此功能，我们可以轻松反射其l索引属性(列的标题)并做出多国语言功能。</p>
<p>&nbsp;uses System.RTTI;</p>
<p>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; RX:TRttiContext;<br>&nbsp; RT:TRttiType;<br>&nbsp; RP:TRttiProperty;<br>&nbsp; RIP:TRttiIndexedProperty;<br>&nbsp; Value:TValue;<br>&nbsp; i,iCount:Integer;<br>&nbsp; Col:TColumn;<br>begin<br>&nbsp; RX := TRttiContext.Create;<br>&nbsp; RT := RX.GetType(TDBGridColumns.ClassInfo);<br>&nbsp; RP := RT.GetProperty('Count');<br>&nbsp; iCount := RP.GetValue(DBGrid1.Columns).AsInteger;</p>
<p>&nbsp; for RIP in RT.GetIndexedProperties do<br>&nbsp; begin<br>&nbsp;&nbsp;&nbsp; if RIP.PropertyType.Handle = TypeInfo(TColumn) then<br>&nbsp;&nbsp;&nbsp; begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ListBox1.Items.Add(RIP.Name+ ':'+RIP.ToString);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for I := 0 to iCount - 1 do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Value := RIP.GetValue(DBGrid1.Columns,[i]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Col := Value.AsObject as TColumn;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ListBox1.Items.Add(Col.Title.Caption);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<br>&nbsp;&nbsp;&nbsp; end;<br>&nbsp; end;</p>
<p>end;</p>
<p>运行效果图</p>
<p><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/8bcc68f1c8d860c2a60f5243.jpg" small="0"></span><br></p>
<p>&nbsp;</p> <a href="http://hi.baidu.com/tintinsoft/blog/item/f20ce61e5b4cb811314e1517.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/f20ce61e5b4cb811314e1517.html#comment">查看评论</a>]]></description>
        <pubDate>2011-09-04  19:07</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/f20ce61e5b4cb811314e1517.html</guid>
</item>

<item>
        <title><![CDATA[解决 Delphi XE (2010，2009) 里的UTF8乱码问题！]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/e3e78051e85ca674843524f1.html]]></link>
        <description><![CDATA[
		
		<p>Delphi 后续 Unicode&nbsp;版本中，&nbsp;一些单元里碰到UTF8编码字符，如果我们可能没有安装西欧的一些字符集，单元有可能显示错误，用delphi右键菜单 File Format-&gt;UTF8也未必能修复好。</p>
<p>如图：</p>
<p><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/b3fba398f14416506f068c1a.jpg" small="0"></span><br></p>
<p>正是因为 Delphi 单元不认识UTF8字符集，导致单引号被吃掉，编译异常！</p>
<p>&nbsp;</p>
<p>这个时候，千万不要随便修改或保存该单元文件。将该单元拖到 NodePad++里，在 NodePad++ 菜单-&gt;格式-&gt;以UTF8显示，即可看到这样的效果，UTF8字符编码马上原形毕露（如图：xC0，xFF， 记住这是十六进制，是零而不是大写字母的O）：</p>
<p><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/035da9b67be556ac30add1e4.jpg" small="0"></span></p>
<p><span></span>&nbsp;</p>
<p><span>以 #$ 打头，修正如下：</span></p>
<p><span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/fe1d661fdc7254ac1ad576c5.jpg" small="0"></span><br></span></p>
<p><span>如果是char字符，则改为&nbsp; #$00C0和&nbsp;#$00FF，记住多两个零。</span></p>
<p><span>如果是ansi</span><span>char，则改为 #$C0和&nbsp;#$FF。</span></p>
<p><span>我经历的一些控件： ICS 7.0,&nbsp;SynEdit, Database Comparer VC 都有这个UTF8编码问题。</span></p>
<p><span>摆平她们，然后享受她们！</span></p>
<p><br></p>
<p>&nbsp;</p> <a href="http://hi.baidu.com/tintinsoft/blog/item/e3e78051e85ca674843524f1.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/e3e78051e85ca674843524f1.html#comment">查看评论</a>]]></description>
        <pubDate>2011-04-19  23:27</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/e3e78051e85ca674843524f1.html</guid>
</item>

<item>
        <title><![CDATA[我们永远优雅，但绝不炫耀：合并BPL包图文教程！]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/40934a0edac6373f6159f351.html]]></link>
        <description><![CDATA[
		
		<p>&nbsp;Delphi IDE 本身就是一个插件模式的工具，插件的好处不用多说。运行包的BPL，其实就是众多单元的集合，因此可以再次重新组合，只要你将各个BPL包用到的单元再组合一次！<span></span><br></p>
<p>本文以&nbsp; <a href="http://code.google.com/p/tangram-plugin-framework/">http://code.google.com/p/tangram-plugin-framework/</a>&nbsp;插件框架自带的BPL包合并向导工具做一次图文介绍！</p>
<p>&nbsp;</p>
<p>1、安装好开源插件框架 tangram-plugin后，然后点击 菜单 File-&gt;New-&gt;Others，找到tangram FrameWork里的包合并向导，</p>
<p><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/e8ce8812b87539d66438db26.jpg" small="0"></span></p>
<p><span>2、Dev控件堪称独孤求败，最强也是最肥的数据库解决方案。我们以Dev套件包为准，合并Dev几十个BPL包为一个BPL包。</span></p>
<p><span>这里用到dev功能是cxGirid，treelist和垂直表格，如果用到其他的功能，涉及的BPL会有所不同！</span></p>
<p><span><span><img class="blogimg" src="http://hiphotos.baidu.com/tintinsoft/pic/item/2952b2769338404db151b906.jpg" small="0"></span></span></p>
<p><span><span>选择单元</span></span></p>
<p><span><span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/c2fd690feecd249c7acbe112.jpg" small="0"></span></span></span></p>
<p><span><span><span>3、生成DPK工程，改名为Dev.BPL，记得保存。DPK文件如果没有生成，请先带一个空白工程，然后再用向导生成DPK，即重复上面的步骤。生成DPK后，再移除原来的DPR工程。</span></span></span></p>
<p><span><span><span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/1beb8c0b681fd64994ca6bec.jpg" small="0"></span></span></span></span></p>
<p><span><span><span><span>4、有可能碰到重复的单元，已经在别的包被引用了，我们的原则是，只封装Dev的单元。</span></span></span></span></p>
<p><span><span><span><span>（Dev的单元名好区分，都是以cx或dx打头。）比如sysInit，在 contains 按 CTRL+Y删除即可。</span></span></span></span></p><span><span><span><span></span>
<p><br></span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/63cda81a1c0d0b4f8718bff0.jpg" small="0"></span></p>
<p><span>5、编译会提示，我们新的Dev包，引用到其他单元，在不同的BPL里。选择View details可以查看引用到详细单元。</span></p>
<p><span>按“OK”按钮，将引用到的其他包名（BPL），记录在 Dev.DPK里的require 区域。</span></p>
<p><span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/e3cdd3fdafb430abfd037fd5.jpg" small="0"></span></span></p>
<p><span><span>6、输出BPL和DCP目录，最好是当前目录下，否则又要去delphi的DCP和BPL目录查找，太麻烦。这两个目录输入“点”字符：“.”，表示当前路径。</span></span></p>
<p><span><span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/e9c39c00171b7480267fb5ac.jpg" small="0"></span><br></span>7、按Build 编译，生成Dev.BPL和Dev.DCP在当前路径下。新的Dev.BPL为 9M左右，比杨玉环还肥。<br></span><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/31bf17326be618ae1b4cffbe.jpg" small="0"></span><br><br>8、我们用ASPACK给BPL减肥一下，大概可以压缩到只有53%大小，只有4M多，减肥效果明显。<span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/8bcc68f113afa9f9a50f5280.jpg" small="0"></span><br>9、我们做一个简单的例子，将新的BPL和DCP放在EXE当前目录下。配置工程选项，选择Packages，在Build with runtime packages里输入</p>
<p>vcl;rtl;dev。这里必须要说一下 vcl;rtl 这两个包是delphi的核心运行包，尤其是基于DLL插件的框架，如果带包编译，必须少不了这2个包。引用vcl;rtl 这2个包，避免了很多DLL的麻烦和痛苦，如焦点切换，application共享等问题。</p>
<p><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/8326cc2b92bfd67bd62af17a.jpg" small="0"></span></p>
<p>运行后，程序正确。新的EXE只有700K不到，经过ASPACK压缩后，只有200多K。<br></p>
<p><span><img class="blogimg" border="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/0b059aca451d45ab53664f99.jpg" small="0"></span><br></p>
<p>点评：BPL合并方式，简化了发布程序带来的痛苦，可以将系统的BPL和第三方的BPL各自合并。新的BPL并不影响原来的BPL或者第三方控件的开发环境，这只是运行包而已，在发布的时候带上即可。任何绿色插件程序文件，一般都会放在当前目录，尽量避免丢到syste32目录，这是微软windows的一个操作恶习，将系统目录当成垃圾桶。delphi的插件模式简单而透明，不会依赖系统，相反，.Net 4.0自带的发布版FrameWork，40多M，安装后目录上百兆，而且狂写系统注册表。.Net框架不会给你绿色试用，这已经违背了绿色软件的原则。注册表臃肿的后果，windows会越来越慢。&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 相信原生程序和托管程序之争会一直延续下去。.net似乎已经没有搞头，只有不停在语法上折腾，而折腾的后果，导致程序兼容性不够好（兼容性比JDK差多了）。如果你的操作系统自带了众多.Net 版本呢：1.0/1.1/2.0/3.0/3.5/4.0........XXX.0，每个.Net版本还有小版本号，诸如SP1，SP2，SP3等，请不要奇怪。未来的windows8/windows9/WIN X。。。。，Net框架加上加上几万种的驱动程序，windows上百G安装大小并不奇怪。.Net发布复杂性还在于捆绑在操作系统上，有些特殊功能必须在windows上配置，而且需要管理员的权限。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 简单而简洁，这是一切应用程序的基本要求。微软，请不要将.net 演变成 COM/COM+，请给我们一个简单而简洁，高效又安全的操作系统环境！</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br></p></span></span>
<p><br>&nbsp;</p> <a href="http://hi.baidu.com/tintinsoft/blog/item/40934a0edac6373f6159f351.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/40934a0edac6373f6159f351.html#comment">查看评论</a>]]></description>
        <pubDate>2011-04-05  19:30</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/40934a0edac6373f6159f351.html</guid>
</item>

<item>
        <title><![CDATA[Delphi XE 随想]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/f7eb42831d9685b00df4d270.html]]></link>
        <description><![CDATA[
		
		<div style="LAYOUT-GRID:  15.6pt none" class="Section0">
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span style="FONT-SIZE: 14px">&nbsp;&nbsp;&nbsp; 去年写的一篇文章《</span><span><span style="FONT-SIZE: 14px">Delphi2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">发布日。。。</span></span><span style="FONT-SIZE: 14px">》，引起了众多</span><span><span style="FONT-SIZE: 14px">delphi&nbsp;fans</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">的一些共鸣！</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">确实是一件里程碑的重大事件！</span></span></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px"></span></span>&nbsp;</p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-SIZE: 14px">&nbsp;&nbsp;&nbsp; 今年</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">8</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">月</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">Delphi&nbsp;Xe</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">悄悄来了，但似乎没有像</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">delphi2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">那么反响大！</span></span></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px"></span></span>&nbsp;</p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-SIZE: 14px">&nbsp;&nbsp;&nbsp; 在我看来，</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">delphi&nbsp;XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">只是</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">的</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">SP6</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">补丁，既然是补丁，稳定性肯定更好，只是没有太多的新鲜亮点！</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">修复最多的还是泛型问题，以及</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">VCL</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">类库和</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">RTL</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">核心。</span></span></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px"></span></span>&nbsp;</p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-SIZE: 14px">&nbsp;&nbsp;&nbsp; Delphi&nbsp;XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">最大亮点是</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">Builder&nbsp;</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">速度比</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">快了一倍左右，</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">Code&nbsp;Inside</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">功能比</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">快，这个还做的真不错！</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">完全兼容</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">，稳定性也不错，应该是</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">最佳替代品！如果非要在硬盘上只能留一个</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">delphi</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">版本，那只能是</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">Delphi&nbsp;XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">！谁叫他那么邪恶呢？</span></span></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px"></span></span>&nbsp;</p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-SIZE: 14px">&nbsp;&nbsp;&nbsp; 只是，令人惋惜的是，</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">的</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">RTTI</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">开辟了一个新天地，在</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">中竟然没有得到发展或修正问题。诸如，</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">的</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">RTTI</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">还不支持&nbsp;类属性、常量、数组属性等。</span></span></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px"></span></span>&nbsp;</p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-SIZE: 14px">&nbsp;&nbsp;&nbsp;&nbsp;根据发展路线图看，</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">delphi&nbsp;XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">本来承载跨平台的伟大任务，估计人手问题，加上</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">CodeGear</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">产品阵线太庞大，应接不暇，导致不得不在后期在</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">砍掉跨平台内容！</span></span></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px"></span></span>&nbsp;</p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-SIZE: 14px">&nbsp;&nbsp;&nbsp; 在我看来，</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">delphi&nbsp;XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">是</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">Win32&nbsp;+&nbsp;Unicode&nbsp;</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">最后一个经典版本，之后便进入了</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">Win64+</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">跨平台</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">+</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">多核多线程时代！微软估计也不想看到这样的结果，不过，谁叫微软丢了原生语言开发而去捡了“托管语言平台”这个烂芝麻呢！再说一下微软，在</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">VS2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">中，微软终于有点醒悟了，增强了对</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">VC2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">的原生语言开发。只是令人搞笑的是，</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">VC2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">终于有了</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">Ribbon</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">菜单的可视化开发，这等小事，竟然大肆渲染！</span></span></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px"></span></span>&nbsp;</p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-SIZE: 14px">&nbsp;&nbsp;&nbsp; 再说一下易博龙的销售问题！随着中国</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">delphi&nbsp;fans</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">老去，新人接不上来，</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">delphi</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">人才变得青黄不接！更令人叹息的是，易博龙还实行价格歧视政策（跟</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">ThinkPad</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">有的一比），</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">2999</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">美元企业版的价格在大陆要卖</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">3-4</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">万一套，比较低廉的个人版和专业版不能再大陆售卖。要说易博龙中国能做点服务也可以值这个钱了，但是，一来没有中文版帮助或其他汉化的文献，二来所谓的服务只是一手交钱一手交货的服务，真不知道易博龙中国存在的理由是什么。</span></span></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px"></span></span>&nbsp;</p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-SIZE: 14px">&nbsp;&nbsp;&nbsp; 而易博龙所谓的增值计划，都是买新产品送老产品，诸如买</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">送</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2010/D2007</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">，这又不是天朝冰箱里冻了一年的猪肉的那么值钱，实在令人哭笑不得！一年一个版本的发展计划，让购买者犹豫不决，而易博龙开发者疲以奔命新项目开发和不断出现的</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">Bug</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">。</span></span></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px"></span></span>&nbsp;</p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-SIZE: 14px">&nbsp;&nbsp;&nbsp; 如果你想购买</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">delphi&nbsp;</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">新版本，</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">倒是不错的选择，支持泛型、</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">RTTI</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">反射、</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">Unicode</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">，你用过了就不会再缅怀经典的</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D7</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">版本！如果你买了</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">，不想再升级到</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">的话，我还是鼓励你使用盗版的</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">，放弃</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">。你可以有理由跟他们说，把一个属于</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2010</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">的补丁当做新产品来卖，你是不甘心的。如果你还一直使用</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D7</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">的话，建议你起码要升级到</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2007</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">，因为</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D2007</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">是</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">win32+ansi</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">的最后经典版本，完全兼容</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">D7</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">！当然，要跟上世界潮流，建议你试试一下</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">XE</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">盗版。当然，如果你做软件发财了，良心发现一下吧，支持一下正版吧！</span></span></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px"></span></span>&nbsp;</p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span style="FONT-SIZE: 14px">&nbsp;&nbsp;&nbsp; 其实真的非常希望易博龙能调整销售策略，与其维持大陆惨淡的销售人气，不如一视同仁，北美和大陆一个价格、一种销售方案；培养和留住开发人员，这才是立足之本！</span></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span style="FONT-SIZE: 14px"></span>&nbsp;</p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-SIZE: 14px">&nbsp;&nbsp;&nbsp; 当企业级应用越来越要求更高更好的体验，当浏览器像老牛慢车一样扛不住</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">BS</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">的胖客户端应用，假以时日，内存条越来越便宜，个人电脑</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">8G-16G</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">内存比比皆是，</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">WIN64</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">迅速推广开了，桌面三层的企业级应用会推向一个新的高潮！请相信，</span><span style="FONT-FAMILY: Times New Roman; FONT-SIZE: 14px">Delphi</span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px">还会迎来一个美好的明天！</span></span></p>
<p style="MARGIN-TOP: 0pt; MARGIN-BOTTOM: 0pt" class="p0"><span><span style="FONT-FAMILY: 宋体; FONT-SIZE: 14px"></span></span>&nbsp;</p></div> <a href="http://hi.baidu.com/tintinsoft/blog/item/f7eb42831d9685b00df4d270.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/f7eb42831d9685b00df4d270.html#comment">查看评论</a>]]></description>
        <pubDate>2010-12-31  23:06</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/f7eb42831d9685b00df4d270.html</guid>
</item>

<item>
        <title><![CDATA[解决“trying to modify read-only Field”问题！]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/55fb59a61b8c749ad04358cb.html]]></link>
        <description><![CDATA[
		
		<p>后台使用SQL语句中，经常会关联<strong>自定义函数</strong>或<strong>视图</strong>，而CDS(TClientDataSet)对字段校验比较严格，涉及到的自定义函数或视图输出的字段，都会强制改为ReadOnly为True属性。</p>
<p>当后台使用UniDAC+CDS，关联视图或自定义函数，为了<strong>数据一致性</strong>，有可能需要在前台界面上<strong>修改</strong>CDS相关的自定义函数<strong>输出的字段</strong>，即便是将 该字段设置为 <strong>readonly</strong>为<strong>false</strong>，或将其字段的 <strong>FieldDefs</strong>属性的<strong>attributes</strong>的<strong>faReadOnly</strong>去掉，系统也会抛出一个异常：trying to modify read-only Field。</p>
<p><span><img class="blogimg" border="0" small="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/f91367d8e0e7a3a03b012f45.jpg"><br>
</span></p>
<p>解决问题很简单，将TUniQuery.Options.<strong>SetFieldsReadOnly</strong>为<strong>false</strong>即可。</p>
<p>查一下TUniQuery.Options.<strong>SetFieldsReadOnly的帮助，这样写道：</strong></p>
<p>If True, dataset sets the ReadOnly property to True for all fields that do not belong to UpdatingTable or can not be updated. Set this option for datasets that use automatic generation of the update SQL statements only.</p>
<p> </p>
<p> </p> <a href="http://hi.baidu.com/tintinsoft/blog/item/55fb59a61b8c749ad04358cb.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/55fb59a61b8c749ad04358cb.html#comment">查看评论</a>]]></description>
        <pubDate>2010-10-28  23:49</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/55fb59a61b8c749ad04358cb.html</guid>
</item>

<item>
        <title><![CDATA[Remobjects Hydra 与 DevExpress 皮肤兼容问题！]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/380fec02357bbfe209fa9387.html]]></link>
        <description><![CDATA[
		
		<p>DevExpress的皮肤是典型的巨无霸，即使你用插件技术，如果不使用动态皮肤包，每个插件DLL将增肥10M左右。既然是企业级应用，默认的四种皮肤技术也足够了。</p>
<p>移除皮肤包很容易，干脆在菜单Component-&gt;Install Packages直接删除算了（当然也可以将勾选去掉）。</p>
<p>但是使用 Remobjects Hydra + DevExpress（6.52）发现一个问题，dxSkinsCore, dxSkinsDefaultPainters, dxSkinscxPCPainter这四个单元总是阴魂不散附加在interface区域的单元里，删也删除不掉。由于有了这四个莫须有的单元，我又懒得再加载相关的皮肤包，导致每次系统退出时候总是有内存泄露问题。经研究，在菜单-&gt;Project-&gt;Modify Skin Options 设置成如下图</p>
<p><span><span><img class="blogimg" border="0" small="0" src="http://hiphotos.baidu.com/tintinsoft/pic/item/28d117f2019c7b8e0b46e018.jpg"><br>
</span><br>
</span></p>
<p>再删除替换整个工程组（EXE+DLL）的dxSkinsDefaultPainters, dxSkinscxPCPainter四个单元，再也没有内存泄露！</p> <a href="http://hi.baidu.com/tintinsoft/blog/item/380fec02357bbfe209fa9387.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/Remobjects">Remobjects</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/380fec02357bbfe209fa9387.html#comment">查看评论</a>]]></description>
        <pubDate>2010-08-30  23:21</pubDate>
        <category><![CDATA[Remobjects]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/380fec02357bbfe209fa9387.html</guid>
</item>

<item>
        <title><![CDATA[这是一个最好的时代，这也是一个最坏的时代！]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/a6dc89443015a932869473ef.html]]></link>
        <description><![CDATA[
		
		<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  当James宣布追随<u>韦德</u>和<u>波什</u>而加入热火队的时候，这是一个最好的时代，这也是一个最坏的时代，即将上演！骑士队老板<u>丹-吉尔伯特</u>再也掩饰不住沮丧、失望与愤怒，公开&ldquo;诅咒&rdquo;<u>詹姆斯</u>。我们可以体会<u>丹-吉尔伯特</u>的心情，但商业不是NBA的全部，竞技体育后面是梦想、成就、荣辱、团队精神的元素组成。相对于詹姆斯和韦德来说，即便是拿了顶薪6年1.25亿大合同，但对他们的来说，工资只不过是养家糊口，只要拿到总冠军戒指，赞助商、广告等收入汹涌进入口袋。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 乔丹职业在95-98年赛季，公牛队开出了震撼全世界体坛的合同给乔丹，3年一个亿美元，年薪3300多万美元，按照现在的通货膨胀率，  至少年薪5000万美元。整个一年赛季，乔丹赚了8千万美元，成为最富有的体育运动员。如今，詹姆斯+韦德+波什，成为最富有最激情的新三巨头，将会开创一个属于他们未来的最好时代，当然，这也是其他29支队伍最坏的时代！</p> <a href="http://hi.baidu.com/tintinsoft/blog/item/a6dc89443015a932869473ef.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/N%20B%20A">N B A</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/a6dc89443015a932869473ef.html#comment">查看评论</a>]]></description>
        <pubDate>2010-07-09  22:01</pubDate>
        <category><![CDATA[N B A]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/a6dc89443015a932869473ef.html</guid>
</item>

<item>
        <title><![CDATA[SQL SERVER 2005(2008)插入Blob（Image）字段范例]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/dd093c7ec71c540529388a45.html]]></link>
        <description><![CDATA[
		
		<p>一般来说，插入Blob字段数据，多数以在前台程序以流的方式来执行，但有的时候，难免要写后台的SQL语句插入Blob字段数据。在 SQL Server 2000之前的版本，用SQL 插入Blob（TEXT）字段一直是麻烦问题，在SQL SERVER 2005(2008)之后的版本，终于有了极大简化，范例如下：</p>
<p><strong>INSERT</strong> <strong>INTO</strong> E_UserPhoto(UserID, CreateTime,UpdateTime,Photo)<br>
&nbsp;&nbsp;  <strong>SELECT</strong> 7,GETDATE(),GETDATE(),<br>
&nbsp;&nbsp;  * <strong>FROM</strong> <strong><font color="#ff0000">OPENROWSET</font></strong>(<strong><font color="#ff0000">BULK</font></strong> N'<strong><font color="#ff0000">C:\Users\Administrator\Pictures\a.jpg'</font></strong>, <strong>SINGLE_BLOB</strong>) <br>
&nbsp;&nbsp;  as photo</p>
<p>请注意，获取BLOB字段后必须用字段别名命名，如 As Photo，否则会有以下错误：</p>
<p><strong><font color="#ff0000">必须在 FROM 子句中为大容量行集指定相关名称。</font></strong></p>
<p> </p> <a href="http://hi.baidu.com/tintinsoft/blog/item/dd093c7ec71c540529388a45.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/dd093c7ec71c540529388a45.html#comment">查看评论</a>]]></description>
        <pubDate>2010-06-27  11:52</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/dd093c7ec71c540529388a45.html</guid>
</item>

<item>
        <title><![CDATA[巧用Delphi 2010新 RTTI 管理常量(const)！]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/0331266ca40b6bf0421694b9.html]]></link>
        <description><![CDATA[
		
		<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  常量定义(<strong>const</strong>)在D7及D7之前的版本，一般只能在单元里，以全局方式声明和定义。自D7之后的新版本，常量可以放在一个类里声明，比如放在 类的 <strong>public</strong>或<strong>private</strong>里。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  有那么一种常量，你希望常量的<strong>名称</strong>和真实的<strong>常量值</strong>一样，比如，用于作配置文件的常量。当然，如果你不觉得辛苦，一般来说，常量名和常量值逐个敲出来，也无可厚非。但是，如果你还在使用D2010作开发而不发挥新RTTI技术，很显然，你已经Out了，不随波逐流使用新技术，连&ldquo;走马观花&rdquo;赏花的机会也没有。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;  为了方便管理常量，我们需要声明一个记录类型。为啥使用记录类型而不是类呢？因为记录类型不用创建和释放，其次，记录比类更节省系统资源。</p>
<p>&nbsp;&nbsp;&nbsp;  //参数的名称信息，用于常量设置，都是字符串<br>
<strong>TParamName</strong> = <strong>record</strong><br>
&nbsp;&nbsp;&nbsp;  Socket:string;<br>
&nbsp;&nbsp;&nbsp;  System:string;<br>
&nbsp;&nbsp;&nbsp;  DBConfig:string;<br>
&nbsp;&nbsp;&nbsp;  //通讯参数<br>
&nbsp;&nbsp;&nbsp;  ThreadCount:string;<br>
&nbsp;&nbsp;&nbsp;  Port:string;<br>
&nbsp;&nbsp;&nbsp;  SessionLife:string;<br>
&nbsp;&nbsp;&nbsp;  TimeOut:string;<br>
&nbsp;&nbsp;&nbsp;  ZipRate:string;<br>
&nbsp;&nbsp;&nbsp;  Encrypt:string;<br>
&nbsp;&nbsp;&nbsp;  //系统参数<br>
&nbsp;&nbsp;&nbsp;  AutoRun:string;<br>
&nbsp;&nbsp;&nbsp;  SocketLog:string;<br>
&nbsp;&nbsp;&nbsp;  BusinessLog:string;<br>
&nbsp;&nbsp;&nbsp;  DBLog:string;<br>
&nbsp;&nbsp;&nbsp;  //数据库配置<br>
&nbsp;&nbsp;&nbsp;  Server:string;<br>
&nbsp;&nbsp;&nbsp;  Provider:string;<br>
&nbsp;&nbsp;&nbsp;  DataBase:string;<br>
&nbsp;&nbsp;&nbsp;  DBPort:string;<br>
&nbsp;&nbsp;&nbsp;  UserName:string;<br>
&nbsp;&nbsp;&nbsp;  UserPswd:string;<br>
&nbsp;&nbsp;&nbsp;  Pooling:string;<br>
&nbsp;&nbsp;&nbsp;  PoolMax:string;<br>
&nbsp;&nbsp;&nbsp;  PoolMin:string;<br>
&nbsp;&nbsp;&nbsp;  PoolLife:string;<br>
<strong>end;</strong></p>
<p> </p>
<p>------------我们使用一个新的方法管理 记录类型的 RTTI--------------------------------------</p>
<p>uses RTTI;</p>
<p>function TRttiInfo.SetRecordDeftValue(TypeInfoValue, RecValue: Pointer): Boolean;<br>
var<br>
RTX:TRttiContext;<br>
RT:TRttiType;<br>
RF:TRttiField;<br>
iCount:Integer;<br>
begin<br>
Result := False;<br>
try<br>
&nbsp;&nbsp;&nbsp;  RTX := TRttiContext.Create;<br>
&nbsp;&nbsp;&nbsp;  RT := RTX.GetType(TypeInfoValue);<br>
&nbsp;&nbsp;&nbsp;  iCount := 0;<br>
&nbsp;&nbsp;&nbsp;  for RF in RT.AsRecord.GetFields do<br>
&nbsp;&nbsp;&nbsp;  begin<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  RF.SetValue(RecValue,RF.Name);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Inc(iCount);<br>
&nbsp;&nbsp;&nbsp;  end;<br>
&nbsp;&nbsp;&nbsp;  Result := iCount &gt;0;<br>
finally<br>
&nbsp;&nbsp;&nbsp;  RTX.Free;<br>
end;</p>
<p>end;</p>
<p>--------------调用就非常简单，需要指针来辅助参数传输了---------------</p>
<p>var</p>
<p>&nbsp;&nbsp;  SysParamName:TParamName ;//记录声明</p>
<p> </p>
<p>调用：</p>
<p>&nbsp;&nbsp;&nbsp;  RttiInfo.<strong>SetRecordDeftValue</strong>(TypeInfo(TParamName),@SysParamName);</p>
<p>&nbsp;&nbsp;&nbsp;  1、 由于记录类型是一个抽象的类型，没有具体的类型名，因此需要借助 TypeInfo来获取类型信息</p>
<p>&nbsp;&nbsp;  2、通过 @SysParamName 获取指定记录的地址。</p>
<p> </p>
<p>很简单吧，希望能对你有点帮助！</p> <a href="http://hi.baidu.com/tintinsoft/blog/item/0331266ca40b6bf0421694b9.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/0331266ca40b6bf0421694b9.html#comment">查看评论</a>]]></description>
        <pubDate>2010-03-02  09:18</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/0331266ca40b6bf0421694b9.html</guid>
</item>

<item>
        <title><![CDATA[JSon SuperObject 研究2:数据集与JSON对象互转]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/8bcc68f1cc036ca4a40f5288.html]]></link>
        <description><![CDATA[
		
		<p>&nbsp;&nbsp;  JSON不能完全替代XML，但绝对是未来的大势所趋，其优点是简单、体积小、解析更快、解析占用资源更少。在delphi中，数据集是最常用数据存取方式。因此，必须建立JSON与TDataSet之间的互转关系，实现数据之间通讯与转换。值得注意的是，这只是普通的TDataset与JSON之间转换，由于CDS包含了Delta数据包，其数据格式远比普通的TDataset更复杂。下面的程序，或许你有不同的想法，如果你的想法更好更快，欢迎一起讨论。今天是2009年最后的几十分钟，重要的并不是写博客，而是想向大家说一声&ldquo;新年好运，事业有成&rdquo;！</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;  数据集字段信息，是一个完整的字典信息。因此，我们在JSON必须也建立字典信息，才能创建数据集的字段信息。我们设置其JSON信息如下：</p>
<p>&nbsp;&nbsp;  COLS:[字段列表信息]，如：</p>
<p>&quot;Cols&quot;:[{&quot;JsonType&quot;:&quot;integer&quot;,&quot;FieldIndex&quot;:0,&quot;FieldType&quot;:&quot;Integer&quot;,&quot;FieldSize&quot;:0,&quot;FieldName&quot;:&quot;ID&quot;,&quot;Required&quot;:false},{&quot;JsonType&quot;:&quot;string&quot;,&quot;FieldIndex&quot;:1,&quot;FieldType&quot;:&quot;String&quot;,&quot;FieldSize&quot;:100,&quot;FieldName&quot;:&quot;Title&quot;,&quot;Required&quot;:false},{&quot;JsonType&quot;:&quot;variant&quot;,&quot;FieldIndex&quot;:2,&quot;FieldType&quot;:&quot;Blob&quot;,&quot;FieldSize&quot;:0,&quot;FieldName&quot;:&quot;Picture&quot;,&quot;Required&quot;:false}]</p>
<p>数据信息以Data做节点，也是一个数组嵌套记录信息：</p>
<p>&quot;Data&quot;:[记录集信息]</p>
<p>废话少说，直接上代码：</p>
<p>unit uDBJson;</p>
<p>interface<br>
uses<br>
  SysUtils,Classes,Variants,DB,DBClient,SuperObject;</p>
<p>type<br>
  TTableJSon = class</p>
<p>  private<br>
&nbsp;&nbsp;&nbsp;  const cstFieldType = 'FieldType';<br>
&nbsp;&nbsp;&nbsp;  const cstFieldName = 'FieldName';<br>
&nbsp;&nbsp;&nbsp;  const cstFieldSize = 'FieldSize';<br>
&nbsp;&nbsp;&nbsp;  const cstJsonType = 'JsonType';<br>
&nbsp;&nbsp;&nbsp;  const cstRequired = 'Required';<br>
&nbsp;&nbsp;&nbsp;  const cstFieldIndex = 'FieldIndex';</p>
<p>&nbsp;&nbsp;&nbsp;  const cstCols= 'Cols';<br>
&nbsp;&nbsp;&nbsp;  const cstData= 'Data';</p>
<p>  public<br>
&nbsp;&nbsp;&nbsp;  class function JSonFromDataSet(DataSet:TDataSet):string;<br>
&nbsp;&nbsp;&nbsp;  class function CreateFieldByJson(Fields:TFieldDefs;ColsJson:ISuperObject):Boolean;<br>
&nbsp;&nbsp;&nbsp;  class function ImportDataFromJSon(DataSet:TDataSet;DataJson:ISuperObject):Integer;<br>
&nbsp;&nbsp;&nbsp;  class function CDSFromJSon(CDS:TClientDataSet;Json:ISuperObject):Boolean;<br>
&nbsp;&nbsp;&nbsp;  class function GetValue(Json:ISuperObject;const Name:string):Variant;</p>
<p>&nbsp;&nbsp;&nbsp;  class function CreateJsonValue(Json:ISuperObject;const Name:string;const Value:Variant):Boolean;<br>
&nbsp;&nbsp;&nbsp;  class function CreateJsonValueByField(Json:ISuperObject;Field:TField):Boolean;<br>
&nbsp;&nbsp;&nbsp;  class function GetValue2Field(Field:TField;JsonValue:ISuperObject):Variant;<br>
  end;<br>
implementation<br>
uses TypInfo,encddecd;</p>
<p>{ TTableJSon } </p>
<p>class function TTableJSon.CDSFromJSon(CDS: TClientDataSet;<br>
  Json: ISuperObject): Boolean;<br>
var<br>
  ColsJson:ISuperObject;  <br>
begin<br>
  Result := False;<br>
  if Json = nil then<br>
&nbsp;&nbsp;&nbsp;  Exit;<br>
  CDS.Close;<br>
  CDS.Data := Null;<br>
  //创建字段<br>
  ColsJson := Json.O[cstCols];<br>
  CreateFieldByJson(CDS.FieldDefs,ColsJson);<br>
  if CDS.FieldDefs.Count &gt;0 then<br>
&nbsp;&nbsp;&nbsp;  CDS.CreateDataSet;<br>
  ImportDataFromJSon(CDS,Json.O[cstData]);<br>
  Result := True;<br>
end;</p>
<p>class function TTableJSon.CreateFieldByJson(Fields: TFieldDefs;<br>
  ColsJson: ISuperObject): Boolean;<br>
var<br>
  SubJson:ISuperObject;<br>
  ft:TFieldType;<br>
begin<br>
  Result := False;<br>
  Fields.DataSet.Close;<br>
  Fields.Clear;<br>
  for SubJson in ColsJson do<br>
  begin<br>
&nbsp;&nbsp;&nbsp;  ft := TFieldType(GetEnumValue(TypeInfo(TFieldType),'ft'+SubJson.S[cstFieldType]));<br>
&nbsp;&nbsp;&nbsp;  if ft= ftAutoInc then  //自增字段不能录入，必须更改<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ft := ftInteger;<br>
&nbsp;&nbsp;&nbsp;  Fields.Add(SubJson.S[cstFieldName],ft,SubJson.I[cstFieldSize],SubJson.B[cstRequired]);<br>
  end;<br>
  Result := True;<br>
end;</p>
<p>class function TTableJSon.CreateJsonValue(Json: ISuperObject;<br>
  const Name: string; const Value: Variant): Boolean;<br>
begin<br>
  Result := False;<br>
  Json.O[Name] := SO(Value);<br>
  Result := True;<br>
end;</p>
<p>class function TTableJSon.CreateJsonValueByField(Json: ISuperObject;<br>
  Field: TField): Boolean;<br>
begin<br>
  Result := False;<br>
  if Field Is TDateTimeField then<br>
&nbsp;&nbsp;&nbsp;  Json.O[Field.FieldName] := SO(Field.AsDateTime)<br>
  else if Field is TBlobField then<br>
&nbsp;&nbsp;&nbsp;  Json.S[Field.FieldName] := EncodeString(Field.AsString)<br>
  else<br>
&nbsp;&nbsp;&nbsp;  Json.O[Field.FieldName] := SO(Field.Value);<br>
  Result := True;<br>
end;</p>
<p>class function TTableJSon.GetValue(<br>
  Json: ISuperObject;const Name: string): Variant;<br>
begin<br>
  case Json.DataType of<br>
&nbsp;&nbsp;&nbsp;  stNull: Result := Null;<br>
&nbsp;&nbsp;&nbsp;  stBoolean: Result := Json.B[Name];<br>
&nbsp;&nbsp;&nbsp;  stDouble: Result := Json.D[Name];<br>
&nbsp;&nbsp;&nbsp;  stCurrency: Result := Json.C[Name];<br>
&nbsp;&nbsp;&nbsp;  stInt: Result := Json.I[Name];<br>
&nbsp;&nbsp;&nbsp;  stString: Result := Json.S[Name];<br>
  end;<br>
end;</p>
<p>class function TTableJSon.GetValue2Field(Field: TField; JsonValue:ISuperObject): Variant;<br>
begin<br>
  if JsonValue.DataType = stNull then<br>
&nbsp;&nbsp;&nbsp;  Result := Null<br>
  else if Field is TDateTimeField then<br>
&nbsp;&nbsp;&nbsp;  Result := JavaToDelphiDateTime(JsonValue.AsInteger)<br>
  else if (Field is  TIntegerField) or (Field is TLargeintField) then<br>
&nbsp;&nbsp;&nbsp;  Result := JsonValue.AsInteger<br>
  else if Field is TNumericField then<br>
&nbsp;&nbsp;&nbsp;  Result := JsonValue.AsDouble<br>
  else if Field is TBooleanField then<br>
&nbsp;&nbsp;&nbsp;  Result := JsonValue.AsBoolean<br>
  else if Field is TStringField then<br>
&nbsp;&nbsp;&nbsp;  Result := JsonValue.AsString<br>
  else if Field is TBlobField then<br>
&nbsp;&nbsp;&nbsp;  Result := DecodeString(JsonValue.AsString)&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>end;</p>
<p>class function TTableJSon.ImportDataFromJSon(DataSet: TDataSet;<br>
  DataJson: ISuperObject): Integer;<br>
var<br>
  SubJson:ISuperObject;<br>
  i:Integer;<br>
  iter: TSuperObjectIter;<br>
begin<br>
  if not DataSet.Active then<br>
&nbsp;&nbsp;&nbsp;  DataSet.Open;<br>
  DataSet.DisableControls;<br>
  try<br>
&nbsp;&nbsp;&nbsp;  for SubJson in DataJson do<br>
&nbsp;&nbsp;&nbsp;  begin<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  DataSet.Append;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if ObjectFindFirst(SubJson,iter) then<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  begin<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  repeat<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if DataSet.FindField(iter.Ite.Current.Name)&lt;&gt;nil then<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  DataSet.FindField(iter.Ite.Current.Name).Value :=<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  GetValue2Field(<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  DataSet.FindField(iter.Ite.Current.Name),<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  iter.Ite.Current.Value);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  until not ObjectFindNext(iter) ;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  end;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  DataSet.Post;<br>
&nbsp;&nbsp;&nbsp;  end;<br>
  finally<br>
&nbsp;&nbsp;&nbsp;  DataSet.EnableControls;<br>
  end; <br>
end;</p>
<p>class function TTableJSon.JSonFromDataSet(DataSet:TDataSet):string;<br>
  procedure GetFieldTypeInfo(Field:TField;var Fieldtyp,JsonTyp:string);<br>
  begin<br>
&nbsp;&nbsp;&nbsp;  Fieldtyp := GetEnumName(TypeInfo(tfieldtype),ord(Field.DataType));<br>
&nbsp;&nbsp;&nbsp;  Delete(Fieldtyp,1,2);<br>
&nbsp;&nbsp;&nbsp;  if Field is TStringField then<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  JsonTyp := 'string'<br>
&nbsp;&nbsp;&nbsp;  else if Field is TDateTimeField then<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  JsonTyp := 'integer'<br>
&nbsp;&nbsp;&nbsp;  else if (Field is TIntegerField) or (Field is TLargeintField) then<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  JsonTyp := 'integer'<br>
&nbsp;&nbsp;&nbsp;  else if Field is TCurrencyField then<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  JsonTyp := 'currency'<br>
&nbsp;&nbsp;&nbsp;  else if Field is TNumericField then<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  JsonTyp := 'double'<br>
&nbsp;&nbsp;&nbsp;  else if Field is TBooleanField then<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  JsonTyp := 'boolean'<br>
&nbsp;&nbsp;&nbsp;  else<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  JsonTyp := 'variant';<br>
  end;<br>
var<br>
  sj,aj,sj2:ISuperObject;<br>
  i:Integer;<br>
  Fieldtyp,JsonTyp:string;<br>
  List:TStringList;<br>
begin<br>
  sj := SO();<br>
  //创建列<br>
  aj := SA([]);<br>
  List := TStringList.Create;<br>
  try<br>
&nbsp;&nbsp;&nbsp;  List.Sorted := True;<br>
&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  for i := 0 to DataSet.FieldCount - 1 do<br>
&nbsp;&nbsp;&nbsp;  begin<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2 := SO();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  GetFieldTypeInfo(DataSet.Fields[i],Fieldtyp,JsonTyp);<br>
&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.S[cstFieldName] := DataSet.Fields[i].FieldName;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.S[cstFieldType] := Fieldtyp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.S[cstJsonType] := JsonTyp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.I[cstFieldSize] := DataSet.Fields[i].Size;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.B[cstRequired] := DataSet.Fields[i].Required;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.I[cstFieldIndex] := DataSet.Fields[i].Index;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  aj.AsArray.Add(sj2);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  List.Add(DataSet.Fields[i].FieldName+'='+JsonTyp);<br>
&nbsp;&nbsp;&nbsp;  end;<br>
&nbsp;&nbsp;&nbsp;  sj.O['Cols'] := aj;<br>
&nbsp;&nbsp;&nbsp;  //创建数据集的数据<br>
&nbsp;&nbsp;&nbsp;  DataSet.DisableControls;</p>
<p>&nbsp;&nbsp;&nbsp;  DataSet.First;<br>
&nbsp;&nbsp;&nbsp;  aj := SA([]);<br>
&nbsp;&nbsp;&nbsp;  while not DataSet.Eof  do<br>
&nbsp;&nbsp;&nbsp;  begin<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2 := SO();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for i := 0 to DataSet.FieldCount - 1 do<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  begin<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //sj2.S[IntToStr(DataSet.Fields[i].Index)] := VarToStrDef(DataSet.Fields[i].Value,'');<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if VarIsNull(DataSet.Fields[i].Value) then<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.O[DataSet.Fields[i].FieldName] := SO(Null)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  else<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  begin<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  CreateJsonValueByField(sj2,DataSet.Fields[i]);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  end;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  end;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  aj.AsArray.Add(sj2);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  DataSet.Next;<br>
&nbsp;&nbsp;&nbsp;  end;<br>
&nbsp;&nbsp;&nbsp;  sj.O['Data'] := aj;</p>
<p>&nbsp;&nbsp;&nbsp;  Result := sj.AsString;<br>
  finally<br>
&nbsp;&nbsp;&nbsp;  List.Free;<br>
&nbsp;&nbsp;&nbsp;  DataSet.EnableControls;<br>
  end; <br>
 <br>
end;</p>
<p>end.</p>
<p> </p>
<p>调用示例：</p>
<p>//数据集转JSON对象或JSON文本</p>
<p>var<br>
  json:TTableJSon;<br>
  s:string;</p>
<p>begin</p>
<p>  S := json.JSonFromDataSet(ADODataSet1);</p>
<p>  //在用TStringStream读入字符串S，存成文本，看看其格式.</p>
<p>end;</p>
<p>//JSON对象或文本，装载到数据集</p>
var<br>
  json:ISuperObject;<br>
begin<br>
  json := TSuperObject.ParseFile('json.txt',False);<br>
  TTableJSon.CDSFromJSon(cdsJSON,json);<br>
 end;
<p> </p> <a href="http://hi.baidu.com/tintinsoft/blog/item/8bcc68f1cc036ca4a40f5288.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/8bcc68f1cc036ca4a40f5288.html#comment">查看评论</a>]]></description>
        <pubDate>2009-12-31  23:37</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/8bcc68f1cc036ca4a40f5288.html</guid>
</item>

<item>
        <title><![CDATA[JSon SuperObject 研究]]></title>
        <link><![CDATA[http://hi.baidu.com/tintinsoft/blog/item/08b9cb1737ff9e13962b43a2.html]]></link>
        <description><![CDATA[
		
		<p>&nbsp;&nbsp;&nbsp;&nbsp;  SuperObject是delphi不多的著名开源JSON开源类库，其作者的作品还有大名鼎鼎的DSPACK等许多著名的开源VCL类库。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;  至于SuperObject的详细用法，万一老师已经很描述很清楚。最新版的1.2.1，添加了currency属性，也支持D2010，包括最新的RTTI。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;  SuperObject看起来很容易上手，但有一些概念必须理解清楚，比如数组的创建和使用、空值如何赋值等。以下就讲讲SuperObject一些特殊的用法：</p>
<p> 1、JSON数组。创建数组有两种方式，一个是 TSuperObject.Create(stArray)，另外一种是用接口方式 SA([]);</p>
<p>最常用的是后面一种。数组JSON对象转换<strong>AsArray</strong>方法，然后使用<strong>ADD</strong>或其<strong>length</strong>等方法或属性；数组加入JSON对象，JSON对象必须以<strong>O</strong>的属性支持赋值；范例如下：</p>
<p>//////这个范例是创建列的元信息</p>
<p>var<br>
  sj,aj,sj2:ISuperObject;<br>
  i:Integer;<br>
  Fieldtyp,JsonTyp:string;<br>
  List:TStringList;<br>
begin<br>
  sj := SO();//创建JSON对象<br>
  aj := SA([]);//创建数组</p>
<p>&nbsp;&nbsp;  for i := 0 to DataSet.FieldCount - 1 do<br>
&nbsp;&nbsp;&nbsp;  begin<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2 := SO();//创建列的信息，数组里的子对象<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //GetFieldTypeInfo(DataSet.Fields[i],Fieldtyp,JsonTyp);//获取字段信息，以及对应的JSON字段信息，可以忽略不看<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.S[cstFieldName] := DataSet.Fields[i].FieldName;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.S[cstFieldType] := Fieldtyp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.S[cstJsonType] := JsonTyp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.I[cstFieldSize] := DataSet.Fields[i].Size;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.B[cstRequired] := DataSet.Fields[i].Required;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  sj2.I[cstFieldIndex] := DataSet.Fields[i].Index;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  aj.AsArray.Add(sj2);// 数组转换，必须用 AsArray<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  List.Add(DataSet.Fields[i].FieldName+'='+JsonTyp);<br>
&nbsp;&nbsp;&nbsp;  end;<br>
&nbsp;&nbsp;&nbsp;  sj.O['Cols'] := aj;//数组添加到JSON对象，必须以对象方式</p>
<p>end;</p>
<p>2、如何处理空值NULL。空值是强类型数据下一种未赋值或未知的值。下面是SuperObject 的数据类型，看看字面意思也就大概明白。  TSuperType = (<br>
&nbsp;&nbsp;&nbsp;  stNull,<br>
&nbsp;&nbsp;&nbsp;  stBoolean,<br>
&nbsp;&nbsp;&nbsp;  stDouble,<br>
&nbsp;&nbsp;&nbsp;  stCurrency,<br>
&nbsp;&nbsp;&nbsp;  stInt,<br>
&nbsp;&nbsp;&nbsp;  stObject,<br>
&nbsp;&nbsp;&nbsp;  stArray,<br>
&nbsp;&nbsp;&nbsp;  stString<br>
&nbsp;&nbsp;&nbsp;  ,stMethod  );</p>
<p>&nbsp;&nbsp;&nbsp;  SO()接口方法有好多Overload方法，其中</p>
<p><strong>  function SO(const value: Variant): ISuperObject; overload</strong></p>
<p>就包含了空值的处理。同样，空值也是一种属性对象，因此，我们必须这样赋值：</p>
<p>SJ.O['Name'] := SO(NULL); 在使用之前，最好先判断 ISuperObject 值 的 datatype是否为 stNull</p>
<p>3、从文件获取JSON对象。ISuperObject不能直接从文件导入JSON信息，必须借助实体类TSuperObject。</p>
<p>var<br>
  sj:ISuperObject;<br>
begin<br>
&nbsp;&nbsp;&nbsp;  sj := TSuperObject.ParseFile('Json.txt');</p>
<p>end; </p>
<p> </p> <a href="http://hi.baidu.com/tintinsoft/blog/item/08b9cb1737ff9e13962b43a2.html">阅读全文</a>
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/tintinsoft/blog/category/delphi%BC%BC%CA%F5">delphi技术</a>&nbsp;<a href="http://hi.baidu.com/tintinsoft/blog/item/08b9cb1737ff9e13962b43a2.html#comment">查看评论</a>]]></description>
        <pubDate>2009-12-31  22:58</pubDate>
        <category><![CDATA[delphi技术]]></category>
        <author><![CDATA[TinTinSoft]]></author>
		<guid>http://hi.baidu.com/tintinsoft/blog/item/08b9cb1737ff9e13962b43a2.html</guid>
</item>


</channel>
</rss>
