﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-textbox-随笔分类-delphi</title><link>http://www.cnitblog.com/textbox/category/8653.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 14:38:53 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 14:38:53 GMT</pubDate><ttl>60</ttl><item><title>delphi 的string 引用数为0的时候它的内存也释放了.</title><link>http://www.cnitblog.com/textbox/archive/2011/03/28/73205.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Mon, 28 Mar 2011 09:41:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2011/03/28/73205.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/73205.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2011/03/28/73205.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/73205.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/73205.html</trackback:ping><description><![CDATA[
		<p> </p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">unit Unit1;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />interface<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />uses<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  Dialogs, StdCtrls;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />type<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  TForm1 </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000">(TForm)<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    Button1: TButton;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    Memo1: TMemo;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    Button2: TButton;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    procedure Button1Click(Sender: TObject);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    procedure Button2Click(Sender: TObject);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    procedure FormCreate(Sender: TObject);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  private<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    { Private declarations }<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    fs1:string;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  public<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    { Public declarations }<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  end;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />var<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  Form1: TForm1;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  s1,s2,s3:string;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  c:PChar;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  slis:TStringList;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  saddr:integer;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />implementation<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />{$R </span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">.dfm}<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />function   StringStatus   ( var Str:   string):   string;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />var ss1,ss2,ss3:string;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />Result   :</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">   </span>
				<span style="COLOR: #800000">'</span>
				<span style="COLOR: #800000">Address:</span>
				<span style="COLOR: #800000">'</span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">IntToStr   (Integer   (Str))   </span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  </span>
				<span style="COLOR: #800000">'</span>
				<span style="COLOR: #800000">,   Length:   </span>
				<span style="COLOR: #800000">'</span>
				<span style="COLOR: #000000">   </span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">   IntToStr   (Length   (Str))   </span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  </span>
				<span style="COLOR: #800000">'</span>
				<span style="COLOR: #800000">,   References:   </span>
				<span style="COLOR: #800000">'</span>
				<span style="COLOR: #000000">   </span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">   IntToStr(PInteger(Integer(Str)</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">8</span>
				<span style="COLOR: #000000">)</span>
				<span style="COLOR: #000000">^</span>
				<span style="COLOR: #000000">) </span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  </span>
				<span style="COLOR: #800000">'</span>
				<span style="COLOR: #800000">,   Value:   </span>
				<span style="COLOR: #800000">'</span>
				<span style="COLOR: #000000">   </span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000">   Str;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />end;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />function Readfilecontend(filename:string):string;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />var s:TStringStream;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  s:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">TStringStream.Create;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  s.LoadFromFile(filename);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  result:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">s.DataString;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  s.Free;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  s:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">nil<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />end;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />procedure TForm1.Button1Click(Sender: TObject);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />var l_s,l_s1:string;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    l_s:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">Readfilecontend(</span>
				<span style="COLOR: #800000">'</span>
				<span style="COLOR: #800000">C:\Users\admin\Desktop\7470.htm</span>
				<span style="COLOR: #800000">'</span>
				<span style="COLOR: #000000">);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    saddr:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">integer(l_s);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    l_s1:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">l_s;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    s1:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">l_s;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    fs1:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">s1;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    StringStatus(s1);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    s2:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">s1;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    self.Memo1.Lines.Add(StringStatus(string(saddr)));<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    s3:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">s2;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    self.Memo1.Lines.Add(StringStatus(string(saddr)));<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />end;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />procedure TForm1.Button2Click(Sender: TObject);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />   s1:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #800000">''</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />   self.Memo1.Lines.Add(StringStatus(string(saddr)));<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />   s2:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #800000">''</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />   self.Memo1.Lines.Add(StringStatus(string(saddr)));<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />   s3:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #800000">''</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />   self.fs1:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #800000">'</span>
				<span style="COLOR: #800000">12</span>
				<span style="COLOR: #800000">'</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />   </span>
				<span style="COLOR: #000000">//</span>
				<span style="COLOR: #000000">self.Memo1.Lines.Add(StringStatus(string(saddr)));<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />   </span>
				<span style="COLOR: #000000">//</span>
				<span style="COLOR: #000000">Pinteger(saddr</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">8</span>
				<span style="COLOR: #000000">)</span>
				<span style="COLOR: #000000">^</span>
				<span style="COLOR: #000000">:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">0;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />   </span>
				<span style="COLOR: #000000">//</span>
				<span style="COLOR: #000000">self.Memo1.Lines.Add(StringStatus(string(saddr)));<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />end;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />procedure TForm1.FormCreate(Sender: TObject);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />end;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />end.</span>
		</div>
		<br />
		<br />
<img src ="http://www.cnitblog.com/textbox/aggbug/73205.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2011-03-28 17:41 <a href="http://www.cnitblog.com/textbox/archive/2011/03/28/73205.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Delphi2010  的string 支持unicode.它做了什么修改来支持unicode 呢?</title><link>http://www.cnitblog.com/textbox/archive/2011/03/28/73198.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Mon, 28 Mar 2011 01:39:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2011/03/28/73198.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/73198.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2011/03/28/73198.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/73198.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/73198.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">先来看看他的</span>
				<span lang="EN-US">string </span>
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的定义吧</span>
				<span lang="EN-US">.</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?>
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">Delphi7:</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>type</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>
						<span style="mso-tab-count: 1">    </span>PStrRec = ^StrRec;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>
						<span style="mso-tab-count: 1">    </span>StrRec = <span style="COLOR: blue">packed</span><span style="COLOR: blue">record</span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">    </span>refCnt: Longint;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">    </span>length: Longint;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>
						<span style="COLOR: blue">end</span>;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">Delphi 2010:</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>PStrRec = ^StrRec;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>StrRec = <span style="COLOR: blue">packed</span><span style="COLOR: blue">record</span></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">    </span>codePage: Word;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">    </span>elemSize: Word;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">    </span>refCnt: Longint;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">    </span>length: Longint;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-spacerun: yes">  </span>
						<span style="COLOR: blue">end</span>;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">每个</span>
				<span lang="EN-US">string</span>
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span>
				<span lang="EN-US">StrRec </span>
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都是可以根据</span>
				<span lang="EN-US"> string </span>
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内存地址</span>
				<span lang="EN-US">– sizeof(StrRec) </span>
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">得到</span>
				<span lang="EN-US">.</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">细心的人已经可以看出来一些端倪了</span>
				<span lang="EN-US">.2010</span>
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">增加了两个</span>
				<span lang="EN-US">Word</span>
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来保存编码和宽度</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编译器会处理</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">声明的是</span>
				<span lang="EN-US">AnsiString </span>
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时候</span>
				<span lang="EN-US">elemSize=1 ,codePage= (</span>
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果是繁体系统就是</span>
				<span lang="EN-US">big5</span>
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的页码</span>
				<span lang="EN-US"> 950 </span>
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">简体就是</span>
				<span lang="EN-US"> 936) </span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果声明是</span>
				<span lang="EN-US">string (Unicode) elemSize=2<span style="mso-spacerun: yes">  </span>,codePage= 1200 (0x04B0)</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果声明是</span>
				<span lang="EN-US"> UTF8String </span>
				<span style="FONT-FAMILY: SimSun; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时候</span>
				<span lang="EN-US">elemSize=1 ,codePage= 65001</span>
		</p>
<img src ="http://www.cnitblog.com/textbox/aggbug/73198.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2011-03-28 09:39 <a href="http://www.cnitblog.com/textbox/archive/2011/03/28/73198.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Delphi的字符驱动应用</title><link>http://www.cnitblog.com/textbox/archive/2011/03/07/72985.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Mon, 07 Mar 2011 09:48:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2011/03/07/72985.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/72985.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2011/03/07/72985.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/72985.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/72985.html</trackback:ping><description><![CDATA[1.通过属性字符修改对象属性值(published )<br />    
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">   SetPropValue(DBText1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">Color</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">$</span><span style="COLOR: #000000">000080</span><span style="COLOR: #000000">);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />   SetPropValue(self</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">DBEdit1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">BorderStyle</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">bsNone);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span></div>2.通过字符串访问对象属性.(published )<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">GetPropValue(self</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">DBEdit1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">BorderStyle</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />GetPropValue(self</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">DBText1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">Color</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">)</span></div>3.通过字符串呼叫对象方法(方法必须是published 级别的)<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">procedure InvokeMethod(obj</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000"> TObject; methoName</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />type<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  TExec </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> procedure of </span><span style="COLOR: #0000ff">object</span><span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  Routine</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000"> TMethod;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #008080">Exec</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000"> TExec;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  Routine</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">Data </span><span style="COLOR: #000000">:=</span><span style="COLOR: #000000"> Pointer(obj);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  Routine</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">Code </span><span style="COLOR: #000000">:=</span><span style="COLOR: #000000"> obj</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">MethodAddress(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">ButtonClick</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> NOT Assigned(Routine</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">Code) then<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">Exit</span><span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #008080">Exec</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">:=</span><span style="COLOR: #000000"> TExec(Routine);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #008080">Exec</span><span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008080">end</span><span style="COLOR: #000000">;</span></div>4.通过字符串设置事件 (<span style="COLOR: #000000">ButtonClick 必须是published 级别的)</span><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">procedure TForm4</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">Button3Click(Sender</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000"> TObject);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  M</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000"> TMethod;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  M</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">Code </span><span style="COLOR: #000000">:=</span><span style="COLOR: #000000"> self</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">MethodAddress(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">ButtonClick</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  M</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">Data </span><span style="COLOR: #000000">:=</span><span style="COLOR: #000000"> self;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  SetMethodProp(self</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">Button4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">OnClick</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> M);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008080">end</span><span style="COLOR: #000000">;</span></div>5.字符串与枚举类型的转化<br />   
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000">  b</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">TBorderStyle;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /> <br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />b</span><span style="COLOR: #000000">:=</span><span style="COLOR: #000000">TBorderStyle(GetEnumValue(TypeInfo(TBorderStyle)</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">bsSingle</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">));<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">转字符号</span><span style="COLOR: #008000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">GetEnumName(TypeInfo(TBorderStyle)</span><span style="COLOR: #000000">,</span><span style="COLOR: #008080">Ord</span><span style="COLOR: #000000">(bsSingle))</span></div><br />6.字符创建窗口<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">　　</span><span style="COLOR: #0000ff">function</span><span style="COLOR: #000000"> TShowFormClass</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">CreateAClass(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> AClassName</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000"> TForm;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　</span><span style="COLOR: #0000ff">var</span><span style="COLOR: #000000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　  LFormClass </span><span style="COLOR: #000000">:</span><span style="COLOR: #000000"> TFormClass;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　  LForm</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000"> TForm;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　  LFormClass </span><span style="COLOR: #000000">:=</span><span style="COLOR: #000000"> TFormClass(FindClass(AClassName));<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　  LForm </span><span style="COLOR: #000000">:=</span><span style="COLOR: #000000"> LFormClass</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">Create(Application);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　  Result </span><span style="COLOR: #000000">:=</span><span style="COLOR: #000000"> LForm;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　</span><span style="COLOR: #008080">end</span><span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />//创建的窗口必须先注册</span><span style="COLOR: #008000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">　　initialization                            <br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　  RegisterClasses([TAboutBox</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">TFormArea]);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　</span><span style="COLOR: #008080">end</span><span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　finalization<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　  UnRegisterClasses([TAboutBox</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">TFormArea]);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />　　</span><span style="COLOR: #008080">end</span><span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 调用 </span><span style="COLOR: #008000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />CreateAClass(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">TFormArea</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /> </span></div><br /><br /><img src ="http://www.cnitblog.com/textbox/aggbug/72985.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2011-03-07 17:48 <a href="http://www.cnitblog.com/textbox/archive/2011/03/07/72985.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>窥探delphi 的各类函数呼叫机制</title><link>http://www.cnitblog.com/textbox/archive/2011/03/07/72953.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Mon, 07 Mar 2011 02:28:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2011/03/07/72953.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/72953.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2011/03/07/72953.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/72953.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/72953.html</trackback:ping><description><![CDATA[代码如下<br /><div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">unit Unit4;<br /><br /></span><span style="color: rgb(0, 0, 255);">interface</span><span style="color: rgb(0, 0, 0);"><br /><br />uses<br />  Windows</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> Messages</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> SysUtils</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> Variants</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> Classes</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> Graphics</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> Controls</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> Forms</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"><br />  Dialogs</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> StdCtrls</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> DBCtrls</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> Mask;<br /><br />type<br />  TForm4 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">(TForm)<br />    Button2</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> TButton;<br />    procedure Button2Click(Sender</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> TObject);<br />  </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"><br /><br />    { </span><span style="color: rgb(0, 0, 255);">Private</span><span style="color: rgb(0, 0, 0);"> declarations }<br />  </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"><br />    { </span><span style="color: rgb(0, 0, 255);">Public</span><span style="color: rgb(0, 0, 0);"> declarations }<br />    procedure add(a</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 255);">integer</span><span style="color: rgb(0, 0, 0);">);<br />    </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> procedure add1(a</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 255);">integer</span><span style="color: rgb(0, 0, 0);">);<br />  </span><span style="color: rgb(0, 128, 128);">end</span><span style="color: rgb(0, 0, 0);">;<br />  <br />   procedure add2(a</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 255);">integer</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);"><br />  Form4</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> TForm4;<br />  c</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 255);">integer</span><span style="color: rgb(0, 0, 0);">;<br />implementation<br />{</span><span style="color: rgb(128, 0, 128);">$R</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*.</span><span style="color: rgb(0, 0, 0);">dfm}<br /><br />procedure add2(a</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 255);">integer</span><span style="color: rgb(0, 0, 0);">);<br />begin<br />    c</span><span style="color: rgb(0, 0, 0);">:=</span><span style="color: rgb(0, 0, 0);">a</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">end</span><span style="color: rgb(0, 0, 0);">;<br />procedure TForm4</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">add(a</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">integer</span><span style="color: rgb(0, 0, 0);">);<br />begin<br />    c</span><span style="color: rgb(0, 0, 0);">:=</span><span style="color: rgb(0, 0, 0);">a</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">end</span><span style="color: rgb(0, 0, 0);">;<br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> procedure TForm4</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">add1(a</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">integer</span><span style="color: rgb(0, 0, 0);">);<br />begin<br />   c</span><span style="color: rgb(0, 0, 0);">:=</span><span style="color: rgb(0, 0, 0);">a</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">end</span><span style="color: rgb(0, 0, 0);">;<br /><br /></span><span style="color: rgb(0, 128, 128);">end</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);"><br /></span></div>汇编代码<br /><div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><font color="#009900"><span style="color: rgb(0, 0, 0);"></span></font><span style="color: rgb(0, 0, 0);"><font color="#009900"></font><br />004FB1E8 BA01000000       mov edx</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">$</span><span style="color: rgb(0, 0, 0);">00000001</span><span style="color: rgb(0, 0, 0);"><br />004FB1ED E836FFFFFF       call TForm4</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">add  //成员函数<br /></span><span style="color: rgb(0, 0, 0);"><font color="#009900"></font><br />004FB1F2 BA01000000       mov edx</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">$</span><span style="color: rgb(0, 0, 0);">00000001</span><span style="color: rgb(0, 0, 0);"><br />004FB1F7 A15CAA4F00       mov eax</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">[$004faa5c]<br />004FB1FC E82FFFFFFF       call TForm4</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">add1 //类函数<br /></span><span style="color: rgb(0, 0, 0);"><font color="#009900"></font><br />004FB201 B801000000       mov eax</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">$</span><span style="color: rgb(0, 0, 0);">00000001</span><span style="color: rgb(0, 0, 0);"><br />004FB206 E815FFFFFF       call add2  //单元函数<br /></span></div><br />1.成员函数数<br />  别看它的呼叫那么简单,其实也要给eax传值的. 成员函数的调用需要对eax隐含的传值.传什么呢?答案就是:类的实体地址. 如以上<span style="color: rgb(0, 0, 0);">TForm4</span><span style="color: rgb(0, 0, 0);">类的实体是</span><span style="color: rgb(0, 0, 0);">Form4 那么 </span>eax=Pointer(Form4) 这样才能call.因为是成员函数,所以eax都是指向 Pointer(self)的.这也是为什么成员函数不能作为windows的回调,线程函数的原因.<br /><div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">procedure TForm4</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">Button1Click(Sender</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);"> TObject);<br /></span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);"> p</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">PPropInfo;<br />    setproc</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">Pointer;<br />    tp</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">Pointer;<br />begin<br /><br />   p</span><span style="color: rgb(0, 0, 0);">:=</span><span style="color: rgb(0, 0, 0);">GetPropInfo(self</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">DBText1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">Color</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">[TTypeKind</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">tkInteger]);<br />   ListBox1</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">Items</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">Add(p</span><span style="color: rgb(0, 0, 0);">^.</span><span style="color: rgb(0, 0, 0);">Name);<br />   setproc</span><span style="color: rgb(0, 0, 0);">:=</span><span style="color: rgb(0, 0, 0);">p</span><span style="color: rgb(0, 0, 0);">^.</span><span style="color: rgb(0, 0, 0);">SetProc;<br />   tp</span><span style="color: rgb(0, 0, 0);">:=</span><span style="color: rgb(0, 0, 0);">DBText1;<br />   asm<br />     push eax<br />     mov eax</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">tp //实体地址传值给eax<br />     mov edx</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">$</span><span style="color: rgb(0, 0, 0);">80</span><span style="color: rgb(0, 0, 0);"> //传参数<br />     call setproc<br />     pop eax<br />   </span><span style="color: rgb(0, 128, 128);">end</span><span style="color: rgb(0, 0, 0);">;<br />  <br /></span><span style="color: rgb(0, 128, 128);">end</span><span style="color: rgb(0, 0, 0);">;</span></div>以上代码是修改一个<span style="color: rgb(0, 0, 0);">DBText的Color属性</span>.如果没有传eax是会失败的.<br />2.类函数<br />  与成员含数类似,不过EAX就是传类<span style="color: rgb(0, 0, 0);">TForm4</span><span style="color: rgb(0, 0, 0);">的地址</span><br />3.单元函数<br />  正常的函调用无须隐含传什么值<br /><img src ="http://www.cnitblog.com/textbox/aggbug/72953.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2011-03-07 10:28 <a href="http://www.cnitblog.com/textbox/archive/2011/03/07/72953.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>delphi2010 你完全支持unicode怎么那么多陷阱啊</title><link>http://www.cnitblog.com/textbox/archive/2011/03/04/72925.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Fri, 04 Mar 2011 09:41:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2011/03/04/72925.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/72925.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2011/03/04/72925.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/72925.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/72925.html</trackback:ping><description><![CDATA[看到DB.pas 里面的<br />procedure TStringField.SetAsString(const Value: string);<br />begin<br />  SetAsAnsiString(AnsiString(Value)); //这个就叫做支持unicode.......所有的unicode string 到传到了里面全变成了ansi 字符.害的我在繁体系统里读取简体unicode 文件全是乱码.纳闷.<br />end;<br />你的string是unicode没错,可是你的vcl又有多少是ansi做核心编码的???看到上面的语句真有点浪费我的时间.<br />本来以为是vcl代码不一致的问题导致,可是看到cpu里面的代码就确认是传进去的unicode 竟然被转成ansi 了.能不乱码.一个简体unicode在繁体系统里面能不乱吗??????哎!!默哀.<br /><br />TStringField.SetAsString:<br />004F85A8 55               push ebp<br />004F85A9 8BEC             mov ebp,esp<br />004F85AB 6A00             push $00<br />004F85AD 53               push ebx<br />004F85AE 56               push esi<br />004F85AF 8BF2             mov esi,edx<br />004F85B1 8BD8             mov ebx,eax<br />004F85B3 33C0             xor eax,eax<br />004F85B5 55               push ebp<br />004F85B6 68F3854F00       push $004f85f3<br />004F85BB 64FF30           push dword ptr fs:[eax]<br />004F85BE 648920           mov fs:[eax],esp<br />004F85C1 8D45FC           lea eax,[ebp-$04]<br />004F85C4 8BD6             mov edx,esi<br />004F85C6 B900000000       mov ecx,$00000000<br />004F85CB E844F2F0FF       call @LStrFromUStr<br />004F85D0 8B55FC           mov edx,[ebp-$04]<br />004F85D3 8BC3             mov eax,ebx<br />004F85D5 8B08             mov ecx,[eax]<br />004F85D7 FF91EC000000     call dword ptr [ecx+$000000ec]   <font color="#ff0000">//TStringField.SetAsAnsiString:<br /></font>004F85DD 33C0             xor eax,eax<br />004F85DF 5A               pop edx<br />004F85E0 59               pop ecx<br />004F85E1 59               pop ecx<br />004F85E2 648910           mov fs:[eax],edx<br />004F85E5 68FA854F00       push $004f85fa<br />004F85EA 8D45FC           lea eax,[ebp-$04]<br />004F85ED E8A2E2F0FF       call @LStrClr<br />004F85F2 C3               ret <br />004F85F3 E914D9F0FF       jmp @HandleFinally<br />004F85F8 EBF0             jmp $004f85ea<br />004F85FA 5E               pop esi<br />004F85FB 5B               pop ebx<br />004F85FC 59               pop ecx<br />004F85FD 5D               pop ebp<br />004F85FE C3               ret <br />004F85FF 90               nop <br /><br />看来还是得使用TWideStringField 了<br /><br /><br /> <img src ="http://www.cnitblog.com/textbox/aggbug/72925.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2011-03-04 17:41 <a href="http://www.cnitblog.com/textbox/archive/2011/03/04/72925.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个把字符转换成各种编码文件的delphi2010函数.</title><link>http://www.cnitblog.com/textbox/archive/2011/03/03/72913.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Thu, 03 Mar 2011 02:28:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2011/03/03/72913.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/72913.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2011/03/03/72913.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/72913.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/72913.html</trackback:ping><description><![CDATA[
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">  procedure SaveFile(</span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000"> FileName: </span>
				<span style="COLOR: #0000ff">string</span>
				<span style="COLOR: #000000">; Source: </span>
				<span style="COLOR: #0000ff">string</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    encoding: TEncoding);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  var<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    sl: TStrings;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    memoStream: TFileStream;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    buff: Tbytes;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    LByteOrderMark: TBytes;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000"> Source </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #008000">'</span>
				<span style="COLOR: #008000">' then</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">      </span>
				<span style="COLOR: #0000ff">exit</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    try<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />      buff :</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> encoding.GetBytes(Source);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />      memoStream :</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> TFileStream.Create(FileName, fmCreate);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />      LByteOrderMark :</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> encoding.GetPreamble;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />      memoStream.Write(LByteOrderMark[</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">], Length(LByteOrderMark));<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />      memoStream.Write(buff[</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">], length(buff));<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    finally<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />      memoStream.Free;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span>
				<span style="COLOR: #0000ff">end</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  </span>
				<span style="COLOR: #0000ff">end</span>
				<span style="COLOR: #000000">;</span>
		</div>
		<br />
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">      SaveFile('C:\Temp\test_' + 'ascii_gbk.txt', ss, TEncoding.GetEncoding(936));//gbk<br />      SaveFile('C:\Temp\test_' + 'ascii_bg5.txt', ss, TEncoding.GetEncoding(950));//bg5 繁体<br />      SaveFile('C:\Temp\test_' + 'utf8.txt', ss, TEncoding.UTF8);<br />      SaveFile('C:\Temp\test_' + 'unicode.txt', ss, TEncoding.Unicode);</div>
		<br />unicode转中文的时候必须要制定页码,不然会出现乱码.比如的以下这两句.<br />  SaveFile('C:\Temp\test_' + 'ascii_gbk.txt', ss, TEncoding.GetEncoding(936));//gbk<br />  SaveFile('C:\Temp\test_' + 'ascii_bg5.txt', ss, TEncoding.GetEncoding(950));//bg5 繁体<br /><img src ="http://www.cnitblog.com/textbox/aggbug/72913.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2011-03-03 10:28 <a href="http://www.cnitblog.com/textbox/archive/2011/03/03/72913.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>判断文件的编码格式（unicode;Utf-8;Ansi;Unicode Big endian)</title><link>http://www.cnitblog.com/textbox/archive/2011/03/02/72902.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Wed, 02 Mar 2011 03:53:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2011/03/02/72902.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/72902.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2011/03/02/72902.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/72902.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/72902.html</trackback:ping><description><![CDATA[程序原理通过通过判断文件头几个字节来判断文件的编码格式<br /><br /><div>ANSI ：　　　　　　　  无格式定义； </div><div>Unicode ：　　　　　　前两个字节为 FFFE ； </div><div>Unicode big endian ：　前两字节为 FEFF ；　 </div><div>UTF-8 ：　　　　　　  前两字节为 EFBB ；<br /><br />代码部分来自网络+自己修改<br />定义：<br /><br /><div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: rgb(0,0,0)">type<br />  TTextFormat </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> (tfAnsi</span><span style="COLOR: rgb(0,0,0)">,</span><span style="COLOR: rgb(0,0,0)"> tfUnicode</span><span style="COLOR: rgb(0,0,0)">,</span><span style="COLOR: rgb(0,0,0)"> tfUnicodeBigEndian</span><span style="COLOR: rgb(0,0,0)">,</span><span style="COLOR: rgb(0,0,0)"> tfUtf8);<br /></span><span style="COLOR: rgb(0,128,128)">end</span><span style="COLOR: rgb(0,0,0)">;<br /></span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)"><br />  TextFormatFlag</span><span style="COLOR: rgb(0,0,0)">:</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">array</span><span style="COLOR: rgb(0,0,0)"> [tfAnsi </span><span style="COLOR: rgb(0,0,0)">..</span><span style="COLOR: rgb(0,0,0)"> tfUtf8] of word </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> ($</span><span style="COLOR: rgb(0,0,0)">0000</span><span style="COLOR: rgb(0,0,0)">,</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(128,0,128)">$FFFE</span><span style="COLOR: rgb(0,0,0)">,</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(128,0,128)">$FEFF</span><span style="COLOR: rgb(0,0,0)">,</span><span style="COLOR: rgb(0,0,0)"><br />    </span><span style="COLOR: rgb(128,0,128)">$EFBB</span><span style="COLOR: rgb(0,0,0)">);<br /></span></div><br />函数<br /><div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: rgb(0,0,255)">function</span><span style="COLOR: rgb(0,0,0)"> GetFileType(</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)"> FileName</span><span style="COLOR: rgb(0,0,0)">:</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">string</span><span style="COLOR: rgb(0,0,0)">)</span><span style="COLOR: rgb(0,0,0)">:</span><span style="COLOR: rgb(0,0,0)"> TTextFormat;<br /></span><span style="COLOR: rgb(0,0,255)">var</span><span style="COLOR: rgb(0,0,0)"><br />  w</span><span style="COLOR: rgb(0,0,0)">:</span><span style="COLOR: rgb(0,0,0)"> word;<br />  b</span><span style="COLOR: rgb(0,0,0)">:</span><span style="COLOR: rgb(0,0,0)"> Byte;<br />begin<br />  with TFileStream</span><span style="COLOR: rgb(0,0,0)">.</span><span style="COLOR: rgb(0,0,0)">Create(FileName</span><span style="COLOR: rgb(0,0,0)">,</span><span style="COLOR: rgb(0,0,0)"> fmOpenRead or fmShareDenyNone) </span><span style="COLOR: rgb(0,0,255)">do</span><span style="COLOR: rgb(0,0,0)"><br />    </span><span style="COLOR: rgb(0,0,255)">try</span><span style="COLOR: rgb(0,0,0)"><br />      Read(w</span><span style="COLOR: rgb(0,0,0)">,</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">);<br />      asm    // 因为是以Word数据类型读取，故高低字节互换<br />          PUSH EAX<br />          MOVZX EAX,  w<br />          XCHG AL,AH<br />          MOV w, AX<br />          POP EAX<br />        end;</span><span style="COLOR: rgb(0,128,0)"></span><span style="COLOR: rgb(0,0,0)">      <br /></span><span style="COLOR: rgb(0,0,255)">       if</span><span style="COLOR: rgb(0,0,0)"> w </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> TextFormatFlag[tfUnicode] then<br />        Result </span><span style="COLOR: rgb(0,0,0)">:=</span><span style="COLOR: rgb(0,0,0)"> TTextFormat</span><span style="COLOR: rgb(0,0,0)">.</span><span style="COLOR: rgb(0,0,0)">tfUnicode<br />      </span><span style="COLOR: rgb(0,0,255)">else</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">if</span><span style="COLOR: rgb(0,0,0)"> w </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> TextFormatFlag[tfUnicodeBigEndian] then<br />        Result </span><span style="COLOR: rgb(0,0,0)">:=</span><span style="COLOR: rgb(0,0,0)"> TTextFormat</span><span style="COLOR: rgb(0,0,0)">.</span><span style="COLOR: rgb(0,0,0)">tfUnicodeBigEndian<br />      </span><span style="COLOR: rgb(0,0,255)">else</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">if</span><span style="COLOR: rgb(0,0,0)"> w </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> TextFormatFlag[tfUtf8] then<br />        Result </span><span style="COLOR: rgb(0,0,0)">:=</span><span style="COLOR: rgb(0,0,0)"> TTextFormat</span><span style="COLOR: rgb(0,0,0)">.</span><span style="COLOR: rgb(0,0,0)">tfUtf8<br />      </span><span style="COLOR: rgb(0,0,255)">else</span><span style="COLOR: rgb(0,0,0)"><br />        Result </span><span style="COLOR: rgb(0,0,0)">:=</span><span style="COLOR: rgb(0,0,0)"> TTextFormat</span><span style="COLOR: rgb(0,0,0)">.</span><span style="COLOR: rgb(0,0,0)">tfAnsi;<br />    finally<br />      Free;<br />    </span><span style="COLOR: rgb(0,128,128)">end</span><span style="COLOR: rgb(0,0,0)">;<br /></span><span style="COLOR: rgb(0,128,128)">end</span><span style="COLOR: rgb(0,0,0)">;</span></div><br /><br /></div><img src ="http://www.cnitblog.com/textbox/aggbug/72902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2011-03-02 11:53 <a href="http://www.cnitblog.com/textbox/archive/2011/03/02/72902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Schema.ini 与CSV文件的字段类型 </title><link>http://www.cnitblog.com/textbox/archive/2011/03/02/72900.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Wed, 02 Mar 2011 03:14:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2011/03/02/72900.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/72900.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2011/03/02/72900.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/72900.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/72900.html</trackback:ping><description><![CDATA[
		<p>
				<br />利用ADO访问csv文件可以利用Schema.ini来订制格式,数据类型, Schema.ini 必须与csv在同一个目录才生效<br /><br />test1.csv 内容<br /><br />a,b,c<br />qqq,qqq,qq<br />22,22,22<br />2,2,2<br />2,4,2<br />qqq,qqq,qq<br />qqq,qqq,qq</p>
		<p>
				<br />
				<br />
				<br />
				<br />Schema.ini 内容</p>
		<p align="left">[test1.csv]<br />Format=Delimited(,)<br />ColNameHeader=True<br />MaxScanRows=0<br />CharacterSet=ANSI<br />a=F1 Char Width 3<br />b=F2 Char Width 10<br />c=F3 Integer</p>
		<p align="left">[test2.csv]<br />Format=Delimited(,)<br />ColNameHeader=False<br />MaxScanRows=0<br />CharacterSet=ANSI<br />Col1=F1 Char Width 5<br />Col2=F2 Char Width 5<br />Col3=F3 Char Width 5<br />Col4=F4 Char Width 5<br />Col5=F5 Char Width 5<br />Col6=F6 Char Width 5<br /><br />delphi source<br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">procedure TForm1.Button1Click(Sender: TObject);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />var<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  t:Cardinal;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  t:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">GetTickCount();<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  ADOConnection1.Close;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  ADOConnection1.ConnectionString :</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #008000">'</span>
				<span style="COLOR: #008000">Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Temp\;Persist Security Info=False;Extended Properties="Text;HDR=Yes;FMT=Delimited(,)"'; // HDR表示首行字段列表，Delimited(,)表示是以逗号分割的文件</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">  ADOQuery1.Close;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  ADOQuery1.SQL.Text :</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #008000">'</span>
				<span style="COLOR: #008000">select * from [Test1.csv]';</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">  ADOQuery1.Open;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  t:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">GetTickCount()</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">t;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  memo1.Lines.Add(inttoStr(t));<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">end</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />procedure TForm1.Button2Click(Sender: TObject);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />var<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  t:Cardinal;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  t:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">GetTickCount();<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  ADOConnection1.Close;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  ADOConnection1.ConnectionString :</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #008000">'</span>
				<span style="COLOR: #008000">Provider=MSDASQL;Driver={Microsoft Text Driver (*.txt; *.csv)};DBQ=C:\Temp';</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">  ADOQuery1.Close;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  ADOQuery1.SQL.Text :</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #008000">'</span>
				<span style="COLOR: #008000">select * from Test1.csv';</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">  ADOQuery1.Open;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  t:</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">GetTickCount()</span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000">t;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />  memo1.Lines.Add(inttoStr(t));<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">end</span>
				<span style="COLOR: #000000">;</span>
		</div>
		<p align="left">
				<br />这个这两种读取方式.数据量小,第一种快点.数据量大第二种快. 如果没有Schema.ini 你会发现读取出来的数据有些是空的.是字段类型的缘故.</p>
<img src ="http://www.cnitblog.com/textbox/aggbug/72900.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2011-03-02 11:14 <a href="http://www.cnitblog.com/textbox/archive/2011/03/02/72900.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>delphi VMT</title><link>http://www.cnitblog.com/textbox/archive/2010/08/18/68223.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Wed, 18 Aug 2010 09:24:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2010/08/18/68223.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/68223.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2010/08/18/68223.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/68223.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/68223.html</trackback:ping><description><![CDATA[定义VMP结构体<br />type<br />PVmt   =   ^TVmt;<br />TVmt   =   record<br />  SelfPtr:     TClass;<br />  IntfTable:   PInterfaceTable;<br />  AutoTable:   PAutoTable;<br />  InitTable:   PInitTable;<br />  TypeInfo:   PTypeInfo;<br />  FieldTable:   PFieldTable;<br />  MethodTable:   PMethodTable;<br />  DynMethodTable:   PDynMethodTable;<br />  ClassName:     PShortString;<br />  InstanceSize:   LongInt;<br />  ClassParent:   ^TClass;<br />  SafeCallException:   Pointer;<br />  AfterConstruction:   Pointer;<br />  BeforeConstruction:   Pointer;<br />  Dispatch:   Pointer;<br />  DefaultHandler;   Pointer;<br />  NewInstance:   Pointer;<br />  FreeInstance:   Pointer;<br />  Destory:   Pointer;<br />end;<br /><br /><img src ="http://www.cnitblog.com/textbox/aggbug/68223.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2010-08-18 17:24 <a href="http://www.cnitblog.com/textbox/archive/2010/08/18/68223.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Delphi RTTI 资料</title><link>http://www.cnitblog.com/textbox/archive/2010/08/18/68222.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Wed, 18 Aug 2010 09:18:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2010/08/18/68222.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/68222.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2010/08/18/68222.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/68222.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/68222.html</trackback:ping><description><![CDATA[
		<font size="4" face="Arial">
				<br />
				<span class="Apple-style-span" style="color: rgb(68, 68, 68); border-collapse: collapse;">
						<span class="Apple-style-span" style="font-size: 14px; line-height: 22px;">一：获得对象的RTTI（以下代码基于<span class="t_tag" href="http://hi.baidu.com/delphicode/blog/item/tag.php?name=Delphi" style="word-wrap: break-word; line-height: normal; cursor: pointer; border-bottom: 1px solid rgb(255, 0, 0); white-space: nowrap;">Delphi</span> 6/7）<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 RTTI(Runtime Type Information 
运行时类型信息)指的是对象在编译的时候，将其属性、方法的类型信息编译进特殊的区域，使得应用程序可以运行时，动态的查找对象的成员（fields）和
属性（properties），以及定位函数（methods）。能够编译进RTTI的成员主要是被声明在对象的published部分，对象
published部分的成员与public部分的成员具有相同的可见性，但区别就在于此。当在持久化和反持久化的时候，RTTI被用来访问属性的值、在
对象浏览器（Object Inspector）中显示属性，以及关联事件（Event）和事件句柄函数（Event 
Handler）。Published部分的属性类型被限定在几种特殊的类型中，只能是Ordinal（有序类型）、string、class、
interface、variant和函数指针类型，数组属性是不能被声明为published。当然也不是每一个被声明在published部分的成员
都可以被持久化下来，比如record、array，同时声明在published部分的函数不支持overload。任何一个类希望拥有RTTI，需要
在其类声明的时候加上编译开关{$M+}，或者其父类在声明的时候有{$M+}，所以最简单的方式获得RTTI就是从TPersistent继承。 <br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 对象属性的RTTI <br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 特别注意，并不是所有类型的属性都可以被编译到RTTI中。<br style="word-wrap: break-word; line-height: normal;" />
 以下是获得属性、类型的方法<br style="word-wrap: break-word; line-height: normal;" />
 function GetObjProps(AObj: TPersistent): String;<br style="word-wrap: break-word; line-height: normal;" />
 var<br style="word-wrap: break-word; line-height: normal;" />
 StrList: TStringList;<br style="word-wrap: break-word; line-height: normal;" />
 PropCount, I: Integer;<br style="word-wrap: break-word; line-height: normal;" />
 PropList: PPropList;<br style="word-wrap: break-word; line-height: normal;" />
 begin<br style="word-wrap: break-word; line-height: normal;" />
 StrList:= TStringList.Create;<br style="word-wrap: break-word; line-height: normal;" />
 try<br style="word-wrap: break-word; line-height: normal;" />
    PropCount:= GetPropList(AObj, PropList);<br style="word-wrap: break-word; line-height: normal;" />
    try<br style="word-wrap: break-word; line-height: normal;" />
       if PropCount&gt;0 then<br style="word-wrap: break-word; line-height: normal;" />
         for I := 0 to PropCount-1 do<br style="word-wrap: break-word; line-height: normal;" />
            StrList.Append(Format('Property %s : %s ;',[PropList[I]^.Name, PropList[I]^.PropType^^.Name]));<br style="word-wrap: break-word; line-height: normal;" />
    finally<br style="word-wrap: break-word; line-height: normal;" />
       if PropCount&gt;0 then FreeMem(PropList,PropCount*SizeOf(Pointer));<br style="word-wrap: break-word; line-height: normal;" />
    end;<br style="word-wrap: break-word; line-height: normal;" />
    Result:= StrList.Text;<br style="word-wrap: break-word; line-height: normal;" />
 finally<br style="word-wrap: break-word; line-height: normal;" />
    StrList.Free;<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 当自己制作一个属性浏览器的时候，就可以通过TypInfo单元中的各种方法，获得属性名称、类型、值的读写。 <br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 对象函数的RTTI <br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 
之所在很早的时候函数就被编译进RTTI中，并不是为了在Delphi中实现反射，因为反射的概念只是Java、.NET这种基于VM的语言的一个小特
性，而基于VM产生出的各种特性，包括垃圾回收、平台无关这些都是编译型语言的硬伤，所以Delphi不会特地为了反射而反射，只是用在一些特殊的领域。
Delphi中支持函数的RTTI最早是为了实现事件句柄（EventHandler）的持久化。在Delphi语言创建之初就确定了对
Property-Event的支持，这个特性也是Delphi最富魅力的特性之一。所谓的Event（事件），是消息或内部逻辑中发出的特定的请
求，Event的定义需要明确特定的事件意义以及特定的编程接口，它是基于消息机制的一种逻辑扩展接口，Event本身并不直接包含逻辑，它只是一个锚
点，真正的执行逻辑在EventHandler中，EventHandler依赖于外部的注入。<br style="word-wrap: break-word; line-height: normal;" />
 例如：<br style="word-wrap: break-word; line-height: normal;" />
 对象声明了一个处理消息WM_LBUTTONDBLCLK的函数，在接收到该消息后执行<br style="word-wrap: break-word; line-height: normal;" />
 if Assigned(FOnDblClick) then FOnDblClick(Self);<br style="word-wrap: break-word; line-height: normal;" />
 
则外部就可以通过在EventOnDBClick属性上挂接处理函数，来实现对事件的响应，注入逻辑。我们知道，在IDE和持久化机制中，针对事件属性关
联的EventHandler是声明在窗体对象published部分的函数（准确的说，由于EventHandler关联关系是需要持久化的，所以在
Delphi的持久化机制中，EventHandler一定要是TReader/TWriter的Root下published中声明的函数），这是一种
比较古老也过时的设计，现在由于AOP（Aspect-Oriented 
program面向方面编程）概念的发展，受其影响已将EventHandler发展为委托对象，事件的发起者只需要将自己注册在委托对象上，事件的处理
逻辑也不直接响应事件，而也是注册在委托对象上，这样设计的好处是由于中间存在了一个delegation，也就提供了更方便更灵活的注入逻辑的机制，在
后期加入和改变事件处理逻辑的时候也最大限度的保障了原有逻辑的稳定。这也是.Net中发展出委托的原因。当然，在很多国内的书籍中介绍到.Net的委托
的时候，都会提到『不必关心具体的执行者，只要知道你的消息交给哪一个委托就好了』，这样的解释并没有切题，因为无论是Delphi中比较古老的设计，还
是现今的委托，消息的发起者都不需要关心接收者的处理。<br style="word-wrap: break-word; line-height: normal;" />
 下面看一段持久化机制中的代码：<br style="word-wrap: break-word; line-height: normal;" />
 procedure WriteMethodProp;<br style="word-wrap: break-word; line-height: normal;" />
 var<br style="word-wrap: break-word; line-height: normal;" />
    Value: TMethod;<br style="word-wrap: break-word; line-height: normal;" />
 begin<br style="word-wrap: break-word; line-height: normal;" />
    Value := GetMethodProp(Instance, PropInfo);<br style="word-wrap: break-word; line-height: normal;" />
    WritePropPath;<br style="word-wrap: break-word; line-height: normal;" />
    if Value.Code = nil then<br style="word-wrap: break-word; line-height: normal;" />
       WriteValue(vaNil)<br style="word-wrap: break-word; line-height: normal;" />
    else<br style="word-wrap: break-word; line-height: normal;" />
       WriteIdent(FLookupRoot.MethodName(Value.Code));<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 这段是TWriter.WriteProperty中持久化Event的子函数，基本逻辑就是：根据函数地址，在LookupRoot中找寻到函数名称，将其持久化。这里的LookupRoot就等于Root。而在TReader中反持久化的时候，代码如下：<br style="word-wrap: break-word; line-height: normal;" />
    tkMethod:<br style="word-wrap: break-word; line-height: normal;" />
       if NextValue = vaNil then<br style="word-wrap: break-word; line-height: normal;" />
       begin<br style="word-wrap: break-word; line-height: normal;" />
         ReadValue;<br style="word-wrap: break-word; line-height: normal;" />
         SetMethodProp(Instance, PropInfo, NilMethod);<br style="word-wrap: break-word; line-height: normal;" />
       end<br style="word-wrap: break-word; line-height: normal;" />
       else<br style="word-wrap: break-word; line-height: normal;" />
       begin<br style="word-wrap: break-word; line-height: normal;" />
         Method.Code :=   FindMethod(Root, ReadIdent);<br style="word-wrap: break-word; line-height: normal;" />
         Method.Data := Root;<br style="word-wrap: break-word; line-height: normal;" />
         if Method.Code &lt;&gt; nil then SetMethodProp(Instance, PropInfo, Method);<br style="word-wrap: break-word; line-height: normal;" />
       end;<br style="word-wrap: break-word; line-height: normal;" />
 这下就一目了然了，Data是Root，Code是根据函数名称在Root下找寻到函数地址。<br style="word-wrap: break-word; line-height: normal;" />
 如果我们想在Delphi中实现委托对象的话，可以在委托对象持久化的时候记录下Event的关联关系，例如，可以是以下的dfm文件：<br style="word-wrap: break-word; line-height: normal;" />
 ...<br style="word-wrap: break-word; line-height: normal;" />
    delegation: TNotifydelegation<br style="word-wrap: break-word; line-height: normal;" />
         Events=&lt;<br style="word-wrap: break-word; line-height: normal;" />
                item<br style="word-wrap: break-word; line-height: normal;" />
                     host = Button1<br style="word-wrap: break-word; line-height: normal;" />
                     Event = 'OnClick'<br style="word-wrap: break-word; line-height: normal;" />
                end&gt;<br style="word-wrap: break-word; line-height: normal;" />
    end<br style="word-wrap: break-word; line-height: normal;" />
 而不必拘泥于一定要生成如下形式，<br style="word-wrap: break-word; line-height: normal;" />
 ...<br style="word-wrap: break-word; line-height: normal;" />
    Button1: TButton<br style="word-wrap: break-word; line-height: normal;" />
         OnClick = delegation.OnNotify<br style="word-wrap: break-word; line-height: normal;" />
    end<br style="word-wrap: break-word; line-height: normal;" />
 因为如果生成这种形式的话，需要改写VCL中的一些代码。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 最简单的情况下，函数的RTTI是通过如下形式获得到的：<br style="word-wrap: break-word; line-height: normal;" />
 var<br style="word-wrap: break-word; line-height: normal;" />
 VMT: Pointer;<br style="word-wrap: break-word; line-height: normal;" />
 MethodInfo: PMethodInfoHeader;<br style="word-wrap: break-word; line-height: normal;" />
 begin<br style="word-wrap: break-word; line-height: normal;" />
    VMT := PPointer(AObj)^;<br style="word-wrap: break-word; line-height: normal;" />
    MethodInfo := PPointer(Integer(VMT) + vmtMethodTable)^;<br style="word-wrap: break-word; line-height: normal;" />
    ...<br style="word-wrap: break-word; line-height: normal;" />
 end；<br style="word-wrap: break-word; line-height: normal;" />
 
这是一段摘自VCL中的代码，其意义是对象首地址负偏移vmtMethodTable（vmtMethodTable=-56在单元System中有相关
常量值的定义）是RTTI方法表的入口地址，注意，方法表入口首先存储的当前对象的方法数量，然后首地址偏移2 
Byte后才是所有函数的名称。在单元ObjAuto中相关结构体定义了方法表的内存结构。<br style="word-wrap: break-word; line-height: normal;" />
 当只有{$M+}的时候，方法表的内存布局是以下结构：<br style="word-wrap: break-word; line-height: normal;" />
 TMethodInfoHeader = packed record<br style="word-wrap: break-word; line-height: normal;" />
    Len: Word;<br style="word-wrap: break-word; line-height: normal;" />
    Addr: Pointer;<br style="word-wrap: break-word; line-height: normal;" />
    Name: ShortString;<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 
其中Len是该函数信息结构的大小（当只有{$M+}时，Len=TMethodInfoHeader结构体的大小，注意Name是变体；当有{$M+}
{$METHODINFO 
ON}时，Len=TMethodInfoHeader+TReturnInfo+TParamInfo+...+TParamInfo），Addr指向
代码段函数地址，Name为函数名。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 当有{$M+}{$$METHODINFO ON}时，内存布局如下：<br style="word-wrap: break-word; line-height: normal;" />
 TMethodInfoHeader = packed record<br style="word-wrap: break-word; line-height: normal;" />
    Len: Word;<br style="word-wrap: break-word; line-height: normal;" />
    Addr: Pointer;<br style="word-wrap: break-word; line-height: normal;" />
    Name: ShortString;<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 +<br style="word-wrap: break-word; line-height: normal;" />
 TReturnInfo = packed record<br style="word-wrap: break-word; line-height: normal;" />
    Version: Byte; // Must be 1<br style="word-wrap: break-word; line-height: normal;" />
    CallingConvention: TCallingConvention;<br style="word-wrap: break-word; line-height: normal;" />
    ReturnType: ^PTypeInfo;<br style="word-wrap: break-word; line-height: normal;" />
    ParamSize: Word;<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 +<br style="word-wrap: break-word; line-height: normal;" />
 TParamInfo = packed record<br style="word-wrap: break-word; line-height: normal;" />
    Flags: TParamFlags;<br style="word-wrap: break-word; line-height: normal;" />
    ParamType: ^PTypeInfo;<br style="word-wrap: break-word; line-height: normal;" />
    Access: Word;<br style="word-wrap: break-word; line-height: normal;" />
    Name: ShortString;<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 +<br style="word-wrap: break-word; line-height: normal;" />
 ...<br style="word-wrap: break-word; line-height: normal;" />
 +<br style="word-wrap: break-word; line-height: normal;" />
 TParamInfo = packed record<br style="word-wrap: break-word; line-height: normal;" />
    Flags: TParamFlags;<br style="word-wrap: break-word; line-height: normal;" />
    ParamType: ^PTypeInfo;<br style="word-wrap: break-word; line-height: normal;" />
    Access: Word;<br style="word-wrap: break-word; line-height: normal;" />
    Name: ShortString;<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 其中，函数有多少参数就有多少TParamInfo结构体。任何对象函数，都包含第一个隐式参数Self，所以任何函数都至少包含一个TParamInfo结构体。<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 在最新版的Delphi中，为了更好的支持反射，于是默认情况扩展了RTTI信息，所以函数表内容变成了不但含有函数头信息，还包含了返回值和参数信息，故而编译后可执行程序的体积也变得庞大。</span>
				</span>
				<br />
		</font>
		<font class="Apple-style-span" size="4" face="Arial">
				<span class="Apple-style-span" style="font-size: 14px; line-height: 22px;">
						<span class="Apple-style-span" style="font-size: 12px; line-height: normal;">
								<span class="Apple-style-span" style="font-size: 14px; line-height: 22px;">
										<br />
										<br style="word-wrap: break-word; line-height: normal;" />
 
以下函数是获得published部分声明的函数名称，不包含参数和返回值，引用单元ObjAuto。AObj声明时包含编译开关{$M+}。（代码修改
自D7VCL中一段，虽然TObject中有MethodName和MethodAddress两个函数，但是使用汇编撰写的，翻译成Pascal代码，
也差不多就是下面这段的意思）：<br style="word-wrap: break-word; line-height: normal;" />
 function GetObjMethodNames(AObj: TPersistent): String;<br style="word-wrap: break-word; line-height: normal;" />
 var<br style="word-wrap: break-word; line-height: normal;" />
 VMT: Pointer;<br style="word-wrap: break-word; line-height: normal;" />
 MethodInfo: Pointer;<br style="word-wrap: break-word; line-height: normal;" />
 Count: Integer;<br style="word-wrap: break-word; line-height: normal;" />
 begin<br style="word-wrap: break-word; line-height: normal;" />
 VMT := PPointer(AObj)^;<br style="word-wrap: break-word; line-height: normal;" />
 repeat<br style="word-wrap: break-word; line-height: normal;" />
    MethodInfo := PPointer(Integer(VMT) + vmtMethodTable)^;<br style="word-wrap: break-word; line-height: normal;" />
    if MethodInfo &lt;&gt; nil then<br style="word-wrap: break-word; line-height: normal;" />
    begin<br style="word-wrap: break-word; line-height: normal;" />
       Count := PWord(MethodInfo)^;<br style="word-wrap: break-word; line-height: normal;" />
       Inc(Integer(MethodInfo), 2);<br style="word-wrap: break-word; line-height: normal;" />
       while Count &gt; 0 do<br style="word-wrap: break-word; line-height: normal;" />
       begin<br style="word-wrap: break-word; line-height: normal;" />
         Result:= Result+ PMethodInfoHeader(MethodInfo)^.Name+#13+#10;<br style="word-wrap: break-word; line-height: normal;" />
         Inc(Integer(MethodInfo), PMethodInfoHeader(MethodInfo)^.Len);<br style="word-wrap: break-word; line-height: normal;" />
         Dec(Count);<br style="word-wrap: break-word; line-height: normal;" />
       end;<br style="word-wrap: break-word; line-height: normal;" />
    end;<br style="word-wrap: break-word; line-height: normal;" />
    VMT := PPointer(Integer(VMT) + vmtParent)^;<br style="word-wrap: break-word; line-height: normal;" />
    if VMT = nil then<br style="word-wrap: break-word; line-height: normal;" />
    begin<br style="word-wrap: break-word; line-height: normal;" />
       Exit;<br style="word-wrap: break-word; line-height: normal;" />
    end;<br style="word-wrap: break-word; line-height: normal;" />
    VMT := PPointer(VMT)^;<br style="word-wrap: break-word; line-height: normal;" />
 until False;<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 以下代码是获取函数及其参数和返回值，引用单元ObjAuto。AObj声明时包含编译开关{$M+}{$METHODINFO ON}：<br style="word-wrap: break-word; line-height: normal;" />
 function TForm1.GetObjMethods(AObj: TPersistent): String;<br style="word-wrap: break-word; line-height: normal;" />
 const<br style="word-wrap: break-word; line-height: normal;" />
 ConventionName: array [Low(TCallingConvention)..High(TCallingConvention)] of String =<br style="word-wrap: break-word; line-height: normal;" />
    ('Register', 'Cdecl', 'Pascal', 'StdCall', 'SafeCall');<br style="word-wrap: break-word; line-height: normal;" />
 var<br style="word-wrap: break-word; line-height: normal;" />
 StrList: TStringList;<br style="word-wrap: break-word; line-height: normal;" />
 VMT: Pointer;<br style="word-wrap: break-word; line-height: normal;" />
 MethodInfo: PMethodInfoHeader;<br style="word-wrap: break-word; line-height: normal;" />
 Count: Integer;<br style="word-wrap: break-word; line-height: normal;" />
 RoutinPrefix, MethodName, ReturnName, Params: String;<br style="word-wrap: break-word; line-height: normal;" />
 MethodAddr, MethodEnd: Pointer;<br style="word-wrap: break-word; line-height: normal;" />
 ReturnAddr: PReturnInfo;<br style="word-wrap: break-word; line-height: normal;" />
 begin<br style="word-wrap: break-word; line-height: normal;" />
 StrList:= TStringList.Create;<br style="word-wrap: break-word; line-height: normal;" />
 try<br style="word-wrap: break-word; line-height: normal;" />
    VMT := PPointer(AObj)^;<br style="word-wrap: break-word; line-height: normal;" />
    repeat<br style="word-wrap: break-word; line-height: normal;" />
       MethodInfo := PPointer(Integer(VMT) + vmtMethodTable)^;<br style="word-wrap: break-word; line-height: normal;" />
       if MethodInfo &lt;&gt; nil then<br style="word-wrap: break-word; line-height: normal;" />
       begin<br style="word-wrap: break-word; line-height: normal;" />
         // Scan method table for the method<br style="word-wrap: break-word; line-height: normal;" />
         Count := PWord(MethodInfo)^;<br style="word-wrap: break-word; line-height: normal;" />
         Inc(Integer(MethodInfo), 2);<br style="word-wrap: break-word; line-height: normal;" />
         while Count &gt; 0 do<br style="word-wrap: break-word; line-height: normal;" />
         begin<br style="word-wrap: break-word; line-height: normal;" />
            RoutinPrefix:= '';<br style="word-wrap: break-word; line-height: normal;" />
            ReturnName:= ';';<br style="word-wrap: break-word; line-height: normal;" />
            Params:= '';<br style="word-wrap: break-word; line-height: normal;" />
            //now methodinfo points to head of method<br style="word-wrap: break-word; line-height: normal;" />
            MethodName:= MethodInfo^.Name;<br style="word-wrap: break-word; line-height: normal;" />
            MethodEnd := Pointer(Integer(MethodInfo) + MethodInfo^.Len);<br style="word-wrap: break-word; line-height: normal;" />
            ReturnAddr:= Pointer(Integer(MethodInfo)+SizeOf(TMethodInfoHeader)-<br style="word-wrap: break-word; line-height: normal;" />
               SizeOf(ShortString)+1+Length(MethodName));<br style="word-wrap: break-word; line-height: normal;" />
            MethodAddr:=Pointer(Integer(ReturnAddr)+SizeOf(TReturnInfo));<br style="word-wrap: break-word; line-height: normal;" />
            // RTTI involves methodinfo<br style="word-wrap: break-word; line-height: normal;" />
            if Integer(MethodAddr) &lt; Integer(MethodEnd) then<br style="word-wrap: break-word; line-height: normal;" />
            begin<br style="word-wrap: break-word; line-height: normal;" />
               if ReturnAddr^.ReturnType= nil then RoutinPrefix:='Procedure'<br style="word-wrap: break-word; line-height: normal;" />
               else<br style="word-wrap: break-word; line-height: normal;" />
               begin<br style="word-wrap: break-word; line-height: normal;" />
                 RoutinPrefix:= 'Function';<br style="word-wrap: break-word; line-height: normal;" />
                 ReturnName:= ': '+ReturnAddr^.ReturnType^^.Name+ ';';<br style="word-wrap: break-word; line-height: normal;" />
               end;<br style="word-wrap: break-word; line-height: normal;" />
               //add routin's convention type<br style="word-wrap: break-word; line-height: normal;" />
               ReturnName:= ReturnName+ ' '+ConventionName[ReturnAddr^.CallingConvention];<br style="word-wrap: break-word; line-height: normal;" />
               //the first parameter is self pointer and be hidden<br style="word-wrap: break-word; line-height: normal;" />
               Inc(Integer(MethodAddr), SizeOf(TParamInfo) -SizeOf(ShortString) + 1 +<br style="word-wrap: break-word; line-height: normal;" />
                 Length(PParamInfo(MethodAddr)^.Name));<br style="word-wrap: break-word; line-height: normal;" />
               while Integer(MethodAddr) &lt; Integer(MethodEnd) do<br style="word-wrap: break-word; line-height: normal;" />
               begin<br style="word-wrap: break-word; line-height: normal;" />
                 Params:= Params+ PParamInfo(MethodAddr)^.Name+': '+<br style="word-wrap: break-word; line-height: normal;" />
                    PParamInfo(MethodAddr)^.ParamType^^.Name;<br style="word-wrap: break-word; line-height: normal;" />
                 Inc(Integer(MethodAddr), SizeOf(TParamInfo) -SizeOf(ShortString) + 1 +<br style="word-wrap: break-word; line-height: normal;" />
                    Length(PParamInfo(MethodAddr)^.Name));<br style="word-wrap: break-word; line-height: normal;" />
               end;<br style="word-wrap: break-word; line-height: normal;" />
            end;<br style="word-wrap: break-word; line-height: normal;" />
            //output information<br style="word-wrap: break-word; line-height: normal;" />
            StrList.Append(Format(RoutinPrefix+' %s(%s)%s;', [MethodName,Params, ReturnName]));<br style="word-wrap: break-word; line-height: normal;" />
            //jump to the next method<br style="word-wrap: break-word; line-height: normal;" />
            Inc(Integer(MethodInfo),PMethodInfoHeader(MethodInfo)^.Len);<br style="word-wrap: break-word; line-height: normal;" />
            Dec(Count);<br style="word-wrap: break-word; line-height: normal;" />
         end;<br style="word-wrap: break-word; line-height: normal;" />
       end;<br style="word-wrap: break-word; line-height: normal;" />
       // Find the parent VMT<br style="word-wrap: break-word; line-height: normal;" />
       VMT := PPointer(Integer(VMT) + vmtParent)^;<br style="word-wrap: break-word; line-height: normal;" />
       if VMT = nil then<br style="word-wrap: break-word; line-height: normal;" />
       begin<br style="word-wrap: break-word; line-height: normal;" />
         Break;<br style="word-wrap: break-word; line-height: normal;" />
       end;<br style="word-wrap: break-word; line-height: normal;" />
       VMT := PPointer(VMT)^;<br style="word-wrap: break-word; line-height: normal;" />
    until False;<br style="word-wrap: break-word; line-height: normal;" />
    Result:= StrList.Text;<br style="word-wrap: break-word; line-height: normal;" />
 finally<br style="word-wrap: break-word; line-height: normal;" />
    StrList.Free;<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 end;</span>
						</span>
				</span>
		</font>
		<font size="4" face="Arial">
				<br />
		</font>
		<pre id="prestr">［作者：Savetime    转贴自：Delphibbs.com    点击数：1560    更新时间：2004-12-28    文章录入：aleyn］ <br /><br />目录<br />===============================================================================<br />⊙ RTTI 简介<br />⊙ 类(class) 和 VMT 的关系<br />⊙ 类(class)、类的类(class of class)、类变量(class variable) 的关系<br />⊙ TObject.ClassType 和 TObject.ClassInfo<br />⊙ is 和 as 运算符的原理<br />⊙ TTypeInfo – RTTI 信息的结构<br />⊙ 获取类(class)的属性(property)信息<br />⊙ 获取方法(method)的类型信息<br />⊙ 获取有序类型(ordinal)、集合(set)类型的 RTTI 信息<br />⊙ 获取其它数据类型的 RTTI 信息<br />===============================================================================<br /><br />本文排版格式为：<br />    正文由窗口自动换行；所有代码以 80 字符为边界；中英文字符以空格符分隔。<br /><br />(作者保留对本文的所有权利，未经作者同意请勿在在任何公共媒体转载。)<br /><br /><br />正文<br />===============================================================================<br />⊙ RTTI 简介<br />===============================================================================<br /><br />RTTI(Run-Time Type Information) 翻译过来的名称是“运行期类型信息”，也就是说可以在运行期获得数据类型或类(class)的信息。这个 RTTI 到底有什么用处，我现在也说不清楚。我是在阅读 Delphi 持续机制的代码中发现了很多 RTTI 的运用，只好先把 RTTI 学习一遍。下面是我的学习笔记。如果你发现了错误请告诉我。谢谢！<br /><br />Delphi 的 RTTI 主要分为类(class)的 RTTI 和一般数据类型的 RTTI，下面从类(class)开始。<br /><br />===============================================================================<br />⊙ 类(class) 和 VMT 的关系<br />===============================================================================<br /><br />一个类(class)，从编译器的角度来看就是一个指向 VMT 的指针(在后文用 VMTptr 表示)。在类的 VMTptr 的负地址方向存储了一些类信息的指针，这些指针的值和指针所指的内容在编译后就确定了。比如 VMTptr - 44 的内容是指向类名称(ClassName)的指针。不过一般不使用数值来访问这些类信息，而是通过 System.pas 中定义的以 vmt 开头的常量，如 vtmClassName、vmtParent 等来访问。<br /><br />类的方法有两种：对象级别的方法和类级别的方法。两者的 Self 指针意义是不同的。在对象级别的方法中 Self 指向对象地址空间，因此可以用它来访问对象的成员函数；在类级别的方法中 Self 指向类的 VMT，因此只能用它来访问 VMT 信息，而不能访问对象的成员字段。<br /><br />===============================================================================<br />⊙ 类(class)、类的类(class of class)、类变量(class variable) 的关系<br />===============================================================================<br /><br />上面说到类(class) 就是 VMTptr。在 Delphi 中还可以用 class of 关键字定义类的类，并且可以使用类的类定义类变量。从语法上理解这三者的关键并不难，把类当成普通的数据类型来考虑就可以了。在编译器级别上表现如何呢？<br /><br />为了简化讨论，我们使用 TObject、TClass 和 TMyClass 来代表上面说的三种类型：<br /><br />type<br />  TClass = class of TObject;<br />var<br />  TMyClass: TClass;<br />  MyObject: TObject;<br />begin<br />  TMyClass := TObject;<br />  MyObject := TObject.Create;<br />  MyObject := TClass.Create;<br />  MyObject := TMyClass.Create;<br />end;<br /><br />在上面的例子中，三个 TObject 对象都被成功地创建了。编译器的实现是：TObject 是一个 VMTPtr 常量。TClass 也是一个 VMTptr 常量，它的值就是 TObject。TMyClass 是一个 VMTptr 变量，它被赋值为 TObject。TObject.Create 与 TClass.Create 的汇编代码完全相同。但 TClass 不仅缺省代表一个类，而且还(主要)代表了类的类型，可以用它来定义类变量，实现一些类级别的操作。<br /><br />===============================================================================<br />⊙ TObject.ClassType 和 TObject.ClassInfo<br />===============================================================================<br /><br />function TObject.ClassType: TClass;<br />begin<br />  Pointer(Result) := PPointer(Self)^;<br />end;<br /><br />TObject.ClassType 是对象级别的方法，Self 的值是指向对象内存空间的指针，对象内存空间的前 4 个字节是类的 VMTptr。因此这个函数的返回值就是类的 VMTptr。<br /><br />class function TObject.ClassInfo: Pointer;<br />begin<br />  Result := PPointer(Integer(Self) + vmtTypeInfo)^;<br />end;<br /><br />TObject.ClassInfo 使用 class 关键字定义，因此是一个类级别的方法。该方法中的 Self 指针就是 VMTptr。所以这个函数的返回值是 VMTptr 负方向的 vmtTypeInfo 的内容。<br /><br />TObject.ClassInfo 返回的 Pointer 指针，实际上是指向类的 RTTI 结构的指针。但是不能访问 TObject.ClassInfo 指向的内容(TObject.ClassInfo 返回值是 0)，因为 Delphi 只在 TPersistent 类及 TPersistent 的后继类中产生 RTTI 信息。(从编译器的角度来看，这是在 TPersistent 类的声明之前使用 {$M+} 指示字的结果。)<br /><br />TObject 还定义了一些获取类 RTTI 信息的函数，列举在下，就不一一分析了：<br /><br />  TObject.ClassName: ShortString;   类的名称<br />  TObject.ClassParent: TClass;      对象的父类<br />  TObject.InheritsFrom: Boolean;    是否继承自某类<br />  TObject.InstanceSize: Longint;    对象实例的大小<br /><br />===============================================================================<br />⊙ is 和 as 运算符的原理<br />===============================================================================<br /><br />我们知道可以在运行期使用 is 关键字判断一个对象是否属于某个类，可以使用 as 关键字把某个对象安全地转换为某个类。在编译器的层次上，is 和 as 的操作是由 System.pas 中两个函数完成的。<br /><br />{ System.pas }<br />function _IsClass(Child: TObject; Parent: TClass): Boolean;<br />begin<br />  Result := (Child &lt;&gt; nil) and Child.InheritsFrom(Parent);<br />end;<br /><br />_IsClass 很简单，它使用 TObject 的 InheritsForm 函数判断该对象是否是从某个类或它的父类中继承下来的。每个类的 VMT 中都有一项 vmtParent 指针，指向该类的父类的 VMT。TObject.InheritsFrom 实际上是通过[递归]判断父类 VMT 指针是否等于自己的 VMT 指针来判断是否是从该类继承的。<br /><br />{ System.pas }<br />class function TObject.InheritsFrom(AClass: TClass): Boolean;<br />var<br />  ClassPtr: TClass;<br />begin<br />  ClassPtr := Self;<br />  while (ClassPtr &lt;&gt; nil) and (ClassPtr &lt;&gt; AClass) do<br />    ClassPtr := PPointer(Integer(ClassPtr) + vmtParent)^;<br />  Result := ClassPtr = AClass;<br />end;<br /><br />as 操作符实际上是由 System.pas 中的 _AsClass 函数完成的。它简单地调用 is 操作符判断对象是否属于某个类，如果不是就触发异常。虽然 _AsClass 返回值为 TObject 类型，但编译器会自动把返回的对象改变为 Parent 类，否则返回的对象没有办法使用 TObject 之外的方法和数据。<br /><br />{ System.pas }<br />function _AsClass(Child: TObject; Parent: TClass): TObject;<br />begin<br />  Result := Child;<br />  if not (Child is Parent) then<br />    Error(reInvalidCast);   // loses return address<br />end;<br /><br />===============================================================================<br />⊙ TTypeInfo – RTTI 信息的结构<br />===============================================================================<br /><br />RTTI 信息的结构定义在 TypInfo.pas 中：<br /><br />  TTypeInfo = record        // TTypeInfo 是 RTTI 信息的结构<br />    Kind: TTypeKind;        // RTTI 信息的数据类型<br />    Name: ShortString;      // 数据类型的名称<br />   {TypeData: TTypeData}    // RTTI 的内容<br />  end;<br /><br />TTypeInfo 就是 RTTI 信息的结构。TObject.ClassInfo 返回指向存放 class TTypeInfo 信息的指针。Kind 是枚举类型，它表示 RTTI 结构中所包含数据类型。Name 是数据类型的名称。注意，最后一个字段 TypeData 被注释掉了，这说明该处的结构内容根据不同的数据类型有所不同。<br /><br />TTypeKind 枚举定义了可以使用 RTTI 信息的数据类型，它几乎包含了所有的 Delphi 数据类型，其中包括 tkClass。<br /><br />  TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat,<br />    tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString,<br />    tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray);<br /><br />TTypeData 是个巨大的记录类型，在此不再列出，后文会根据需要列出该记录的内容。<br /><br />===============================================================================<br />⊙ 获取类(class)的属性(property)信息<br />===============================================================================<br /><br />这一段是 RTTI 中最复杂的部分，努力把本段吃透，后面的内容都是非常简单的。<br /><br />下面是一个获取类的属性的例子：<br /><br />procedure GetClassProperties(AClass: TClass; AStrings: TStrings);<br />var<br />  PropCount, I: SmallInt;<br />  PropList: PPropList;<br />  PropStr: string;<br />begin<br />  PropCount := GetTypeData(AClass.ClassInfo).PropCount;<br />  GetPropList(AClass.ClassInfo, PropList);<br />  for I := 0 to PropCount - 1 do<br />  begin<br />    case PropList[I]^.PropType^.Kind of<br />      tkClass      : PropStr := '[Class] ';<br />      tkMethod     : PropStr := '[Method]';<br />      tkSet        : PropStr := '[Set]   ';<br />      tkEnumeration: PropStr := '[Enum]  ';<br />    else<br />      PropStr := '[Field] ';<br />    end;<br />    PropStr := PropStr + PropList[I]^.Name;<br />    PropStr := PropStr + ': ' + PropList[I]^.PropType^.Name;<br />    AStrings.Add(PropStr);<br />  end;<br />  FreeMem(PropList);<br />end;<br /><br />你可以在表单上放置一个 TListBox ，然后执行以下语句观察执行结果：<br /><br />  GetClassProperties(TForm1, ListBox1.Items);<br /><br />该函数先使用 GetTypeData 函数获得类的属性数量。GetTypeData 是 TypInfo.pas 中的一个函数，它的功能是返回 TTypeInfo 的 TypeData 数据的指针：<br /><br />{ TypInfo.pas }<br />function GetTypeData(TypeInfo: PTypeInfo): PTypeData; assembler;<br /><br />class 的 TTypeData 结构如下：<br /><br />  TTypeData = packed record<br />    case TTypeKind of<br />      tkClass: (<br />        ClassType: TClass;         // 类 (VMTptr)<br />        ParentInfo: PPTypeInfo;    // 父类的 RTTI 指针<br />        PropCount: SmallInt;       // 属性数量<br />        UnitName: ShortStringBase; // 单元的名称<br />       {PropData: TPropData});     // 属性的详细信息<br />  end;<br /><br />其中的 PropData 又是一个大小可变的字段。TPropData 的定义如下：<br /><br />  TPropData = packed record<br />    PropCount: Word;       // 属性数量<br />    PropList: record end;  // 占位符，真正的意义在下一行<br />    {PropList: array[1..PropCount] of TPropInfo}<br />  end;<br /><br />每个属性信息在内存中的结构就是 TPropInfo，它的定义如下：<br /><br />  PPropInfo = ^TPropInfo;<br />  TPropInfo = packed record<br />    PropType: PPTypeInfo;    // 属性类型信息指针的指针<br />    GetProc: Pointer;        // 属性的 Get 方法指针<br />    SetProc: Pointer;        // 属性的 Set 方法指针<br />    StoredProc: Pointer;     // 属性的 StoredProc 指针<br />    Index: Integer;          // 属性的 Index 值<br />    Default: Longint;        // 属性的 Default 值<br />    NameIndex: SmallInt;     // 属性的名称索引(以 0 开始计数)<br />    Name: ShortString;       // 属性的名称<br />  end;<br /><br />为了方便访问属性信息，TypInfo.pas 中还定义了指向 TPropInfo 数组的指针：<br /><br />  PPropList = ^TPropList;<br />  TPropList = array[0..16379] of PPropInfo;<br /><br />我们可以使用 GetPropList 获得所有属性信息的指针数组，数组用完以后要记得用 FreeMem 把数组的内存清除。<br /><br />{ TypInfo.pas }<br />function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): Integer;<br /><br />GetPropList 传入类的 TTypeInfo 指针和 TPropList 的指针，它为 PropList 分配一块内存后把该内存填充为指向 TPropInfo 的指针数组，最后返回属性的数量。<br /><br />上面的例子演示了如何获得类的所有属性信息，也可以根据属性的名称单独获得属性信息：<br /><br />{ TypInfo.pas }<br />function GetPropInfo(TypeInfo: PTypeInfo; const PropName: string): PPropInfo;<br /><br />GetPropInfo 根据类的 RTTI 指针和属性的名称字符串，返回属性的信息 TPropInfo 的指针。如果没有找到该属性，则返回 nil。GetPropInfo 很容易使用，举个例子：<br /><br />  ShowMessage(GetPropInfo(TForm, 'Name')^.PropType^.Name);<br /><br />这句调用显示了 TForm 类的 Name 属性的类型名称：TComponentName。<br /><br />===============================================================================<br />⊙ 获取方法(method)的类型信息<br />===============================================================================<br /><br />所谓方法就是以 of object 关键字声明的函数指针，下面的函数可以显示一个方法的类型信息：<br /><br />procedure GetMethodTypeInfo(ATypeInfo: PTypeInfo; AStrings: TStrings);<br />type<br />  PParamData = ^TParamData;<br />  TParamData = record       // 函数参数的数据结构<br />    Flags: TParamFlags;     // 参数传递规则<br />    ParamName: ShortString; // 参数的名称<br />    TypeName: ShortString;  // 参数的类型名称<br />  end;<br />  function GetParamFlagsName(AParamFlags: TParamFlags): string;<br />  var<br />    I: Integer;<br />  begin<br />    Result := '';<br />    for I := Integer(pfVar) to Integer(pfOut) do begin<br />      if I = Integer(pfAddress) then Continue;<br />      if TParamFlag(I) in AParamFlags then<br />        Result := Result + ' ' + GetEnumName(TypeInfo(TParamFlag), I);<br />    end;<br />  end;<br />var<br />  MethodTypeData: PTypeData;<br />  ParamData: PParamData;<br />  TypeStr: PShortString;<br />  I: Integer;<br />begin<br />  MethodTypeData := GetTypeData(ATypeInfo);<br />  AStrings.Add('---------------------------------');<br />  AStrings.Add('Method Name: ' + ATypeInfo^.Name);<br />  AStrings.Add('Method Kind: ' + GetEnumName(TypeInfo(TMethodKind),<br />    Integer(MethodTypeData^.MethodKind)));<br />  AStrings.Add('Params Count: '+ IntToStr(MethodTypeData^.ParamCount));<br />  AStrings.Add('Params List:');<br />  ParamData := PParamData(@MethodTypeData^.ParamList);<br />  for I := 1 to MethodTypeData^.ParamCount do<br />  begin<br />    TypeStr := Pointer(Integer(@ParamData^.ParamName) +<br />      Length(ParamData^.ParamName) + 1);<br />    AStrings.Add(Format('  [%s] %s: %s',[GetParamFlagsName(ParamData^.Flags),<br />      ParamData^.ParamName, TypeStr^]));<br />    ParamData := PParamData(Integer(ParamData) + SizeOf(TParamFlags) +<br />      Length(ParamData^.ParamName) + Length(TypeStr^) + 2);<br />  end;<br />  if MethodTypeData^.MethodKind = mkFunction then<br />    AStrings.Add('Result Value: ' + PShortString(ParamData)^);<br />end;<br /><br />作为实验，在表单上放置一个 TListBox，然后执行以下代码，观察执行结果：<br /><br />type<br />  TMyMethod = function(A: array of Char; var B: TObject): Integer of object;<br />procedure TForm1.FormCreate(Sender: TObject);<br />begin<br />  GetMethodTypeInfo(TypeInfo(TMyMethod), ListBox1.Items);<br />  GetMethodTypeInfo(TypeInfo(TMouseEvent), ListBox1.Items);<br />  GetMethodTypeInfo(TypeInfo(TKeyPressEvent), ListBox1.Items);<br />  GetMethodTypeInfo(TypeInfo(TMouseWheelEvent), ListBox1.Items);<br />end;<br /><br />由于获取方法的类型信息比较复杂，我尽量压缩代码也还是有这么长，让我们看看它的实现原理。GetMethodTypeInfo 的第一个参数是 PTypeInfo 类型，表示方法的类型信息地址。第二个参数是一个字符串列表，可以使用任何实现 TStrings 操作的对象。我们可以使用 System.pas 中的 TypeInfo 函数获得任何类型的 RTTI 信息指针。TypeInfo 函数像 SizeOf 一样，是内置于编译器中的。<br /><br />GetMethodTypeInfo 还用到了 TypInfo.pas 中的 GetEnumName 函数。这个函数通过枚举类型的整数值得到枚举类型的名称。<br /><br />function GetEnumName(TypeInfo: PTypeInfo; Value: Integer): string;<br /><br />与获取类(class)的属性信息类似，方法的类型信息也在 TTypeData 结构中<br /><br />  TTypeData = packed record<br />    case TTypeKind of<br />      tkMethod: (<br />        MethodKind: TMethodKind;            // 方法指针的类型<br />        ParamCount: Byte;                   // 参数数量<br />        ParamList: array[0..1023] of Char   // 参数详细信息，见下行注释<br />       {ParamList: array[1..ParamCount] of<br />          record<br />            Flags: TParamFlags;             // 参数传递规则 <br />            ParamName: ShortString;         // 参数的名称<br />            TypeName: ShortString;          // 参数的类型<br />          end;<br />        ResultType: ShortString});          // 返回值的名称<br />  end;<br /><br />TMethodKind 是方法的类型，定义如下：<br /><br />  TMethodKind = (mkProcedure, mkFunction, mkConstructor, mkDestructor,<br />    mkClassProcedure, mkClassFunction,<br />    { Obsolete }<br />    mkSafeProcedure, mkSafeFunction);<br /><br />TParamsFlags 是参数传递的规则，定义如下：<br /><br />  TParamFlag = (pfVar, pfConst, pfArray, pfAddress, pfReference, pfOut);<br />  TParamFlags = set of TParamFlag;<br /><br />由于 ParamName 和 TypeName 是变长字符串，不能直接取用该字段的值，而应该使用指针步进的方法，取出参数信息，所以上面的代码显得比较长。<br /><br />===============================================================================<br />⊙ 获取有序类型(ordinal)、集合(set)类型的 RTTI 信息<br />===============================================================================<br /><br />讨论完了属性和方法的 RTTI 信息之后再来看其它数据类型的 RTTI 就简单多了。所有获取 RTTI 的原理都是通过 GetTypeData 函数得到 TTypeData 的指针，再通过 TTypeInfo.TypeKind 来解析 TTypeData。任何数据类型的 TTypeInfo 指针可以通过 TypeInfo 函数获得。<br /><br />有序类型的 TTypeData 定义如下：<br /><br />TTypeData = packed record<br />  tkInteger, tkChar, tkEnumeration, tkSet, tkWChar: (<br />    OrdType: TOrdType;         // 有序数值类型<br />    case TTypeKind of<br />      case TTypeKind of<br />        tkInteger, tkChar, tkEnumeration, tkWChar: (<br />          MinValue: Longint;   // 类型的最小值<br />          MaxValue: Longint;   // 类型的最大值<br />          case TTypeKind of<br />            tkInteger, tkChar, tkWChar: ();<br />            tkEnumeration: (<br />              BaseType: PPTypeInfo;      // 指针的指针，它指向枚举的 PTypeInfo<br />              NameList: ShortStringBase;     // 枚举的名称字符串(不能直接取用)<br />              EnumUnitName: ShortStringBase)); // 所在的单元名称(不能直接取用)<br />          tkSet: (<br />            CompType: PPTypeInfo));            // 指向集合基类 RTTI 指针的指针<br />end;<br /><br />下面是一个获取有序类型和集合类型的 RTTI 信息的函数：<br /><br />procedure GetOrdTypeInfo(ATypeInfo: PTypeInfo; AStrings: TStrings);<br />var<br />  OrdTypeData: PTypeData;<br />  I: Integer;<br />begin<br />  OrdTypeData := GetTypeData(ATypeInfo);<br />  AStrings.Add('------------------------------------');<br />  AStrings.Add('Type Name: ' + ATypeInfo^.Name);<br />  AStrings.Add('Type Kind: ' + GetEnumName(TypeInfo(TTypeKind),<br />    Integer(ATypeInfo^.Kind)));<br />  AStrings.Add('Data Type: ' + GetEnumName(TypeInfo(TOrdType),<br />    Integer(OrdTypeData^.OrdType)));<br />  if ATypeInfo^.Kind &lt;&gt; tkSet then begin<br />    AStrings.Add('Min Value: ' + IntToStr(OrdTypeData^.MinValue));<br />    AStrings.Add('Max Value: ' + IntToStr(OrdTypeData^.MaxValue));<br />  end;<br />  if ATypeInfo^.Kind = tkSet then<br />    GetOrdTypeInfo(OrdTypeData^.CompType^, AStrings);<br />  if ATypeInfo^.Kind = tkEnumeration then<br />    for I := OrdTypeData^.MinValue to OrdTypeData^.MaxValue do<br />      AStrings.Add(Format('  Value %d: %s', [I, GetEnumName(ATypeInfo, I)]));<br />end;<br /><br />在表单上放置一个 TListBox，运行以下代码查看结果：<br /><br />type TMyEnum = (EnumA, EnumB, EnumC);<br />procedure TForm1.FormCreate(Sender: TObject);<br />begin<br />  GetOrdTypeInfo(TypeInfo(Char), ListBox1.Items);<br />  GetOrdTypeInfo(TypeInfo(Integer), ListBox1.Items);<br />  GetOrdTypeInfo(TypeInfo(TFormBorderStyle), ListBox1.Items);<br />  GetOrdTypeInfo(TypeInfo(TBorderIcons), ListBox1.Items);<br />  GetOrdTypeInfo(TypeInfo(TMyEnum), ListBox1.Items);<br />end;<br /><br />(如果枚举元素没有按缺省的 0 基准定义，那么将不能产生 RTTI 信息，为什么？)<br /><br />===============================================================================<br />⊙ 获取其它数据类型的 RTTI 信息<br />===============================================================================<br /><br />上面讨论了几个典型的 RTTI 信息的运行，其它的数据类型的 RTTI 信息的获取方法与上面类似。由于这些操作更加简单，就不一一讨论。下面概述其它类型的 RTTI 信息的情况：<br /><br />LongString、WideString 和 Variant 没有 RTTI 信息；<br />ShortString 只有 MaxLength 信息；<br />浮点数类型只有 FloatType: TFloatType 信息；<br />  TFloatType = (ftSingle, ftDouble, ftExtended, ftComp, ftCurr);<br />Int64 只有最大值和最小值信息(也是 64 位整数表示)；<br />Interface 和动态数组不太熟悉，就不作介绍了。<br /><br />===============================================================================<br />⊙ 结束<br />=============================================================================== <br /></pre>
		<br />
<img src ="http://www.cnitblog.com/textbox/aggbug/68222.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2010-08-18 17:18 <a href="http://www.cnitblog.com/textbox/archive/2010/08/18/68222.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Delphi 字符驱动资料</title><link>http://www.cnitblog.com/textbox/archive/2010/08/18/68221.html</link><dc:creator>零度</dc:creator><author>零度</author><pubDate>Wed, 18 Aug 2010 09:13:00 GMT</pubDate><guid>http://www.cnitblog.com/textbox/archive/2010/08/18/68221.html</guid><wfw:comment>http://www.cnitblog.com/textbox/comments/68221.html</wfw:comment><comments>http://www.cnitblog.com/textbox/archive/2010/08/18/68221.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/textbox/comments/commentRss/68221.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/textbox/services/trackbacks/68221.html</trackback:ping><description><![CDATA[
		<font class="Apple-style-span" size="4">
				<span class="Apple-style-span" style="font-size: 14px; line-height: 22px;">
						<b>第一种：</b>
						<br style="word-wrap: break-word; line-height: normal;" />
 调用TObject.MethodAddress根据函数名称获得函数地址，这时由于只是得到函数地址，需要在调用端明确知道函数类型才能调用。形如以下代码：<br style="word-wrap: break-word; line-height: normal;" />
 var<br style="word-wrap: break-word; line-height: normal;" />
 P: procedure(Sender: TObject) of object;<br style="word-wrap: break-word; line-height: normal;" />
 begin<br style="word-wrap: break-word; line-height: normal;" />
 with TMethod(P) do<br style="word-wrap: break-word; line-height: normal;" />
 begin<br style="word-wrap: break-word; line-height: normal;" />
    Data:= Sender;<br style="word-wrap: break-word; line-height: normal;" />
    Code:= Sender.MethodAddress('OnbtnClick');<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 P(Sender);<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 
这种调用，形式简单，关联速度快，调用速度几乎不受损失。持久化机制中，对于Event-EventHandler关联和事件调用，就是采用该种方式。缺
点是，该种方式获取函数地址的时候，并不能得到函数的类型和参数列表，除非在调用端明确知道函数类型，否则无法执行函数。基于此方法而设计的系统，例如<span class="t_tag" href="http://hi.baidu.com/delphicode/blog/item/tag.php?name=Delphi" style="word-wrap: break-word; line-height: normal; cursor: pointer; border-bottom: 1px solid rgb(255, 0, 0); white-space: nowrap;">Delphi</span>持久化Event，都是依靠Event才知道Handler的类型，他们之间的关联有效性往往是在先期某个阶段就有检查。<br style="word-wrap: break-word; line-height: normal;" /><b>第二种：</b><br style="word-wrap: break-word; line-height: normal;" />
 
这是一种更加灵活一点的函数动态执行方式，使用ObjAuto单元中ObjectInvoke方法（参数：Instance，声明函数的对
象；PMethodInfoHeader，函数的头信息；Params，传入参数的开放数组，传入参数的顺序和声明顺序相反，例如，声明成
procedure<br style="word-wrap: break-word; line-height: normal;" />
 pro(P1: Integer; P2: 
String)，传参的时候，该数组要写成['str',2]）。能够被ObjectInvoke驱动的函数应是声明在对象的published部分，对
象声明的时候要加上编译开关{$M+}{$METHODINFO ON}。<br style="word-wrap: break-word; line-height: normal;" />
 假定有以下的类声明：<br style="word-wrap: break-word; line-height: normal;" />
 type TMyType = type String;<br style="word-wrap: break-word; line-height: normal;" />
 type<br style="word-wrap: break-word; line-height: normal;" />
 ITest = interface(IInvokable)<br style="word-wrap: break-word; line-height: normal;" />
 ['{E6344DBD-8663-40F2-8C7A-C6DFC4FCCA51}']<br style="word-wrap: break-word; line-height: normal;" />
    procedure ShowMsg(); stdcall;<br style="word-wrap: break-word; line-height: normal;" />
    function AddStr(A1: String; A2: Integer): String; stdcall;<br style="word-wrap: break-word; line-height: normal;" />
    function GetName(AComponent: TComponent): String; stdcall;<br style="word-wrap: break-word; line-height: normal;" />
    procedure IncNum(var AInt: Integer); stdcall;<br style="word-wrap: break-word; line-height: normal;" />
    function BuildObjByClass(AClassName: String): TComponent; stdcall;<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 {$METHODINFO ON}<br style="word-wrap: break-word; line-height: normal;" />
 TTest = class(TInterfacedPersistent, ITest)<br style="word-wrap: break-word; line-height: normal;" />
 private<br style="word-wrap: break-word; line-height: normal;" />
    FF2: Integer;<br style="word-wrap: break-word; line-height: normal;" />
    FF1: String;<br style="word-wrap: break-word; line-height: normal;" />
    FF3: TObject;<br style="word-wrap: break-word; line-height: normal;" />
    FF4: TMyType;<br style="word-wrap: break-word; line-height: normal;" />
 public<br style="word-wrap: break-word; line-height: normal;" />
    procedure AfterConstruction; override;<br style="word-wrap: break-word; line-height: normal;" />
    procedure BeforeDestruction; override;<br style="word-wrap: break-word; line-height: normal;" />
 published<br style="word-wrap: break-word; line-height: normal;" />
    property F1: String read FF1 write FF1;<br style="word-wrap: break-word; line-height: normal;" />
    property F2: Integer read FF2 write FF2;<br style="word-wrap: break-word; line-height: normal;" />
    property F3: TObject read FF3 write FF3;<br style="word-wrap: break-word; line-height: normal;" />
    property F4: TMyType read FF4 write FF4;<br style="word-wrap: break-word; line-height: normal;" />
    procedure ShowMsg(); stdcall;<br style="word-wrap: break-word; line-height: normal;" />
    function AddStr(A1: String; A2: Integer): String; stdcall;<br style="word-wrap: break-word; line-height: normal;" />
    function GetName(AComponent: TComponent): String; stdcall;<br style="word-wrap: break-word; line-height: normal;" />
    procedure IncNum(var AInt: Integer); stdcall;<br style="word-wrap: break-word; line-height: normal;" />
    function BuildObjByClass(AClassName: String): TComponent; stdcall;<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 {$METHODINFO OFF}<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 驱动函数ShowMsg，这个比较简单，没有参数和返回值。<br style="word-wrap: break-word; line-height: normal;" />
 ObjAuto.ObjectInvoke(FTest, GetMethodInfo(FTest, 'ShowMsg'), [] ,[]);<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 驱动函数AddStr，两个不同类型的参数，传参的时候是倒序，有一个返回值，但都是简单类型。<br style="word-wrap: break-word; line-height: normal;" />
 var<br style="word-wrap: break-word; line-height: normal;" />
 ResultValue: Variant;<br style="word-wrap: break-word; line-height: normal;" />
 begin<br style="word-wrap: break-word; line-height: normal;" />
 ResultValue:= ObjAuto.ObjectInvoke(FTest, GetMethodInfo(FTest, 'AddStr'), [] , [1, 'BBB']);<br style="word-wrap: break-word; line-height: normal;" />
 ShowMessage(VarToStr(ResultValue));<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 驱动函数IncNum，注意参数是var，传入的是引用，给Variant变量赋值的时候有些讲究。<br style="word-wrap: break-word; line-height: normal;" />
 var<br style="word-wrap: break-word; line-height: normal;" />
 ResultValue: Variant;<br style="word-wrap: break-word; line-height: normal;" />
 Param: Variant;<br style="word-wrap: break-word; line-height: normal;" />
 I: Integer;<br style="word-wrap: break-word; line-height: normal;" />
 begin<br style="word-wrap: break-word; line-height: normal;" />
 I:= 1;<br style="word-wrap: break-word; line-height: normal;" />
 with TVarData(Param) do<br style="word-wrap: break-word; line-height: normal;" />
 begin<br style="word-wrap: break-word; line-height: normal;" />
    VType:= varInteger or varByRef;<br style="word-wrap: break-word; line-height: normal;" />
    VPointer:= @I;<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" />
 ObjAuto.ObjectInvoke(FTest, GetMethodInfo(FTest, 'IncNum'), [] ,[Param]);<br style="word-wrap: break-word; line-height: normal;" />
 ShowMessage(IntToStr(I));<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 驱动函数BuildObjByClass，返回的是对象类型，对象地址在TVarData.VPointer上，但Variant不支持对象类型，故TVarData.VType为unknown。<br style="word-wrap: break-word; line-height: normal;" />
 var<br style="word-wrap: break-word; line-height: normal;" />
 ResultValue: Variant;<br style="word-wrap: break-word; line-height: normal;" />
 begin<br style="word-wrap: break-word; line-height: normal;" />
 ResultValue:= ObjAuto.ObjectInvoke(FTest, GetMethodInfo(FTest,'BuildObjByClass'), [] , ['TForm1']);<br style="word-wrap: break-word; line-height: normal;" />
 ShowMessage(TComponent(TVarData(ResultValue).VPointer).ClassName);<br style="word-wrap: break-word; line-height: normal;" />
 ...<br style="word-wrap: break-word; line-height: normal;" />
 end;<br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" /><br style="word-wrap: break-word; line-height: normal;" />
 
在这里，并没有给出函数GetName是如何驱动，这是因为在使用ObjectInvoke的时候，ObjectInvoke参数为variant类型，
由于Variant不支持对象以及指针类型，所以TVarData.VType为unknown，尽管TVarData.VPointer上可能有值，但
在ObjectInvoke内部会对传入参数类型做检查，抛出类型异常。有人提出过修改ObjectInvoke的实现，去除传入参数的类型检查，但我觉
得此举不甚严谨，因为类型检查在保证程序的鲁棒性是非常必要的，由于ObjectInvoke参数类型为Variant，其本身就不能携带完整实参类型信
息（比之更进一步的方法是在驱动接口方法中的实现），另外还有一些类型的完整检查只能依赖于声明信息，例如结构体、枚举、集合、没有RTTI的对象，这些
内容在Java、.Net中都比较容易获得，但在Delphi中却很难。最后，看一下VCL中使用ObjectInvoke的地方，主要是针对
WebSnap，也即是说ObjectInvoke出现的并不算晚，但是针对Web调用，不支持传递指针也是可以接受的。</span>
		</font>
<img src ="http://www.cnitblog.com/textbox/aggbug/68221.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/textbox/" target="_blank">零度</a> 2010-08-18 17:13 <a href="http://www.cnitblog.com/textbox/archive/2010/08/18/68221.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>