Delphi中高级DLL的编写和调用技巧
根据Delphi提供的有关 DLL编写和调用的帮助信息,你可以很快完成一般的 DLL编写和调用的 应用程序。本文介绍的主题是如何编写和调用能够传递各种参数(包括对象实例)的 DLL。例如, 主叫程序传递给 DLL一个ADOConnection 对象示例作为参数, DLL中的函数和
根据Delphi提供的有关 DLL编写和调用的帮助信息,你可以很快完成一般的 DLL编写和调用的 应用程序。本文介绍的主题是如何编写和调用能够传递各种参数(包括对象实例)的 DLL。例如, 主叫程序传递给 DLL一个ADOConnection 对象示例作为参数, DLL中的函数和过程调用通过该对象 实例访问数据库。
需要明确一些基本概念。对于 DLL,需要在主程序中包含 exports子句,用于向外界提供调用 接口,子句中就是一系列函数或过程的名字。对于主叫方(调用 DLL的应用程序或其它的 DLL), 则需要在调用之前进行外部声明,即external保留字指示的声明。这些是编写 DLL和调用 DLL必须 具备的要素。
另外需要了解Object Pascal 中有关调用协议的内容。在Object Pascal 中,对于过程和函数 有以下五种调用协议:
指示字 参数传递顺序 参数清除者 参数是否使用寄存器
register 自左向右 被调例 ......
最近一阵子,总是被一个莫名其妙的bug困扰。自己写的ocx(.net2005)在delphi7中调用,明明没有释放主动释放过内存,却被连续释放了两次。结果,程序退出时就down掉了。当然,这是在debug模式下才会出现,但是exe跑的时候会莫名奇妙的down掉,而且出错往往指向ocx,我想一定和ocx的调用有关。
上网找了purify,boundscheck等工具也是未果。很不爽。
最后只能把ocx的函数和属性一个一个调用检查。才发现错误。
原来....竟然....是:ocx的属性最后一项不能是VARANT_BOOL型,改为LONG就好了,太奇怪了(似乎只在最后一项时才有问题)。
VARANT_BOOL大概是2个字节的,估计调用时内存越界了。但是无论是vc还是delphi,似乎都没有做好。
看来,要避免这样的问题,统一用LONG型是最稳妥地。
OCX有时间要把其他的函数也修改一下了。 ......
procedure TForm1.Button3Click(Sender: TObject);
begin
//显示创建的数据集: dbgrid->datasource->clientdataset
//如果手工控制dbgrid显示宽度,dbgrid右键创建两个字段aa,bb,分别设置宽度即可
cds1.FieldDefs.Add('aa',ftString,40);
cds1.FieldDefs.Add('bb',ftInteger);
cds1.CreateDataSet;
cds1.Append;cds1.FieldValues['aa']:='a1';cds1.FieldValues['bb']:='10';cds1.Post;
cds1.Append;cds1.FieldValues['aa']:='a2';cds1.FieldValues['bb']:='20';cds1.Post;
cds1.Append;cds1.FieldValues['aa']:='a3';cds1.FieldValues['bb']:='30';cds1.Post;
//cds1.Active:=true;
//cds1.EmptyDataSet;
end; ......
procedure mc_SplitStr(sourStr:String;splitChar:String;desLst:TStringList);
var
tmpStr:String;
sValue:String;
iStart,iPos:Integer;
begin
try
desLst.Clear; //很重要,否则,会一直是第一个值
tmpStr:=sourStr;
iStart:=1;
iPos:=Pos(splitChar,tmpStr);
if iPos>0 then
begin
while iPos>0 do
begin
sValue:=MidBStr(tmpStr,iStart,iPos-iStart);
desLst.Add(sValue);
iPos:=iPos+length(splitChar); //跳过多分隔符情况下的剩余分隔字节
tmpStr:=midbstr(tmpStr,iPos,Length(tmpStr)-iPos+1);
iPos:=Pos( ......
Delphi
Delphi这是一个windows桌面编程软件,现在版本有很多,主要用的还是Delphi7,7以上的版本都需要装.net
静态调用和动态调用,静态调用就是直接往窗体上托控件,而动态调用就是编写代码调用控件的类实现一些功能。
通常情况下都是这两种方式相结合的使用,随着Delphi的深入,就会发现托控件不是万能的,很多时候都需要写代码,当然了托控件也能实现一些简单的功能。 ......
TreeView由节点构成,建树通过对TreeView.items属性进行操作。Items是一个TTreeNodes对象,这是一个TTreeNode集。
一、针对TTreeNodes,也就是 TreeView.Items,有这些属性:
1、count,节点个数。
2、item[index] ,通过index得到节点。
二、针对TTreeNodes,也就是 TreeView.Items,常用的添加节点的操作有:
AddFirst添加第一个根节点。由此函数添加的节点总排在前面,除非后来又使用此函数添加了一个节点,则后添加的节点将排在前面。该函数返回新添加的节点。
AddChildFirst添加第一个子节点,要求有父节点作为其参数。返回新添加的节点。
AddChild添加一个子节点,要求有父节点作为其参数。返回新添加的节点。
Add添加一个兄弟节点,要求有兄弟节点作为其参数。返回新添加的节点。
三、针对TTreeNodes,也就是 TreeView.Items,常用的得到节点的操作有:
GetFirstNode() 得到根节点。
然后配合TTreeNode.GetNext(),就可以访问所有的节点。
四、建树举例:
var
root_node,cur_node:TTreeNode;
begin
root_node:=AddFirst(nil,根节点1);
cur_node:=addChildfirst(root_node,nil,根节点1_child1);
add(cur_node,根节点1 ......