﻿<?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>BlogJava-konhon-随笔分类-Delphi</title><link>http://www.blogjava.net/konhon/category/3015.html</link><description>忘掉過去，展望未來。找回自我，超越自我。
&lt;br&gt;
&lt;b&gt;逃避不一定躲的过, 面对不一定最难过, 孤单不一定不快乐, 得到不一定能长久, 失去不一定不再拥有, 可能因为某个理由而伤心难过, 但我却能找个理由让自己快乐.&lt;/b&gt;&lt;br&gt;&lt;p&gt;
&lt;!-- Search Google --&gt;
&lt;left&gt;
&lt;form method="get" action="http://www.google.com/custom" target="google_window"&gt;
&lt;table&gt;
&lt;tr&gt;&lt;td nowrap="nowrap" valign="top" align="left" height="32"&gt;
&lt;a href="http://www.google.com/"&gt;
&lt;img src="http://www.google.com/logos/Logo_25wht.gif" border="0" alt="Google" align="middle"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;input type="text" name="q" size="31" maxlength="255" value=""&gt;&lt;/input&gt;
&lt;input type="submit" name="sa" value="搜索"&gt;&lt;/input&gt;
&lt;input type="hidden" name="client" value="pub-5408663347953425"&gt;&lt;/input&gt;
&lt;input type="hidden" name="forid" value="1"&gt;&lt;/input&gt;
&lt;input type="hidden" name="ie" value="UTF-8"&gt;&lt;/input&gt;
&lt;input type="hidden" name="oe" value="UTF-8"&gt;&lt;/input&gt;
&lt;input type="hidden" name="cof" value="GALT:#008000;GL:1;DIV:#336699;VLC:663399;AH:center;BGC:FFFFFF;LBGC:336699;ALC:0000FF;LC:0000FF;T:000000;GFNT:0000FF;GIMP:0000FF;FORID:1;"&gt;&lt;/input&gt;
&lt;input type="hidden" name="hl" value="zh-CN"&gt;&lt;/input&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/form&gt;
&lt;/left&gt;
&lt;!-- Search Google --&gt;
</description><language>zh-cn</language><lastBuildDate>Thu, 29 Mar 2007 12:21:27 GMT</lastBuildDate><pubDate>Thu, 29 Mar 2007 12:21:27 GMT</pubDate><ttl>60</ttl><item><title>TClientDataSet</title><link>http://www.blogjava.net/konhon/archive/2007/03/29/107306.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Thu, 29 Mar 2007 10:57:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2007/03/29/107306.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/107306.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2007/03/29/107306.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/107306.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/107306.html</trackback:ping><description><![CDATA[<strong>
				<a href="http://www.openitpower.com/wenzhang/97/10846_1.html">http://www.openitpower.com/wenzhang/97/10846_1.html</a>
				<br />
				<br />
		</strong>　　与TTable、TQuery一样，TClientDataSet也是从TDataSet继承下来的，它通常用于多层体系结构的客户端。TClientDataSet最大的特点是它不依赖于BDE(Borland Database Engine)，但它需要一个动态链接库的支持，这个动态链接库叫DBCLIENT.DLL。在客户端，也不需要用TDatabase构件，因为客户端并不直接连接数据库。<br />　　由于TClientDataSet是从TDataSet继承下来的，所以，它支持诸如编辑、搜索、浏览、纠错、过滤等功能。由于TClientDataSet在内存中建立了数据的本地副本，上述操作的执行速度很快。也正是由于TClientDataSet并不直接连接数据库，因此，客户程序必须提供获取数据的机制。在Delphi 4中，TClientDataSet有三种途径获取数据：<br />.从文件中存取数据。<br />.从本地的另一个数据集中获取数据。<br />.通过IProvider接口从远程数据库服务器获取数据。<br />　　在一个客户程序中，可以同时运用上述三种机制获取数据。 <br /><b>11.1 浏览和编辑数据</b><br />　　和其他数据集构件一样，可以用标准的数据控件显示由TClientDataSet引入的数据集，当然，这需要借助于TDataSource构件。<br />　　由于TClientDataSet是从TDataSet继承下来的，所以，凡是其他数据集构件支持的功能，TClientDataSet构件也大致具备。不同的是，TClientDataSet能够在内存中建立数据的副本，因此，TClientDataSet比其他数据集构件增加了一些特殊的功能。<br />11.1.1 浏览数据<br />　　可以用标准的数据控件显示由TClientDataSet引入的数据集。在运行期，可以调用诸如First、GotoKey、Last、Next和Prior等函数来浏览数据。<br />　　TClientDataSet也支持书签功能，可以用书签来标记某条记录，以后就可以方便地找到这条记录。<br />　　对于TTable、TQuery等数据集构件来说，只能读RecNo属性来判断当前记录的序号。对于TClientDataSet构件来说，还可以写RecNo属性，使某一序号的记录成为当前记录。<br /><b>11.1.2 CanModify属性</b><br />　　TDataSet的CanModify属性用于判断数据集中的数据是否可以修改。CanModify属性本身是只读的，也就是说，数据是否能够修改不取决于应用程序。<br />　　不过，TClientDataSet构件有其特殊性，因为TClientDataSet已经把数据在内存中建立了副本，因此，应用程序可以决定是否允许修改数据。如果不允许用户修改数据，只要把ReadOnly属性设为True，此时，CanModify属性肯定返回False。<br />　　与其他数据集构件不同，修改TClientDataSet构件的ReadOnly属性时，不需要事先把Active属性设为True。<br /><b>11.1.3 取消修改</b><br />　　TClientDataSet传输数据的基本单位称为数据包，当前的数据包可以由Data属性来访问。不过，用户对数据的修改并不直接反映到Data属性中，而是临时写到一个日志即Delta属性中，这样做的好处是以后随时可以取消修改。<br />　　不过，这里要说明一点，尽管用户的修改并没有反映到Data，当用户在数据控件中看到的却是最新修改的数据。如果一条记录被反复修改了多次，用户看到的只是最新的数据，但日志中却记载了多次。<br />　　要取消上一次的修改，调用UndoLastChange函数。UndoLastChange需要传递一个布尔类型的参数叫FollowChange，如果FollowChange参数设为True，光标就移到被恢复的记录上，如果FollowChange参数设为False，光标仍然在当前记录上。<br />　　ChangeCount属性返回日志中记载的修改次数。如果一条记录被反复修改了多次，每调用一次UndoLastChange能够逐级取消上一次的修改。<br />　　UndoLastChange只能取消上一次的修改，如果想一下子取消所有的修改，首先要选择一个记录，然后调用RevertRecord。RevertRecord将从日志中取消所有对当前记录的修改。<br />　　TClientDataSet还有一个SavePoint属性，它能把当前的编辑状态保存起来，以后随时可以返回当时的状态。例如，可以这样保存当前的状态：<br />　　BeforeChanges := ClientDataSet1.SavePoint;<br />　　以后，可以这样来恢复当时的状态：<br />　　ClientDataSet1.SavePoint := BeforeChanges;<br />　　应用程序可以保存多处状态，可以恢复其中一个状态，不过，一旦某个状态被恢复，在其之后的状态就无效。<br />　　如果要一下子取消日志中记载的所有修改，可以调用CancelUpdates函数。CancelUpdates将把日志清空，取消所有的修改。<br />　　如果LogChanges属性设为False，用户对数据的修改就会直接反映到Data属性中。 <br /><b>11.1.4 合并修改</b><br />　　要把日志中记载的修改合并到Data属性中，有两种方式，具体使用哪一种方式，取决于应用程序获取数据的机制。不过，不管是哪种机制，合并后，日志自动被清空。<br />　　对于一个从文件中获取数据的程序来说，只要调用MergeChangeLog函数，就把日志中记载的修改合并到Data属性中。不用担心其他用户同时修改了数据。<br />　　对于一个从应用服务器获取数据的程序来说，就不能调用MergeChangeLog来合并数据，而要调用ApplyUpdates函数，ApplyUpdates会把日志中记载的修改传递给应用服务器，待应用服务器成功地把数据更新了数据库服务器后，才会合并到Data属性中。<br /><b>11.1.5 纠错</b><br />　　TClientDataSet支持纠错功能。一般情况下，需要自己建立纠错规则，以便对用户输入的数据进行纠错。<br />　　此外，如果获得了IProvider接口的话，还可以从远程服务器引入纠错规则。<br />　　有时候，客户端可能需要暂时禁止纠错，因为客户端从应用服务器检索数据是分阶段进行的，在所有的数据检索完毕之前，有些纠错规则很可能会报错。 <br />要暂时禁止纠错，可以调用DisableConstraints，要重新允许纠错，可以调用EnableConstraints函数。DisableConstraints和EnableConstraints实际上都是作用于一个内部的计数。<br /><b>11.2 索 引</b><br />　　使用索引有这么几个好处：<br />.在数据集中定位记录比较快。<br />.能够在两个数据集之间建立Lookup或Master/Detail关系。<br />.可以对记录排序。<br />　　在多层体系结构中，当客户程序从应用服务器检索数据时，它同时获得了默认的索引。默认的索引叫DEFAULT_ORDER，可以使用这个索引排序，但不能修改或删除这个索引。<br />　　除了默认的索引外，TClientDataSet还对日志中记载的记录自动建立了一个副索引叫CHANGEINDEX。与DEFAULT_ORDER一样，不能修改或删除这个副索引。<br />　　另外，还可以使用数据集中已建立的其他索引，或者自己建立索引。<br /><b>11.2.1 创建一个新的索引</b><br />　　要创建一个新的索引，可以调用AddIndex。AddIndex需要传递若干个参数：<br />　　一是Name参数，用于指定索引名。在运行期切换索引时需要用到索引的名称。<br />　　二是Fields参数，它是一个字符串，用于指定索引中的字段名，彼此之间用分号隔开。<br />　　三是Options参数，用于设置索引的选项，包含ixDescending元素表示按降序排列，包含ixCaseInsensitive元素表示大小写不敏感。<br />　　四是DescFields参数，它也是一个字符串，用于指定若干个字段名，这些字段将按照降序排列。<br />　　五是CaseInsFields参数，它的作用与DescFields参数类似，包含在CaseInsFields参数中的字段将对大小写不敏感。<br />　　六是GroupingLevel参数，用于指定分组级别，其值不能超过索引中的字段数。<br />　 下面的代码创建了一个索引：<br />If Edit1.Text &lt;&gt; '' and ClientDataSet1.Fields.FindField(Edit1.Text) then<br />Begin<br />ClientDataSet1.AddIndex(Edit1.Text+'Index',Edit1.Text, 　<br />　 [ixCaseInsensitive],'','',0);<br />ClientDataSet1.IndexName := Edit1.Text + 'Index';<br />End;<br />为了避免创建一个索引，可以临时用IndexFieldNames属性来指定若干个字段，让数据集按这些字段排序。<br /><b>11.2.2 删除和切换索引</b><br />　　要删除一个先前创建的索引，可以调用DeleteIndex并指定要删除的索引名称。注意：DEFAULT_ORDER和CHANGEINDEX不能删除。<br />　　如果建立了多个索引，可以任意选择其中的一个索引，这就要用到IndexName属性。<br /><b>11.2.3 用索引把数据分组</b><br />　　选择了一个索引后，数据集将自动按其中的字段进行排序。这样，临近的记录往往在关键字段上含有相同的值。例如，假设有一个表是这样的：<br />SalesRep　Customer　OrderNo　Amount<br />1　　　　　　1 　　　　5 　　　100<br />1　　　　　　1　　　　 2　　　 50<br />1　　　　　　2　　　　 3 　　　200<br />1 　　　 　　2　　　 　6　　 　75<br />2　　　　　　1　　　 　1　　 　10<br />2　　　　　　3　　　 　4　　 　200<br />　　可以看出，SalesRep字段的值有重复的。对于SalesRep字段的值为1的来说，Customer字段的值也有重复的。这就是说，可以按SalesRep字段分组，进而再按Customer字段分组。显然，这里的分组级别是不同的，按SalesRep字段建立的分组属于第一级，按Customer字段建立的分组属于第二级。实际上，分组级别取决于字段在索引中的顺序。<br />　　TClientDataSet可以决定是否按照分组级别来显示记录的值。例如，也许想以下面这种形式显示数据：<br />SalesRep　Customer　OrderNo　Amount<br />1　　　　　　1　　　　5　　　　100<br />　　　　　　　　　　　2　　　　50<br />　　　　　　 2　　　　3　　　　200<br />　　　　　　　　　　　6　　　　75<br />2　　　　　　1　　　　1　　　　10<br />2　　　　　　3　　　　4　　　　200<br />　　要判断当前记录某一级的什么位置，可以调用GetGroupState函数。GetGroupState函数需要传递一个参数，用于指定分组级别。<br /><b>11.3 计 算 字 段</b><br />　　与其他数据集一样，也可以在TClientDataSet建立的数据集中增加计算字段。计算字段的值是基于同一个记录中的其他字段计算出来的。<br />　　在其他数据集中，只要用户修改了数据或当前记录发生改变，就会触发OnCalcFields事件，换句话说，计算字段的值就被计算一次。<br />　　TClientDataSet引入了“内部计算字段”的概念。与一般的计算字段不同的是，内部计算字段的值将随其他字段的值一起存取，这样，只有当用户修改了数据才会触发OnCalcFields事件，如果仅仅改变了当前记录，不会触发OnCalcFields事件。也就是说，内部计算字段的值需要重新计算的机会大大减少。<br />　　在处理OnCalcFields事件的句柄中，首先要判断State属性。如果State属性返回dsInternalCalc，此时需要计算内部计算字段的值。如果State属性返回dsCalcFields，此时需要计算一般的计算字段的值。<br /><b>11.4 统 计 值</b><br />　　TClientDataSet增加了统计的功能，它可以基于分组自动计算总和、平均、计数、最大、最小值。当用户编辑数据时，这些统计值会自动跟着变化。<br /><b>11.4.1 指定统计方式</b><br />　　要指定怎样进行统计，就要用到Aggregates属性。这个属性是一个TAggregates对象，它用于管理一组TAggregate对象。<br />　　在设计期，可以单击Aggregates属性边上的省略号按钮打开如图11.1所示<br />的编辑器。<br />　　图11.1 管理一组TAggregate对象<br />　　单击按钮可以增加一个TAggregate对象，单击按钮可以删减一个TAggregate对象，单击按钮可以把TAggregate对象前移，单击按钮可以把TAggregate对象后移。<br />　　可以用字段编辑器专门创建一个用于表达统计值的字段，该字段的类型必须是“Aggregate”。Delphi 4会自动创建一个TAggregate对象，并加到Aggregates属性中。选择一个TAggregate对象，Object Inpector将显示该对象的属性。<br />　　其中，Expression属性用于指定统计表达式，例如：<br />Sum(Field1)<br />　　也可以是比较复杂的表达式：<br />Sum(Qty * Price) - Sum(AmountPaid)<br />　　在表达式中，可以使用下列统计运算符：<br />.Sum计算一组数据的总和。<br />.Avg计算一组数据的平均值。<br />.Count计算一组数据中的非空值的个数。<br />.Min计算一组数据的最小值。<br />.Max计算一组数据的最大值。<br />　　除了上述几个统计运算符外，还可以使用过滤条件中所能使用的运算符，但不能嵌套。在一个表达式中，可以混合出现几个统计值或常量，但不能混合出现统计值和字段。<br />　　Sum(Qty * Price){合法}<br />　　Max(Field1) - Max(Field2){合法}<br />　　Avg(DiscountRate) * 100{合法}<br />　　Min(Sum(Field1)){非法，不能嵌套}<br />　　Count(Field1) - Field2{非法，统计值和字段不能混合出现在一个表达式中}<br /><b>11.4.2 指定分组</b><br />　　默认情况下，统计值是基于数据集中所有的记录计算出来的。不过，也可以针对一部分记录计算统计值，这就需要事先建立分组。<br />　　前面在介绍索引时已经提到分组的概念。可以通过IndexName属性和GroupingLevel属性来选择使用哪个索引以及最大的分组级别。<br />　　例如，假设有一个表是这样的：<br />SalesRep　Customer　OrderNo　Amount<br />1　　　　　　1 　　　　5 　　　100<br />1　　　　　　1　　　　 2　　　 50<br />1　　　　　　2　　　　 3 　　　200<br />1 　　　 　　2　　　 　6　　 　75<br />2　　　　　　1　　　 　1　　 　10<br />2　　　　　　3　　　 　4　　 　200<br />　　如果要按SalesRep字段分组，并且指定其中的第一级，程序代码应当这样写：<br />Agg.Expression := 'Sum(Amount)';<br />Agg.IndexName := 'SalesCust';<br />Agg.GroupingLevel := 1;<br />Agg.AggregateName := 'Total for Rep';<br /><b>11.4.3 怎样获取统计值</b><br />　　要获取统计值，可以调用TAggregate对象的Value函数。如果统计值是基于数据集中所有的记录计算出来的，随时可以调用Value函数。如果统计值是基于分组计算出来的，必须保证当前记录正好位于该分组内。因此，在调用Value之前，最好先调用GetGroupState函数看看当前记录是否位于该分组内。<br />　　要在数据控件中显示统计值，必须事先在字段编辑器中创建一个永久字段对象，该字段的类型必须是Aggregate。<br /><b>11.5 数 据 包</b><br />　　通过Data属性可以访问客户程序从应用服务器检索到的数据。程序示例如下：<br />Procedure TForm1.Button1Click(Sender: TObject);<br />Begin<br />ClientDataSet1.Data := ClientDataSet1.Provider.DataRequest(FilterEdit.Text);<br />End;<br /><b>11.5.1 直接对Data属性赋值</b><br />　　前面讲过，客户程序既可以通过IProvider接口获取数据，也可以从另一个数据集获取数据，后者就是通过Data属性赋值的。程序示例如下：<br />　　ClientDataSet1.Data := ClientDataSet2.Data;<br />　　一旦Data被赋值，就可以用标准的数据控件显示这些数据。<br />　　注意：当从另一个数据集获取数据时，另一个数据集的日志也将被复制过来，但不包括原来的范围和过滤条件。<br />　　如果要从另一个基于BDE的数据集中获取数据，可以通过数据集构件的Provider属性，程序示例如下：<br />　　ClientDataSet1.Data := Table1.Provider.Data;<br />　　如果要从一个自定义的数据集获取数据，首先要创建一个临时的TProvider构件，然后设置其DataSet属性指定这个自定义的数据集。程序示例如下：<br />TempProvider := TDataSetProvider.Create(Form1);<br />TempProvider.DataSet := SourceDataSet;<br />ClientDataSet1.Data := TempProvider.Data;<br />TempProvider.Free;<br /><b>11.5.2 在数据包中加入自定义的信息</b><br />　　可以把自定义的信息加到数据包中。当把数据保存到文件或流中时，这些自定义的信息也将保存到文件或流中。如果把数据包直接赋值给另一个数据集的话，这些自定义的信息也将被复制。<br />　　要把自定义的信息加到数据包中，可以调用SetOptionalParam函数。要从数据包中检索自定义的信息，可以调用GetOptionalParam。程序示例如下：<br />Procedure TAppServer.Provider1UpdateData(Sender: TObject; DataSet: TClientDataSet); <br />var<br />WhenProvided: TDateTime;<br />Begin<br />WhenProvided := DataSet.GetOptionalParam('TimeProvided');<br />...<br />End;<br /><b>11.5.3 克隆另一个数据集</b><br />　　调用TClientDataSet的CloneCursor函数可以获得一个数据集的完全相同的副本。它与直接通过Data属性赋值是有区别的。<br />　　区别之一：数据在两个数据集之间是共享的，修改其中一个将同时修改另一个。<br />　　区别之二：除了数据外，CloneCursor函数还复制了一些属性和事件，这取决于Reset和KeepSettings参数怎样设置。<br />　　　CloneCursor函数需要传递三个参数，其中，Source参数指定源数据集，Reset参数和KeepSettings参数用于设置除了数据外是否还要复制下列属性和事件：Filter、Filtered、FilterOptions、OnFilterRecord、IndexName、MasterSource、MasterFields、ReadOnly、RemoteServer、ProviderName、Provider。<br />　　如果Reset和KeepSettings参数都设为False，源数据集的上述属性和事件都将被复制给目标数据集。如果Reset参数设为True，目标数据集的上述属性和事件都将被清空。如果Reset参数设为False，而KeepSettings参数设为True，目标数据集的上述属性和事件不变，不过，必须保证这些属性和事件与克隆后的数据相容。<br /><b>11.6 与应用服务器通讯</b><br />　　在多层体系结构中，客户程序通过IProvider接口与应用服务器交换数据。这一章介绍怎样在客户端获得IProvider接口、怎样向应用服务器传递参数、怎样向应用服务器请求数据、怎样把用户对数据的修改写到数据库中。<br /><b>11.6.1 怎样在客户端获得IProvider接口</b><br />　　在单层应用程序以及工作在“公文包”模式下的多层应用程序中，不需要用到IProvider接口。而在多层体系结构中，客户程序要与应用服务器交换数据，首先必须获得IProvider接口，这就要用到RemoteServer属性和ProviderName属性。<br />　　RemoteServer属性用于指定客户端的MIDAS连接构件。MIDAS连接构件又称Data Broker，用于建立和维护与应用服务器的连接。<br />　　在设计期，正确设置了RemoteServer属性后，就可以在对象观察器中为ProviderName属性选择一个值，实际上就是选择应用服务器上的一个TProvider构件。<br /><b>11.6.2 向应用服务器传递参数</b><br />　　客户程序可以向应用服务器传递参数，这些参数实际上是传递给应用服务器上的TQuery构件或TStoredProc构件。既可以在设计期也可以在运行期设置参数。<br />　　在设计期，可以单击Params属性边上的省略号按钮，打开一个如图11.2所示的编辑器。<br />　　图11.2 设置参数<br />　　单击按钮可以增加一个参数，单击按钮可以删减一个参数，单击按钮可以把一个参数前移，单击按钮可以把一个参数后移。<br />　　选择一个参数，对象观察器将显示该参数(TParam对象)的属性。<br />　　在运行期可以调用TParams的CreateParam函数来创建一个参数。例如，下面的代码创建了一个参数叫CustNo，它的使用类型是ptInput，数据类型是ftInteger，它的值设为605。<br />With ClientDataSet1.Params.CreateParam(ftInteger, 'CustNo', ptInput) Do<br />AsInteger := 605;<br />　　设置好参数以后，如果TClientDataset的Active属性是False，只要把Active属性设为True，这些参数将被自动传递给应用服务器。如果Active属性已经为True，就要调用SendParams函数把参数传递给应用服务器。<br />　　注意：传递给应用服务器的参数必须与TQuery构件或TStoredProc构件的参数匹配，包括名称、数据类型和参数类型。<br /><b>11.6.3 怎样向应用服务器请求数据</b><br />　　TClientDataSet提供了两个属性和三个方法，用于怎样向应用服务器请求数据：<br />　　一是FetchOnDemand属性。如果这个属性设为True，TClientDataSet会根据需要自动检索附加的数据包，例如BLOB字段的值或者嵌套表的内容。如果这个属性设为False，程序需要显式地调用GetNextPacket才能获得这些附加的数据包。<br />　　二是PacketRecords属性，用于设置一个数据包中最多可容纳的记录数，设为-1表示一个数据包可以容纳数据集的所有记录。<br />　　三是GetNextPacket函数，用于向应用服务器检索下一个数据包，并把检索到的数据包添加到前一次检索到的数据包的后面。这个函数返回实际检索到的记录数。<br />　　四是FetchBlobs过程，用于从应用服务器检索BLOB字段的值。如果FetchOnDemand属性设为True，就没必要调用FetchBlobs函数。<br />　　五是FetchDetails过程，用于检索嵌套表中的数据。如果FetchOnDemand属性设为True，就没必要调用FetchDetails函数。<br /><b>11.6.4 更新数据库</b><br />　　在多层体系结构中，用户在客户端修改了数据后，需要把最新的数据写到数据库中，这就要调用TClientDataSet的ApplyUpdates函数。<br />　　ApplyUpdates只需要传递一个参数叫MaxErrors，用于指定一个整数，当遇到无法更新的记录超过这个数时，此次更新就中止。如果MaxErrors参数设为0，表示只要遇到一个错误更新就中止，客户端的日志保持不变。如果MaxErrors参数设为-1，当应用服务器发现有错误的记录，就尝试更新下一个记录，等所有的记录都尝试过以后才返回。<br />　　ApplyUpdates会自动调用Reconcile函数，进而调用应用服务器上的TProvider构件的ApplyUpdates函数去更新远程的数据库服务器。没有被DBMS服务器认可的记录通过Reconcile返回给客户端，此时将在客户端触发OnReconcileError事件让您更正错误。最后，ApplyUpdates函数返回仍然没有被认可的记录数。<br /><b>11.7 在文件中存取数据</b><br />　　要从文件中读取数据，可以调用LoadFromFile函数。LoadFromFile函数需要传递一个参数，用于指定文件名。文件名应包含完整的路径。如果客户程序总是从一个固定的文件中读取数据，可以设置FileName属性指定一个文件名，以后，当TClientDataSet引入的数据集打开时，就自动从这个文件中读取数据，不需要调用LoadFromFile。<br />　　要从流中读取数据，可以调用LoadFromStream。LoadFromStream需要传递一个参数，用于指定一个流对象。<br />　　注意：LoadFromFile(LoadFromStream)只能从先前用SaveToFile(SaveToStream)保存的文件中读取数据。<br />　　要把数据保存到文件中，可以调用SaveToFile函数。SaveToFile需要传递一个参数，用于指定文件名。如果指定的文件已存在，文件中的数据将被覆盖。如果客户程序总是把数据保存到一个固定的文件中，可以设置FileName属性指定一个文件名，当TClientDataSet引入的数据集关闭时，就自动把数据保存到这个文件中，不需要调用SaveToFile。<br />　　要把数据保存到流中，可以调用SaveToStream。SaveToStream需要传递一个参数，指定一个流对象。<br />　　注意：当把数据保存到文件或流中时，日志中记载的修改仍然保留。这样，当下次调用LoadFromFile或LoadFromStream读取数据时，仍然可以恢复原来的数据。 <br /><img src ="http://www.blogjava.net/konhon/aggbug/107306.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2007-03-29 18:57 <a href="http://www.blogjava.net/konhon/archive/2007/03/29/107306.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[轉]物流信息系统开发手记-Delphi的三层开发 </title><link>http://www.blogjava.net/konhon/archive/2007/03/28/107039.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Wed, 28 Mar 2007 10:07:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2007/03/28/107039.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/107039.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2007/03/28/107039.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/107039.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/107039.html</trackback:ping><description><![CDATA[<p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">  </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">近日（呵呵，这篇文章是去年写的）用了两个月开发了一个物流信息系统，这个系统是两层、三层相结合，</span><span lang="EN-US">C/S</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang="EN-US">B/S</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">相结合的系统。虽然限于时间的紧张和人手的原因，系统规模不是很大，但是其中涉及的技术却很全面。在这个《<b>开发技术篇</b>》中我们将讲解我在开发系统中遇到的技术问题及解决方案，希望对大家有帮助。对于物流信息系统的分析设计问题，我将在另一篇文章《物流信息系统开发手记――系统构架篇》中讲解。</span></p><p class="MsoNormal"><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-LEFT: 42pt; TEXT-INDENT: -24pt; mso-list: l0 level1 lfo1; tab-stops: list 42.0pt"><span lang="EN-US" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一、</span><span lang="EN-US">Midas</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的安全问题。</span></p><p class="MsoNormal" style="MARGIN-LEFT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>Midas</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">技术是</span><span lang="EN-US"><a title="Delphi" href="http://www.blogjava.net/konhon/category/3015.html" target="_blank">Delphi</a></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中进行三层开发的首选技术，它不仅有纯</span><span lang="EN-US">DCOM/COM+(COM+</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">技术是</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">技术的基础</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的优点，而且也结合了</span><span lang="EN-US">Delphi</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的快速开发特性，可以快速开发出想要的系统，其开发速度是用</span><span lang="EN-US">VC,PB</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">等开发</span><span lang="EN-US">DCOM</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的数十倍，把程序员从烦杂的代码中解脱出来，从而将更多的精力投入到业务逻辑的设计中去。</span></p><p class="MsoNormal" style="MARGIN-LEFT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">但是</span><span lang="EN-US">Midas</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">技术的一个最令人担忧的就是它的安全问题：</span></p><p class="MsoNormal" style="MARGIN-LEFT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">远端只要知道应用服务器的端口号即可访问到应用服务器，而一旦访问到应用服务器，</span><span lang="EN-US">TClientDataSet</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">即可获得</span><span lang="EN-US">ProviderNames</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">列表。一旦知道了</span><span lang="EN-US">ProviderNames</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">列表，这就相当于将数据库暴露在外了。</span></p><p class="MsoNormal" style="MARGIN-LEFT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关于可轻易获得</span><span lang="EN-US">ProviderNames</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">列表的问题，我使用下面的方法解决：</span></p><p class="MsoNormal" style="MARGIN-LEFT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes"> </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在服务器端定义一个</span></p><p class="MsoNormal" style="MARGIN-LEFT: 18pt"><span lang="EN-US">LoginMTS(const AUserId, APassword: WideString): WordBool; </span></p><p class="MsoNormal" style="MARGIN-LEFT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方法。初始状态下，所有的</span><span lang="EN-US">DataSetProvider</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和数据集的连接断开。用户必须调用</span><span lang="EN-US">LoginMTS</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">并传递用户名和密码，登陆成功才将</span><span lang="EN-US">DataSetProvider</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和数据集的连接打开。这样如果用户验证没有通过，即使它获得了</span><span lang="EN-US">ProviderNames</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">列表也没法调用接口中的方法对数据库进行操作。</span></p><p class="MsoNormal" style="MARGIN-LEFT: 42pt; TEXT-INDENT: -24pt; mso-list: l0 level1 lfo1; tab-stops: list 42.0pt"><span lang="EN-US" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">二、</span><span lang="EN-US">Midas</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中主从表的实现</span></p><p class="MsoNormal" style="MARGIN-LEFT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">主从表的应用在信息系统中应用很广。在两层开发中我们可以通过直接建立两个数据集之间为主从关系来实现主从表；在三层中虽然我们仍然可以通过直接建立两个数据集之间为主从关系来实现主从表，但是这样就要求把数据库中所有相关的数据行都下载到本地，丧失了三层开发的优势。我在实际中使用下面的方法实现。这里我以实现入库单查询、添加、修改、删除</span><span lang="EN-US">(CRUD)</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为例来讲解：</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</span><span lang="EN-US">1</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）新建一个</span><span lang="EN-US">MTS Data Module</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，命名为</span><span lang="EN-US">TmtsStockInListBiz,</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">增加如下方法：</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>function QueryStockInListMasterById(const AId: WideString;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">      </span>var ADatas: OleVariant): WordBool; safecall;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>function QueryStockInListSlaveByMasterId(const AId: WideString;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">      </span>var ADatas: OleVariant): WordBool; safecall;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>procedure UpdataStockInListMaster(var ADatas: OleVariant); safecall;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>procedure UpdataStockInListSlave(var ADatas: OleVariant); safecall;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>function GenerateStockInListId: WideString; safecall;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">QueryStockInListMasterById</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">作用是根据入库单单号查询入库单的基本信息（入库日期、负责人等），</span><span lang="EN-US">Aid</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为入库单单号，</span><span lang="EN-US">Adatas</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为返回值，其格式就是</span><span lang="EN-US">Midas</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的数据包，可以将其附给</span><span lang="EN-US">ClientDatSet</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang="EN-US">Data</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">属性。</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">QueryStockInListSlaveByMasterId</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">作用是根据入库单单号查询入库单的详细信息（商品条码，数量）</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">UpdataStockInListMaster</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是对入库单主表进行删除、添加、修改操作。只要将</span><span lang="EN-US">ClientDataSet</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang="EN-US">Delta</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">属性做为传递即可。</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">UpdataStockInListSlave</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是对入库单从表进行删除、添加、修改操作。</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">GenerateStockInListId</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是产生一个唯一的入库单号。</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下面是几个方法的代码，都很简单，就不多解释了，可以查看</span><span lang="EN-US">Delphi</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的帮助。</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">function TmtsStockInListBiz.QueryStockInListMasterById(</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>const AId: WideString; var ADatas: OleVariant): WordBool;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">begin</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>result := false;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>ADatas := null;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>try</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>cdsQuery.Close;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>cdsQuery.CommandText := 'select * from t_StockInListMaster where Id=:Id';</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>cdsQuery.Params.ParamByName('Id').AsString := AId;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>cdsQuery.Open;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>if cdsQuery.RecordCount &gt; 0 then</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>begin</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">      </span>result := true;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">      </span>ADatas := cdsQuery.Data;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>end;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>finally</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>cdsQuery.Close;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>end;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">end;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">procedure TmtsStockInListBiz.UpdataStockInListMaster(</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>var ADatas: OleVariant);</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">var</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>eCount: Integer;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>OwnerData: OleVariant;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">begin</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>DCOMConStockInList.GetServer.AS_ApplyUpdates('dspStockInListMaster',</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>ADatas, -1, eCount, OwnerData);</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">end;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">function TmtsStockInListBiz.GenerateStockInListId: WideString;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">var</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>LPrior: string;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>i: Integer;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">begin</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>cdsQuery.Close;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>cdsQuery.CommandText := 'select top 1 id from t_StockInListMaster order by id desc';</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>cdsQuery.Open;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>LPrior := cdsQuery.FieldByName('Id').AsString;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>i := StrToIntDef(RightStr(LPrior,8),0);</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>Inc(i);</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>result := 'RK' + FormatFloat('00000000',i);</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>cdsQuery.Close;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">end;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</span><span lang="EN-US">2</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）、新建一个应用程序，通过</span><span lang="EN-US">DCOMConnection</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang="EN-US">SocketConnection</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">等连接到</span><span lang="EN-US">MTS</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">组件，然后就可以调用</span><span lang="EN-US">MTS</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的相应的方法实现客户端功能了。</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">放入</span><span lang="EN-US">cdsStockInListMaster</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang="EN-US">cdsStockInListSlave</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">两个</span><span lang="EN-US">ClientDataSet</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">控件，在控件上点击右键，选择“</span><span lang="EN-US">FieldsEditor</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”新建于服务器中的字段同样的字段，然后再次在控件上单击右键，选择“</span><span lang="EN-US">CreateDataSet</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”，建立一个本地数据库。</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">根据入库单号查询入库单的方法实现：</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">procedure TFormStockInList.BtnFindClick(Sender: TObject);</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">var</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>v,vs: OleVariant;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">begin</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>if SocketConStockInList.AppServer.QueryStockInListMasterById(Trim(LEdtId.Text), v) then</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>begin</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>cdsStockInListMaster.Data := v;//</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">显示入库单主表（主要信息）</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>if SocketConStockInList.AppServer.QueryStockInListSlaveByMasterId(Trim(LEdtId.Text), vs) then</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">      </span>cdsStockInListSlave.Data := vs; ;//</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">显示入库单从表（明细信息）</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>end</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>else</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>ShowMessage('</span><span style="FONT-FAMILY: 宋体; 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="TEXT-INDENT: 18pt"><span lang="EN-US">end;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</span><span lang="EN-US">4</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）新建入库单的实现</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">procedure TFormStockInList.BtnNewClick(Sender: TObject);</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">var</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>LId: string;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">begin</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>ClearCDSRecord;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>cdsStockInListMaster.Open;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>cdsStockInListMaster.Insert;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>LId := SocketConStockInList.AppServer.GenerateStockInListId;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>LEdtId.Text := LId;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>cdsStockInListMaster.FieldByName('Id').AsString := LId;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>cdsStockInListMaster.FieldByName('GenerateDate').AsDateTime := Now();</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">end;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</span><span lang="EN-US">5</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）提交功能的实现</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">procedure TFormStockInList.BtnPostClick(Sender: TObject);</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">var</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>LQuerymts: ImtsQueryObjDisp;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>LBar: string;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">begin</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>SetSocketConnectionConnect(SocketConQuery);</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>LQuerymts := ImtsQueryObjDisp(SocketConQuery.GetServer);</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>SocketConQuery.Close;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>if cdsStockInListMaster.RecordCount &gt; 0 then</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>SocketConStockInList.AppServer.UpdataStockInListMaster(cdsStockInListMaster.Delta);</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>if cdsStockInListSlave.RecordCount &gt; 0 then</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>SocketConStockInList.AppServer.UpdataStockInListSlave(cdsStockInListSlave.Delta);</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span lang="EN-US">end;</span></p><p class="MsoNormal" style="TEXT-INDENT: 18pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注：本文中</span><span lang="EN-US">ClientDataSet</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">控件的名称开头一般为</span><span lang="EN-US">cds</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang="EN-US">TsocketConnection</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">控件的名称开头一般为</span><span lang="EN-US">SocketCon</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span></p><p class="MsoNormal"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">三、动态设置</span><span lang="EN-US">TsimpleObjectBroker</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的服务器列表</span></p><p class="MsoNormal"><span lang="EN-US">procedure SetSocketConnectionConnect(AValue: TSocketConnection);</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>procedure FillAppServerList(ABroker: TSimpleObjectBroker);</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>var</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>sl: TStringList;</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes"> </span><span style="mso-spacerun: yes">   </span>i, n: Integer;</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>begin</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>sl := TStringList.Create;</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">从配置文件中读取服务器列表，并保存到</span><span lang="EN-US">sl</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中</span><span lang="EN-US">;</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>n := sl.Count - 1;</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>ABroker.ServerData := null;</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>for i := 0 to n do</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>begin</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">      </span>ABroker.Servers.Add;</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">      </span>ABroker.Servers[i].ComputerName := sl.Strings[i]</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">   </span><span style="mso-spacerun: yes"> </span>end;</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>sl.Free;</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>end;</span></p><p class="MsoNormal"><span lang="EN-US">var</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>LBroker: TSimpleObjectBroker;</span></p><p class="MsoNormal"><span lang="EN-US">begin</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">  </span>LBroker := TSimpleObjectBroker.Create(nil);</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>FillAppServerList(LBroker);</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>AValue.ObjectBroker := LBroker;</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>try</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">      </span>AValue.Connected := true;</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>except</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">      </span>raise Exception.Create('</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应用服务器连接错误！</span><span lang="EN-US">');</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>end;</span></p><p class="MsoNormal"><span lang="EN-US"><span style="mso-spacerun: yes">    </span>LBroker.Free;</span></p><p class="MsoNormal"><span lang="EN-US">end;</span></p><img src ="http://www.blogjava.net/konhon/aggbug/107039.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2007-03-28 18:07 <a href="http://www.blogjava.net/konhon/archive/2007/03/28/107039.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>动态设置DNS的例子</title><link>http://www.blogjava.net/konhon/archive/2005/12/02/22186.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Fri, 02 Dec 2005 01:21:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/12/02/22186.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/22186.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/12/02/22186.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/22186.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/22186.html</trackback:ping><description><![CDATA[<P>一个在普通用户下设置DNS的例子</P>
<P>unit uMain;</P>
<P>interface</P>
<P>uses<BR>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<BR>&nbsp; Dialogs, StdCtrls, Registry;</P>
<P>type<BR>&nbsp; _STARTUPINFOW = record<BR>&nbsp;&nbsp;&nbsp; cb: DWORD;<BR>&nbsp;&nbsp;&nbsp; lpReserved: LPWSTR;<BR>&nbsp;&nbsp;&nbsp; lpDesktop: LPWSTR;<BR>&nbsp;&nbsp;&nbsp; lpTitle: LPWSTR;<BR>&nbsp;&nbsp;&nbsp; dwX: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwY: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwXSize: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwYSize: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwXCountChars: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwYCountChars: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwFillAttribute: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwFlags: DWORD;<BR>&nbsp;&nbsp;&nbsp; wShowWindow: Word;<BR>&nbsp;&nbsp;&nbsp; cbReserved2: Word;<BR>&nbsp;&nbsp;&nbsp; lpReserved2: PByte;<BR>&nbsp;&nbsp;&nbsp; hStdInput: THandle;<BR>&nbsp;&nbsp;&nbsp; hStdOutput: THandle;<BR>&nbsp;&nbsp;&nbsp; hStdError: THandle;<BR>&nbsp; end;<BR>&nbsp; STARTUPINFOW = _STARTUPINFOW;</P>
<P>&nbsp; TForm1 = class(TForm)<BR>&nbsp;&nbsp;&nbsp; Button1: TButton;<BR>&nbsp;&nbsp;&nbsp; Button2: TButton;<BR>&nbsp;&nbsp;&nbsp; procedure Button1Click(Sender: TObject);<BR>&nbsp;&nbsp;&nbsp; procedure Button2Click(Sender: TObject);<BR>&nbsp;&nbsp;&nbsp; procedure FormClose(Sender: TObject; var Action: TCloseAction);<BR>&nbsp; private<BR>&nbsp;&nbsp;&nbsp; { Private declarations }<BR>&nbsp;&nbsp;&nbsp; procedure DoOperation(aCmd: string);<BR>&nbsp; public<BR>&nbsp;&nbsp;&nbsp; { Public declarations }<BR>&nbsp; end;</P>
<P>var<BR>&nbsp; Form1: TForm1;</P>
<P>function CreateProcessWithLogonW(lpUserName, lpDomain, lpPassword: LPCWSTR;<BR>&nbsp; dwLogonFlags: DWORD; lpApplicationName: LPCWSTR; lpCommandLine: LPWSTR;<BR>&nbsp; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: LPCWSTR;<BR>&nbsp; const lpStartupInfo: STARTUPINFOW; var lpProcessInformation: PROCESS_INFORMATION): BOOL; stdcall;<BR>external advapi32 Name 'CreateProcessWithLogonW'</P>
<P><BR>implementation</P>
<P>{$R *.dfm}</P>
<P><BR>procedure DelRegCache;<BR>begin<BR>&nbsp; with TRegistry.Create do<BR>&nbsp; try<BR>&nbsp;&nbsp;&nbsp; RootKey := HKEY_CURRENT_USER;<BR>&nbsp;&nbsp;&nbsp; DeleteKey('Software\Microsoft\Internet Explorer\TypedURLs');<BR>&nbsp; finally<BR>&nbsp;&nbsp;&nbsp; Free;<BR>&nbsp; end;<BR>end;</P>
<P><BR>procedure TForm1.DoOperation(aCmd: string);<BR>var<BR>&nbsp; STARTUPINFO: StartupInfoW;<BR>&nbsp; ProcessInfo: TProcessInformation;<BR>&nbsp; AUser, ADomain, APass, AExe: WideString;<BR>const<BR>&nbsp; LOGON_WITH_PROFILE = $00000001;<BR>&nbsp; LOGON_NETCREDENTIALS_ONLY = $00000002;<BR>begin<BR>&nbsp; Screen.Cursor := crHourGlass;<BR>&nbsp; try<BR>&nbsp;&nbsp;&nbsp; FillChar(STARTUPINFO, SizeOf(StartupInfoW), #0);<BR>&nbsp;&nbsp;&nbsp; STARTUPINFO.cb := SizeOf(StartupInfoW);<BR>&nbsp;&nbsp;&nbsp; STARTUPINFO.dwFlags := STARTF_USESHOWWINDOW;<BR>&nbsp;&nbsp;&nbsp; STARTUPINFO.wShowWindow := SW_SHOW;<BR>&nbsp;&nbsp;&nbsp; AUser := 'administrator';<BR>&nbsp;&nbsp;&nbsp; APass := '123';<BR>&nbsp;&nbsp;&nbsp; ADomain := 'domain';<BR>&nbsp;&nbsp;&nbsp; AExe := aCmd;<BR>&nbsp;&nbsp;&nbsp; if not CreateProcessWithLogonW(PWideChar(AUser), PWideChar(ADomain),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PWideChar(APass),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LOGON_WITH_PROFILE, nil, PWideChar(AExe),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NORMAL_PRIORITY_CLASS, nil, nil, STARTUPINFO, ProcessInfo) then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RaiseLastOSError;<BR>&nbsp;&nbsp;&nbsp; WaitForSingleObject(ProcessInfo.hProcess, INFINITE);<BR>&nbsp; finally<BR>&nbsp;&nbsp;&nbsp; Screen.Cursor := crDefault;<BR>&nbsp; end;<BR>end;</P>
<P>procedure TForm1.Button1Click(Sender: TObject);<BR>begin<BR>&nbsp; DoOperation('netsh interface ip add dns "區域連線" 192.168.10.81 1');<BR>&nbsp; DoOperation('netsh interface ip add dns "區域連線" 202.96.128.166 2');<BR>&nbsp; Application.MessageBox('操作完成!', 'CrackNet', MB_OK + 64);<BR>end;</P>
<P>procedure TForm1.Button2Click(Sender: TObject);<BR>begin<BR>&nbsp; DelRegCache;<BR>&nbsp; DoOperation('netsh interface ip set dns "區域連線" dhcp');<BR>end;</P>
<P>procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);<BR>begin<BR>&nbsp; Hide;<BR>&nbsp; Button2.Click;<BR>end;</P>
<P>end.<BR></P><img src ="http://www.blogjava.net/konhon/aggbug/22186.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-12-02 09:21 <a href="http://www.blogjava.net/konhon/archive/2005/12/02/22186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Delphi 中如何用另外一个用户的身份来运行一人程序 </title><link>http://www.blogjava.net/konhon/archive/2005/11/15/19793.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Tue, 15 Nov 2005 00:15:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/11/15/19793.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/19793.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/11/15/19793.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/19793.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/19793.html</trackback:ping><description><![CDATA[<P>如一个程序要有以下的命令来运行<BR>runas /env /savecred /user:hhql "c:\qlnetbar\bc2\bc2"<BR>我现在的问题是如何在Delphi中用代码来代替 runas /env /savecred /user:hhql 的功能，因为我要监视 c:\qlnetbar\bc2\bc2 的运行情况，所以 c:\qlnetbar\bc2\bc2 必须要由我用Delphi写的程序来运行</P>
<P>请高手指教。。。。<BR><BR><BR>果你用XP或2000，可以用下面的API：CreateProcessWithLogonW<BR>type<BR>&nbsp; _STARTUPINFOW = record<BR>&nbsp;&nbsp;&nbsp; cb: DWORD;<BR>&nbsp;&nbsp;&nbsp; lpReserved: LPWSTR;<BR>&nbsp;&nbsp;&nbsp; lpDesktop: LPWSTR;<BR>&nbsp;&nbsp;&nbsp; lpTitle: LPWSTR;<BR>&nbsp;&nbsp;&nbsp; dwX: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwY: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwXSize: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwYSize: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwXCountChars: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwYCountChars: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwFillAttribute: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwFlags: DWORD;<BR>&nbsp;&nbsp;&nbsp; wShowWindow: Word;<BR>&nbsp;&nbsp;&nbsp; cbReserved2: Word;<BR>&nbsp;&nbsp;&nbsp; lpReserved2: PByte;<BR>&nbsp;&nbsp;&nbsp; hStdInput: THandle;<BR>&nbsp;&nbsp;&nbsp; hStdOutput: THandle;<BR>&nbsp;&nbsp;&nbsp; hStdError: THandle;<BR>&nbsp; end;<BR>&nbsp; STARTUPINFOW = _STARTUPINFOW;</P>
<P>function CreateProcessWithLogonW(lpUserName, lpDomain, lpPassword: LPCWSTR;<BR>&nbsp; dwLogonFlags: DWORD; lpApplicationName: LPCWSTR; lpCommandLine: LPWSTR;<BR>&nbsp; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: LPCWSTR;<BR>&nbsp; const lpStartupInfo: STARTUPINFOW; var lpProcessInformation: PROCESS_INFORMATION): BOOL; stdcall;<BR>&nbsp; external advapi32 Name 'CreateProcessWithLogonW'</P>
<P>procedure TForm1.Button2Click(Sender: TObject);<BR>var<BR>&nbsp; STARTUPINFO: StartupInfoW;<BR>&nbsp; ProcessInfo: TProcessInformation;<BR>&nbsp; AUser, ADomain, APass, AExe: WideString;<BR>const<BR>&nbsp; LOGON_WITH_PROFILE = $00000001;<BR>&nbsp; LOGON_NETCREDENTIALS_ONLY = $00000002;<BR>begin<BR>&nbsp; FillChar(STARTUPINFO, SizeOf(StartupInfoW), #0);<BR>&nbsp; STARTUPINFO.cb := SizeOf(StartupInfoW);<BR>&nbsp; STARTUPINFO.dwFlags := STARTF_USESHOWWINDOW;<BR>&nbsp; STARTUPINFO.wShowWindow := SW_SHOW;<BR>&nbsp; AUser := edtUser.Text;<BR>&nbsp; ADomain := edtDomain.Text;<BR>&nbsp; APass := edtPass.Text;<BR>&nbsp; AExe := edtExe.Text;<BR>&nbsp; if not CreateProcessWithLogonW(PWideChar(AUser), PWideChar(ADomain),<BR>&nbsp;&nbsp;&nbsp; PWideChar(APass),<BR>&nbsp;&nbsp;&nbsp; LOGON_WITH_PROFILE, nil, PWideChar(AExe),<BR>&nbsp;&nbsp;&nbsp; NORMAL_PRIORITY_CLASS, nil, nil, STARTUPINFO, ProcessInfo) then<BR>&nbsp;&nbsp;&nbsp; RaiseLastOSError;<BR>end;</P>
<P>已经测试通过<BR><BR>代码修改了一下：</P>
<P>unit Unit1;</P>
<P>interface</P>
<P>uses<BR>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<BR>&nbsp; Dialogs, StdCtrls;</P>
<P>type<BR>&nbsp; TForm1 = class(TForm)<BR>&nbsp;&nbsp;&nbsp; Button1: TButton;<BR>&nbsp;&nbsp;&nbsp; procedure Button1Click(Sender: TObject);<BR>&nbsp; private<BR>&nbsp;&nbsp;&nbsp; { Private declarations }<BR>&nbsp; public<BR>&nbsp;&nbsp;&nbsp; { Public declarations }<BR>&nbsp; end;</P>
<P>type<BR>&nbsp; _STARTUPINFOW = record<BR>&nbsp;&nbsp;&nbsp; cb: DWORD;<BR>&nbsp;&nbsp;&nbsp; lpReserved: LPWSTR;<BR>&nbsp;&nbsp;&nbsp; lpDesktop: LPWSTR;<BR>&nbsp;&nbsp;&nbsp; lpTitle: LPWSTR;<BR>&nbsp;&nbsp;&nbsp; dwX: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwY: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwXSize: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwYSize: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwXCountChars: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwYCountChars: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwFillAttribute: DWORD;<BR>&nbsp;&nbsp;&nbsp; dwFlags: DWORD;<BR>&nbsp;&nbsp;&nbsp; wShowWindow: Word;<BR>&nbsp;&nbsp;&nbsp; cbReserved2: Word;<BR>&nbsp;&nbsp;&nbsp; lpReserved2: PByte;<BR>&nbsp;&nbsp;&nbsp; hStdInput: THandle;<BR>&nbsp;&nbsp;&nbsp; hStdOutput: THandle;<BR>&nbsp;&nbsp;&nbsp; hStdError: THandle;<BR>&nbsp; end;<BR>&nbsp; STARTUPINFOW = _STARTUPINFOW;</P>
<P>function CreateProcessWithLogonW(lpUserName, lpDomain, lpPassword: LPCWSTR;<BR>&nbsp; dwLogonFlags: DWORD; lpApplicationName: LPCWSTR; lpCommandLine: LPWSTR;<BR>&nbsp; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: LPCWSTR;<BR>&nbsp; const lpStartupInfo: STARTUPINFOW; var lpProcessInformation: PROCESS_INFORMATION): BOOL; stdcall;<BR>&nbsp; external advapi32 Name 'CreateProcessWithLogonW'<BR>var<BR>&nbsp; Form1: TForm1;</P>
<P>implementation</P>
<P>{$R *.dfm}</P>
<P>procedure TForm1.Button1Click(Sender: TObject);<BR>var<BR>&nbsp; STARTUPINFO: StartupInfoW;<BR>&nbsp; ProcessInfo: TProcessInformation;<BR>&nbsp; AUser, ADomain, APass, AExe: WideString;<BR>const<BR>&nbsp; LOGON_WITH_PROFILE = $00000001;<BR>&nbsp; LOGON_NETCREDENTIALS_ONLY = $00000002;<BR>begin<BR>&nbsp; FillChar(STARTUPINFO, SizeOf(StartupInfoW), #0);<BR>&nbsp; STARTUPINFO.cb := SizeOf(StartupInfoW);<BR>&nbsp; STARTUPINFO.dwFlags := STARTF_USESHOWWINDOW;<BR>&nbsp; STARTUPINFO.wShowWindow := SW_SHOW;<BR>&nbsp; AUser := 'pcmax';<BR>&nbsp; //ADomain := edtDomain.Text;<BR>&nbsp; APass := 'pcmax';<BR>&nbsp; AExe := 'c:\windows\system32\mspaint.exe';<BR>&nbsp; if not CreateProcessWithLogonW(PWideChar(AUser), PWideChar(ADomain),<BR>&nbsp;&nbsp;&nbsp; PWideChar(APass),<BR>&nbsp;&nbsp;&nbsp; LOGON_WITH_PROFILE, nil, PWideChar(AExe),<BR>&nbsp;&nbsp;&nbsp; NORMAL_PRIORITY_CLASS, nil, nil, STARTUPINFO, ProcessInfo) then<BR>&nbsp;&nbsp;&nbsp; RaiseLastOSError;<BR>&nbsp; WaitForSingleObject(ProcessInfo.hProcess, INFINITE);<BR>&nbsp; ShowMessage('over now');<BR>end;</P>
<P>end.<BR><BR>运行上面的代码，点击button1就会以用户pcmax运行 c:\windows\system32\mspaint.exe。然后等待运行结束后弹出提示对话框。</P>
<P>&nbsp;</P><img src ="http://www.blogjava.net/konhon/aggbug/19793.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-11-15 08:15 <a href="http://www.blogjava.net/konhon/archive/2005/11/15/19793.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>抓 图</title><link>http://www.blogjava.net/konhon/archive/2005/11/12/19442.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Sat, 12 Nov 2005 00:59:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/11/12/19442.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/19442.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/11/12/19442.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/19442.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/19442.html</trackback:ping><description><![CDATA[抓 图 实 际 上 是 位 图 的 复 制 ， Windows在 复 制 位 图 时 是 不 会 受 鼠 标 <BR>光 标 的 影 响 的 。 可 以 先 抓 图 ， 然 后 在 使 用 DrawIcon将 鼠 标 光 标 画 上 去 。 <BR><BR><BR>procedure TForm1.FormClick(Sender: TObject);<BR>var<BR>&nbsp; winHWND, hCur: integer;<BR>&nbsp; winDC: integer;<BR>&nbsp; rect: TRect;<BR>&nbsp; pt: TPoint;<BR>&nbsp; fBitmap: TBitmap;<BR>begin<BR>&nbsp; hCur := GetCursor(); //&nbsp;取得光标句柄<BR>&nbsp; GetCursorPos(pt); //&nbsp;取得光标位置<BR>&nbsp; winHWND := GetDesktopWindow();<BR>&nbsp; winDC := GetDC(winHWND);<BR>&nbsp; GetWindowRect(winHWND, rect);<BR>&nbsp; fBitmap := TBitmap.create;<BR>&nbsp; try<BR>&nbsp;&nbsp;&nbsp; fBitmap.width := rect.right - rect.left;<BR>&nbsp;&nbsp;&nbsp; fBitmap.height := rect.bottom - rect.top;<BR>&nbsp;&nbsp;&nbsp; BitBlt(fBitmap.canvas.handle, 0, 0, fBitmap.width, fBitmap.height, winDC, 0, 0, SRCCOPY);<BR>&nbsp;&nbsp;&nbsp; DrawIcon(fBitmap.canvas.handle, pt.x, pt.y, hCur); //&nbsp;画光标<BR>&nbsp;&nbsp;&nbsp; ReleaseDC(winHWND, winDC);<BR>&nbsp;&nbsp;&nbsp; Image1.Picture.Bitmap.Assign(fBitmap);<BR>&nbsp; finally<BR>&nbsp;&nbsp;&nbsp; fBitmap.Free;<BR>&nbsp; end;<BR>end;<img src ="http://www.blogjava.net/konhon/aggbug/19442.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-11-12 08:59 <a href="http://www.blogjava.net/konhon/archive/2005/11/12/19442.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 字符串与二进制数之间的互相转换 </title><link>http://www.blogjava.net/konhon/archive/2005/11/02/17868.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Wed, 02 Nov 2005 10:37:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/11/02/17868.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/17868.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/11/02/17868.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/17868.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/17868.html</trackback:ping><description><![CDATA[将一个字符串转为二进制，再从二进制转为原字符串。 <BR><BR>&nbsp; &nbsp;把字符串(可含中文字符)转为二进制数的函数:ConvertStrToBin();把二进制数转换为字符串的函数：ConvertBinToStr()。<BR>&nbsp; &nbsp;以下两个函数亦可以对包含有中文字符的字符串进行处理,逆转时亦可正常转为中文。<BR>Function ConvertStrToBin(Value : string):string;//把字符串转化为二进制数<BR>var tempHex : string[2];<BR>&nbsp; &nbsp; i : integer;<BR>begin<BR>&nbsp; Result := '';<BR>&nbsp; if trim(Value) = '' then Exit;<BR>&nbsp; tempHex := '';<BR>&nbsp; for i := 1 to Length(Value) do<BR>&nbsp; begin<BR>&nbsp; &nbsp; tempHex := IntToHex(Ord(Value[i]),2);//每个字符转成两位十六进制数<BR>&nbsp; &nbsp; Result := Result + BinToHexEachOther(tempHex,False);//十六进制转成二进制<BR>&nbsp; end;<BR>end;<BR><BR>Function ConvertBinToStr(Value : string):string; //把二进制数据转化为字符串<BR>Var tempHex : string;<BR>&nbsp; &nbsp; i, tempInt : integer;<BR>begin<BR>&nbsp; Result := '';<BR>&nbsp; if trim(Value) = '' then Exit;<BR>&nbsp; tempHex := BinToHexEachOther(Value,true);//二进制转成十六进制<BR>&nbsp; i := 0;<BR>&nbsp; Repeat<BR>&nbsp; &nbsp; begin<BR>&nbsp; &nbsp; &nbsp; i := i + 1;<BR>&nbsp; &nbsp; &nbsp; tempInt := HexCharToInt(tempHex[i]);<BR>&nbsp; &nbsp; &nbsp; i := i + 1;<BR>&nbsp; &nbsp; &nbsp; tempInt := tempInt * 16 + HexCharToInt(tempHex[i]);<BR>&nbsp; &nbsp; &nbsp; &nbsp;//以上将两位十六进制数转变为一个十进制数<BR>&nbsp; &nbsp; &nbsp; Result := Result + chr(TempInt); //转成ASCII码<BR>&nbsp; &nbsp; end;<BR>&nbsp; Until i &gt;= length(tempHex)<BR>end;<BR><BR>上两个互逆的函数中要调用到的函数HexCharToInt()和BinToHexEachOther()如下：<BR><BR>function BinToHexEachOther(ValueA : string; Action : Boolean) : string;<BR>&nbsp; //把二进制串转换成十六进制串或相反<BR>&nbsp; var<BR>&nbsp; &nbsp; ValueArray1 : Array [0..15] of string[4];<BR>&nbsp; &nbsp; ValueArray2 : Array [0..15] of char;<BR>&nbsp; &nbsp; i : shortint;<BR>begin<BR>&nbsp; &nbsp; //数组初始化<BR>&nbsp; &nbsp; ValueArray1[0] := '0000'; &nbsp;ValueArray1[1] := '0001'; &nbsp;ValueArray1[2] := '0010';<BR>&nbsp; &nbsp; ValueArray1[3] := '0011'; &nbsp;ValueArray1[4] := '0100'; &nbsp;ValueArray1[5] := '0101';<BR>&nbsp; &nbsp; ValueArray1[6] := '0110'; &nbsp;ValueArray1[7] := '0111'; &nbsp;ValueArray1[8] := '1000';<BR>&nbsp; &nbsp; ValueArray1[9] := '1001'; &nbsp;ValueArray1[10] := '1010'; &nbsp;ValueArray1[11] := '1011';<BR>&nbsp; &nbsp; ValueArray1[12] := '1100'; &nbsp;ValueArray1[13] := '1101'; &nbsp;ValueArray1[14] := '1110';<BR>&nbsp; &nbsp; ValueArray1[15] := '1111';<BR>&nbsp; &nbsp; for i := 0 to 15 do<BR>&nbsp; &nbsp; &nbsp; if i &gt;= 10 then ValueArray2[i] := chr(65 + (i - 10))<BR>&nbsp; &nbsp; &nbsp; else ValueArray2[i] := inttostr(i)[1];<BR><BR>&nbsp; &nbsp; Result := '';<BR>&nbsp; &nbsp; if Action then<BR>&nbsp; &nbsp; begin //二进制串转换成十六进制串<BR>&nbsp; &nbsp; &nbsp; if (Length(ValueA) MOD 4 &lt;&gt; 0) then<BR>&nbsp; &nbsp; &nbsp; &nbsp; ValueA := stringofchar('0',Length(ValueA) MOD 4) + ValueA;<BR>&nbsp; &nbsp; &nbsp; while (Length(ValueA) &gt;= 4) do<BR>&nbsp; &nbsp; &nbsp; begin<BR>&nbsp; &nbsp; &nbsp; &nbsp; for i := 0 to 15 do<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Copy(ValueA,1,4) = ValueArray1[i] then<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := Result + ValueArray2[i];<BR>&nbsp; &nbsp; &nbsp; &nbsp; ValueA := Copy(ValueA,5,Length(ValueA) - 4);<BR>&nbsp; &nbsp; &nbsp; end;<BR>&nbsp; &nbsp; end<BR>&nbsp; &nbsp; else begin //十六进制串转换成二进制串<BR>&nbsp; &nbsp; &nbsp; while (Length(ValueA) &gt;= 1) do<BR>&nbsp; &nbsp; &nbsp; begin<BR>&nbsp; &nbsp; &nbsp; &nbsp; for i := 0 to 15 do<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Copy(ValueA,1,1) = ValueArray2[i] then<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := Result + ValueArray1[i];<BR>&nbsp; &nbsp; &nbsp; &nbsp; ValueA := Copy(ValueA,2,Length(ValueA) - 1);<BR>&nbsp; &nbsp; &nbsp; end;<BR>&nbsp; &nbsp; end;<BR>end;<BR><BR>function HexCharToInt(HexToken : char):Integer;<BR>begin<BR>Result:=0;<BR>if (HexToken&gt;#47) and (HexToken&lt;#58) then &nbsp; &nbsp; &nbsp; { chars 0....9 }<BR>&nbsp; &nbsp;Result:=Ord(HexToken)-48<BR>else if (HexToken&gt;#64) and (HexToken&lt;#71) then &nbsp;{ chars A....F }<BR>&nbsp; &nbsp;Result:=Ord(HexToken)-65 + 10;<BR>end;<BR><BR><BR><SPAN style="HEIGHT: 20px">十六进制字串转十进制又一法：</SPAN> <BR>procedure TForm1.BitBtn1Click(Sender: TObject);<BR>var myint : integer;<BR>begin<BR>&nbsp; myint := StrToInt('$' + '3A'); // myint = 58<BR>&nbsp; showmessage(inttostr(myint));<BR>end; <img src ="http://www.blogjava.net/konhon/aggbug/17868.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-11-02 18:37 <a href="http://www.blogjava.net/konhon/archive/2005/11/02/17868.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>設置系統時間</title><link>http://www.blogjava.net/konhon/archive/2005/10/12/15323.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Wed, 12 Oct 2005 05:49:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/10/12/15323.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/15323.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/10/12/15323.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/15323.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/15323.html</trackback:ping><description><![CDATA[function SetSystemtime(ATime: TDateTime): Boolean;<BR>var<BR>&nbsp; ADateTime: TSystemTime;<BR>&nbsp; yy, mon, dd, hh, min, ss, ms: Word;<BR>begin<BR>&nbsp; decodedate(ATime, yy, mon, dd);<BR>&nbsp; decodetime(ATime, hh, min, ss, ms);<BR>&nbsp; with ADateTime do<BR>&nbsp; begin<BR>&nbsp;&nbsp;&nbsp; wYear := yy;<BR>&nbsp;&nbsp;&nbsp; wMonth := mon;<BR>&nbsp;&nbsp;&nbsp; wDay := dd;<BR>&nbsp;&nbsp;&nbsp; wHour := hh;<BR>&nbsp;&nbsp;&nbsp; wMinute := min;<BR>&nbsp;&nbsp;&nbsp; wSecond := ss;<BR>&nbsp;&nbsp;&nbsp; wMilliseconds := ms;<BR>&nbsp; end;<BR>&nbsp; Result := SetLocalTime(ADateTime);<BR>&nbsp; SendMessage(HWND_BROADCAST, WM_TIMECHANGE, 0, 0);<BR>end;<img src ="http://www.blogjava.net/konhon/aggbug/15323.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-10-12 13:49 <a href="http://www.blogjava.net/konhon/archive/2005/10/12/15323.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>按分隔符取字符串</title><link>http://www.blogjava.net/konhon/archive/2005/08/30/11512.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Tue, 30 Aug 2005 00:21:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/08/30/11512.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/11512.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/08/30/11512.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/11512.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/11512.html</trackback:ping><description><![CDATA[<P>function TForm1.ExtractString(const aString: string; const aSeparator: char; var aPos: Integer): string;<BR>var<BR>&nbsp; I: Integer;<BR>begin<BR>&nbsp; I := aPos;<BR>&nbsp; while (I &lt;= Length(aString)) and (aString[I] &lt;&gt; aSeparator) do Inc(I);<BR>&nbsp; Result := Trim(Copy(aString, aPos, I - aPos));<BR>&nbsp; if (I &lt;= Length(aString)) and (aString[I] = aSeparator) then Inc(I);<BR>&nbsp; aPos := I;<BR>end;</P>
<P>procedure TForm1.Button1Click(Sender: TObject);<BR>var<BR>&nbsp; lString, lSubString: string;<BR>&nbsp; lPos, j: integer;<BR>begin<BR>&nbsp; lString := '023842394201342|343242423423|342342424|533423|2455';<BR>&nbsp; lPos := 1;<BR>&nbsp; j := 0;</P>
<P>&nbsp; while lPos &lt;= Length(lString) do<BR>&nbsp; begin<BR>&nbsp;&nbsp;&nbsp; lSubString := ExtractString(lString, '|', lPos);<BR>&nbsp;&nbsp;&nbsp; inc(j);<BR>&nbsp;&nbsp;&nbsp; if j = 2 then&nbsp;&nbsp;&nbsp; // 第二個<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; showmessage(lSubString);<BR>&nbsp; end;<BR>end;</P><img src ="http://www.blogjava.net/konhon/aggbug/11512.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-08-30 08:21 <a href="http://www.blogjava.net/konhon/archive/2005/08/30/11512.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>動態設定Menu快捷键的问题 </title><link>http://www.blogjava.net/konhon/archive/2005/08/27/11280.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Sat, 27 Aug 2005 02:29:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/08/27/11280.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/11280.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/08/27/11280.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/11280.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/11280.html</trackback:ping><description><![CDATA[MenuItem1.ShortCut := ShortCut(Word(VK_RIGHT), [ssCtrl])<img src ="http://www.blogjava.net/konhon/aggbug/11280.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-08-27 10:29 <a href="http://www.blogjava.net/konhon/archive/2005/08/27/11280.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>啟用禁用要地連接</title><link>http://www.blogjava.net/konhon/archive/2005/08/26/11228.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Fri, 26 Aug 2005 09:11:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/08/26/11228.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/11228.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/08/26/11228.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/11228.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/11228.html</trackback:ping><description><![CDATA[<P><A href="http://www.blogjava.net/Files/konhon/EnableNetCard.rar">http://www.blogjava.net/Files/konhon/EnableNetCard.rar</A><A href="http://www.xfsoft.cn/Article_Show.asp?ArticleID=350"></A></P>
<P>在Delphi中选Project Import Type Library命令，在对话框中选Import Microsoft Shell Controls And Automation类型库，点Install后，在Delphi的ActiveX控件板上就多了TShellFolderItem，TShellLinkObject，TShellFolderView，TShell，TSearchCommand等几个组件</P>
<P>const<BR>&nbsp;&nbsp; discVerb = '禁用(&amp;B)';<BR>&nbsp;&nbsp; connVerb = '启用(&amp;A)';</P>
<P>function TForm1.DisableEthernet(const EthName,State: String): Boolean;<BR>var<BR>&nbsp; cpFolder: Folder;<BR>&nbsp; nwFolder: Folder;<BR>&nbsp; nVerbs: FolderItemVerbs;<BR>&nbsp; i,j,k: integer;<BR>&nbsp; aItem: TListItem;<BR>begin<BR>&nbsp; result := false;<BR>&nbsp; cpFolder := Form1.shell1.NameSpace(3);<BR>&nbsp; if cpFolder &lt;&gt; nil then<BR>&nbsp; begin<BR>&nbsp;&nbsp;&nbsp; for i := 0 to cpFolder.items.Count-1 do<BR>&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if cpFolder.Items.Item(i).Name = '网络和拨号连接' then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nwFolder := cpFolder.items.item(i).GetFolder as Folder;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if nwFolder &lt;&gt; nil then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for j :=0 to nwFolder.items.Count-1 do<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if nwFolder.Items.Item(j).Name = EthName then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nVerbs := nwFolder.Items.Item(j).Verbs;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for k := 0 to&nbsp; nVerbs.Count-1 do<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if nVerbs.Item(k).Name = State then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nVerbs.Item(k).DoIt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aItem := Form1.lvLog.Items.Add;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aItem.Caption := FormatDateTime('yyyy-mm-dd hh:mm:ss',now);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aItem.SubItems.Add(EthName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aItem.SubItems.Add(State);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result := True;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;<BR>&nbsp;&nbsp;&nbsp; end;<BR>&nbsp;&nbsp;&nbsp; if nwFolder = nil then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; showmessage('Network and Dial-up Connections not found');<BR>&nbsp; end<BR>&nbsp; else<BR>&nbsp;&nbsp;&nbsp; showmessage('control panel not found');</P>
<P>end;</P>
<P><BR>procedure TForm1.Button1Click(Sender: TObject);<BR>begin<BR>&nbsp; DisableEthernet('本地连接',discVerb);<BR>end;</P>
<P>procedure TForm1.Button2Click(Sender: TObject);<BR>begin<BR>&nbsp; DisableEthernet('本地连接',connVerb);<BR>end;<BR></P><img src ="http://www.blogjava.net/konhon/aggbug/11228.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-08-26 17:11 <a href="http://www.blogjava.net/konhon/archive/2005/08/26/11228.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>向CGI提交數據</title><link>http://www.blogjava.net/konhon/archive/2005/08/26/11188.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Fri, 26 Aug 2005 03:13:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/08/26/11188.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/11188.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/08/26/11188.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/11188.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/11188.html</trackback:ping><description><![CDATA[procedure TForm1.Button1Click(Sender: TObject);<BR>var<BR>&nbsp; lUrl: string;<BR>&nbsp; lParams: TStrings;<BR>&nbsp; lHtml: string;<BR>begin<BR>&nbsp; lUrl := 'http://snixxx.co.uk/cgi-bin/mt-comments.cgi';<BR>&nbsp; lParams := TStringList.Create;<BR>&nbsp; try<BR>&nbsp;&nbsp;&nbsp; lParams.Add('entry_id=1302');<BR>&nbsp;&nbsp;&nbsp; lParams.Add('author=dqxhyy');<BR>&nbsp;&nbsp;&nbsp; lParams.Add(<A href="mailto:'dqxhyy@sina.com'">'dqxhyy@sina.com'</A>);<BR>&nbsp;&nbsp;&nbsp; lParams.Add('dqxhyydqxhyydqxhyydqxhyy');<BR>&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lHtml := IdHttp1.Post(lUrl, lParams);<BR>&nbsp;&nbsp;&nbsp; except<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; showmessage(lhtml);<BR>&nbsp;&nbsp;&nbsp; end;<BR>&nbsp;&nbsp;&nbsp; showmessage(lhtml);<BR>&nbsp; finally<BR>&nbsp;&nbsp;&nbsp; lParams.Free;<BR>&nbsp; end;<BR>end;<img src ="http://www.blogjava.net/konhon/aggbug/11188.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-08-26 11:13 <a href="http://www.blogjava.net/konhon/archive/2005/08/26/11188.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何通过发送WM_COMMAND消息模拟点击其他程序窗体上的菜单项? </title><link>http://www.blogjava.net/konhon/archive/2005/08/26/11169.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Fri, 26 Aug 2005 02:05:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/08/26/11169.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/11169.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/08/26/11169.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/11169.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/11169.html</trackback:ping><description><![CDATA[<BR>procedure TForm1.Button1Click(Sender: TObject);<BR>var<BR>&nbsp;&nbsp; h,m,s,s1:hwnd;<BR>begin<BR>&nbsp; h:=FindWindow('notepad',nil);<BR>&nbsp;&nbsp; if h&lt;&gt;0 then<BR>&nbsp;&nbsp; begin<BR>&nbsp;&nbsp;&nbsp;&nbsp; m:=GetMenu(h);<BR>&nbsp;&nbsp;&nbsp;&nbsp; s:=GetSubMenu(m,1);<BR>&nbsp;&nbsp;&nbsp;&nbsp; s1:=GetSubMenu(s,7);<BR>&nbsp;&nbsp;&nbsp;&nbsp; SendMessage(h,WM_COMMAND,MakeLong(GetMenuItemId(s,7),0),s1);<BR>&nbsp; end;<BR>end;<img src ="http://www.blogjava.net/konhon/aggbug/11169.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-08-26 10:05 <a href="http://www.blogjava.net/konhon/archive/2005/08/26/11169.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Lalel上单击，然后在Label下文出现下拉框（popupmenu），怎样让下拉框紧挨着Label下方出现。</title><link>http://www.blogjava.net/konhon/archive/2005/08/25/11116.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Thu, 25 Aug 2005 11:58:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/08/25/11116.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/11116.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/08/25/11116.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/11116.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/11116.html</trackback:ping><description><![CDATA[procedure TForm1.Label1Click(Sender: TObject);<BR>var<BR>&nbsp; lPoint: TPoint;<BR>begin<BR>&nbsp; lPoint.X := TLabel(Sender).Left;<BR>&nbsp; lPoint.Y := TLabel(Sender).Top + TLabel(Sender).Height;<BR>&nbsp; lPoint:=ClientToScreen(lPoint);<BR>&nbsp; PopupMenu1.Popup(lPoint.X, lPoint.Y);<BR>end;<img src ="http://www.blogjava.net/konhon/aggbug/11116.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-08-25 19:58 <a href="http://www.blogjava.net/konhon/archive/2005/08/25/11116.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DBGrid不夠寬加'...'</title><link>http://www.blogjava.net/konhon/archive/2005/08/25/11115.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Thu, 25 Aug 2005 11:57:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/08/25/11115.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/11115.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/08/25/11115.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/11115.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/11115.html</trackback:ping><description><![CDATA[procedure TForm1.ADODataSet1MaterielNameGetText(Sender: TField;<BR>&nbsp; var Text: string; DisplayText: Boolean);<BR>var<BR>&nbsp; lSingleWidth: integer;<BR>&nbsp; lDBGridWidth: integer;<BR>begin<BR>&nbsp; lSingleWidth := DBGrid1.Canvas.TextWidth('壹');<BR>&nbsp; lDBGridWidth := DBGrid1.Columns[1].Width;<BR>&nbsp; if DBGrid1.Canvas.TextWidth(Sender.AsString) &lt;= lDBGridWidth then<BR>&nbsp;&nbsp;&nbsp; Text := Sender.AsString<BR>&nbsp; else if DBGrid1.Canvas.TextWidth(Sender.AsString) &gt; lDBGridWidth then<BR>&nbsp; begin<BR>&nbsp;&nbsp;&nbsp; lSingleWidth := lDBGridWidth div lSingleWidth - 1;<BR>&nbsp;&nbsp;&nbsp; if lSingleWidth mod 2 = 1 then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lSingleWidth := lSingleWidth + 1;<BR>&nbsp;&nbsp;&nbsp; Text := Copy(Sender.AsString, 1, lSingleWidth) + '...';<BR>&nbsp; end<BR>end;<BR><img src ="http://www.blogjava.net/konhon/aggbug/11115.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-08-25 19:57 <a href="http://www.blogjava.net/konhon/archive/2005/08/25/11115.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何得到鼠标经过listview每一行的各列信息</title><link>http://www.blogjava.net/konhon/archive/2005/08/25/11114.html</link><dc:creator>konhon 优华</dc:creator><author>konhon 优华</author><pubDate>Thu, 25 Aug 2005 11:45:00 GMT</pubDate><guid>http://www.blogjava.net/konhon/archive/2005/08/25/11114.html</guid><wfw:comment>http://www.blogjava.net/konhon/comments/11114.html</wfw:comment><comments>http://www.blogjava.net/konhon/archive/2005/08/25/11114.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/konhon/comments/commentRss/11114.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/konhon/services/trackbacks/11114.html</trackback:ping><description><![CDATA[<P>uses CommCtrl;</P>
<P>procedure TForm1.ListView1MouseMove(Sender: TObject; Shift: TShiftState; X,<BR>&nbsp; Y: Integer);<BR>var<BR>&nbsp; item: TListItem;<BR>&nbsp; lvhti: LV_HITTESTINFO;<BR>begin<BR>&nbsp; item := ListView1.GetItemAt(X, Y);<BR>&nbsp; if (item &lt;&gt; nil) then<BR>&nbsp;&nbsp;&nbsp; Caption := 'Mouse at: ' + item.Caption<BR>&nbsp; else<BR>&nbsp; begin<BR>&nbsp;&nbsp;&nbsp; lvhti.pt.X := X;<BR>&nbsp;&nbsp;&nbsp; lvhti.pt.Y := Y;<BR>&nbsp;&nbsp;&nbsp; ListView_SubItemHitTest(ListView1.Handle, @lvhti);<BR>&nbsp;&nbsp;&nbsp; if Assigned(ListView1.Items[lvhti.iItem])<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and (ListView1.Items[lvhti.iItem].SubItems.Count &gt;= lvhti.iSubItem) then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Caption := 'Mouse at:' + ListView1.Items[lvhti.iItem].SubItems[lvhti.iSubItem - 1];<BR>&nbsp; end;<BR>end;<BR></P><img src ="http://www.blogjava.net/konhon/aggbug/11114.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/konhon/" target="_blank">konhon 优华</a> 2005-08-25 19:45 <a href="http://www.blogjava.net/konhon/archive/2005/08/25/11114.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>