信息化 频道

<连载>Protel二次开发从入门到精通

  4.例子代码
  4.1 输出印制板信息到电子表格

这个“输出到Spread(Export To Spread)”例子示范了提取一个编辑器服务器文档信息并输出到一个Spread文档是可能的,使用下面的例子,在一个印制板文档中查找到的焊盘(pad)对象的属性并输出到一个spread文档。

请见SDK例子\SAMPLES\NO5\API\Spread\ExportDataToSpread。

{................................................................................}

//主程序。

Function Exporter : PCBTypes.TObjectHandle;

Var

BoardHandle: PCBTypes.TObjecthandle;//印制板对象句柄。

BoardFileName: TString;//印制板DOS型路径名称。

SpreadHandle : TSPHandle;//Spread型文档句柄。

PadHandle: TObjectHandle;//焊盘对象句柄。

IteratorHandle : TObjectHandle;//迭代程序。

Board: TPCBBoard;//印制板对象句柄。

PadRowNumber : Integer;//焊盘统计总数。

Padlist: TStringlist;//存放焊盘信息的列表。

BoardUnit: TUnit;

P: PChar;

Begin

SetAllPCBProcAddresses;

//SetAllPCBProcAddresses过程初始化并且设置所有PCB编辑器调用。即取得所有AdvPcb.dll中输出的函数和过程的地址指针。

BoardHandle := PcbApi_GetCurrentBoardHandle;

//PcbApi_GetCurrentBoardHandle函数返回当前在设计资源管理器中的PCB文档的句柄,如果印制板没有找到则返回值是空(nil)。

If BoardHandle = 0 Then Exit;

//得到印制板的文件名称getting board's Filename。

Board := TPCBBoard.Create(Boardhandle);//建立一个印制板对象。

Board.QueryDatabase(PCBTypes.eGetState);//用内部服务器数据同步外部服务器数据。

BoardFileName := ExtractFileName(ConvertToNormalFilePath(Board.FileName));

//ConvertToNormalFilePath函数转换一个抽象的地址到一个常规的DOS文件路径。

//ExtractFileName获取文件名称和扩展路径。

BoardFileName := ForceFileNameExtension(BoardFileName,'XLS');

//ForceFileNameExtension函数用新的扩展名称替代已存在的文件扩展名称。

BoardUnit := Board.DisplayUnit;

Board.Free;

GetMem(P, 4048);//申请内存。

SetState_Parameter(P,'Server','Spread');//设置命令参数。

SetState_Parameter(P,'Action','Start'); //设置命令参数。

MessageRouter_SendCommandToModule('Client:SetupEDAServers', P, 4048, 0);

//发送命令给Client服务器的SetupEDAServers过程,命令参数存在P中,内存大小为4048。此过程设置EDA服务器。

FreeMem(P, 4048);//释放内存。

SetupApiCalls;//设置一个Spread API调用。

SpreadHandle := CreateASpreadDocument(BoardFileName);//创建一个XLS型的spread文档。

If SpreadHandle = 0 Then Exit;

IteratorHandle:= PcbApi_CreateIterator(BoardHandle,//当前印制板句柄。

ePadObject,//要查找的对象为焊盘对象。

eProcessAll,

eIgnoreLayer);

//建立对象迭代程序。

PadHandle:= PcbApi_GetFirstObject(IteratorHandle);//查找第一个焊盘对象。

PadRowNumber := 0;//焊盘统计总数初始化为0。

While(PadHandle <> 0) Do//查找到有焊盘对象。

Begin

Inc(PadRowNumber);//焊盘对象数目统计。

PadList := TStringList.Create;//建立存放当前焊盘对象的列表。

ExtractAttributesOfAPadObject(PadRowNumber,BoardUnit,PadHandle,PadList);

//调用ExtractAttributesOfAPadObject过程来把当前焊盘中信息输出到列表PadList中。

ExportToSpread(SpreadHandle,PadRowNumber,PadList);

//把PadList列表中信息输出到一个XLS型的spread文档中。

Padlist.Free;//列表释放。

PadHandle := PcbApi_GetNextObject(IteratorHandle);//查找下一个焊盘对象。

End;

PcbApi_DestroyIterator(IteratorHandle);//销毁迭代程序。

RefreshDesignDatabase(SpreadHandle);//刷新spread文档。

End;

{................................................................................}

//CreateASpreadDocument函数创建一工作表。

Function CreateASpreadDocument(Filename : TString) : TSPHandle;

Var

EntityHandle : TObjectHandle;

BinderHandle : TObjectHandle;

NewDocHandle : TObjectHandle;

DocumentEntity : TDocumentEntity;

DDBItem: TDDBItem;

S: TString;

Begin

Result := 0;

EntityHandle :=

ClientAPI_FindEntityByDataHandle(MessageRouter_GetState_CurrentEditorWindow);

//MessageRouter_GetState_CurrentEditorWindow函数返回当前在项层的文档的窗体句柄。当前在项层在文档的窗体句柄。

//ClientApi_FindEntityByDataHandle函数使用一个编辑器窗体句柄来返回查找返回一个实体的句柄。

If Entityhandle = 0 Then Exit;

BinderHandle := ClientAPI_GetDocumentOwnerBinder(EntityHandle);

//ClientApi_GetDocumentOwnerBinder函数获得在其内部存有文档的封装对象的句柄,一个封装对象表现为包含实体的容器,一个实体可为一个设计文档或文件来。

NewDocHandle := ClientAPI_FindChildDocumentInBinder(BinderHandle,Filename);

//ClientApi_FindChildDocumentInBinder过程在容器中查找文档。

If NewDocHandle <> 0 Then ClientApi_DestroyEntity(NewDocHandle);

//文件如果找到,则销毁NewDocHandle句柄。

ClientAPI_GetDocumentEntityAbsoluteAddress(EntityHandle,S);

//ClientApi_GetDocumentEntityAbsoluteAddress在关联的设计数据文档内获得一个文档实体的绝对地址,即得到当前文档的绝对地址。

DDBItem:= TDDBItem.Create('Admin',S);//创建一个文件。

DDBItem.Address.Offset.Name := Filename;//文件名称为Filename。

DDBItem.Address.EditorKind:= 'Spread';//文件类型为Spread。

DDBItem.Address.Id:= cUnassignedID;//地址ID为cUnassignedID。

DDBItem.Address.Attributes:= 0;

DDBItem.Write;//写。

DDBItem.Free;//释放。

NewDochandle := WaitForCommit(BinderHandle,Filename);

ClientAPI_OpenDocumentEntity(NewDocHandle,False);//打开实体,但不在窗体中。

Result := SpreadAPI_GetCurrentSpreadHandle;

//SpreadAPI_GetCurrentSpreadHandle函数返回一个当前在设计资源管理器99中打开的spread文档的句柄。

End;

{....................................................................................}

Function WaitForCommit(BinderHandle : TObjectHandle; Docname :TString) : TObjectHandle;

Var

I : Integer;

Begin

Result := 0;

For I := 1 to 50 Do

Begin

ClientAPI_RepopulateDocumentEntity(BinderHandle,False);

//ClientApi_RepopulateDocumentEntity 过程在封装对象中刷新文档实体的内容依赖于Recursive参数值,如果参数为false,当前实体被刷新,否则实体的封装对象被刷新。它在当文档被增加到一个封装对象中您需要刷新封装对象来让设计资源管理器知道有新的文档时情况下很有用。

Result := ClientAPI_FindChildDocumentInBinder(Binderhandle,Docname);

//ClientApi_FindChildDocumentInBinder过程返回一个名称为Docname参数的文档,ADocumentEntity是包含容器的句柄。在ADocumentEntity句柄所表示的实体中查找名称为Docname的文档。

If Result <> 0 Then Break;

WaitForSingleObject(GetCurrentThread,100);

//GetCurrentThread得到当前的线程。

//WaitForSingleObject等待100毫秒。

End;

End;

{................................................................................}

//ExtractAttributesOfAPadObject过程把焊盘的参数加到列表PadList中。

Procedure ExtractAttributesOfAPadObject(PadNumber : Integer;BoardUnit : TUnit; PadHandle : PCBTypes.TObjectHandle;PadList : TStringList);

Var

Pad : TPCBPad;

S : TString;

Begin

Pad := TPCBPad.Create(PadHandle);//建立焊盘对象

Pad.QueryDatabase(PCBTypes.eGetState);//用内部服务器数据同步外部服务器数据

PadList.Add('Pad : '+ IntToStr(PadNumber));//焊盘N。

PadList.Add('TopXSize = ' + CoordUnitToString(Pad.TopXsize,BoardUnit));

//增加焊盘TopXsize参数。

PadList.Add('TopYsize = ' + CoordUnitToString(Pad.TopYsize,BoardUnit));

//增加焊盘TopYsize参数。

PadList.Add('MidXsize = ' + CoordUnitToString(Pad.MidXsize,BoardUnit));

//增加焊盘MidXsize参数。

PadList.Add('MidYsize = ' + CoordUnitToString(Pad.MidYsize,BoardUnit));

//增加焊盘MidYsize参数。

PadList.Add('BotXsize = ' + CoordUnitToString(Pad.BotXsize,BoardUnit));

//增加焊盘BotXsize参数。

PadList.Add('BotYsize = ' + CoordUnitToString(Pad.BotYsize,BoardUnit));

//增加焊盘BotYsize参数。

PadList.Add('HoleSize = ' + CoordUnitToString(Pad.HoleSize,BoardUnit));

//增加焊盘HoleSize参数。

PadList.Add('TopShape = ' + ShapeToString(Pad.TopShape));

//增加焊盘TopShape参数。

PadList.Add('MidShape = ' + ShapeToString(Pad.MidShape));

//增加焊盘MidShape参数。

PadList.Add('BotShape = ' + ShapeToString(Pad.BotShape));

//增加焊盘BotShape参数。

PadList.Add('Name = '+ Pad.Name);

//增加焊盘Name参数。

Case Pad.DaisyChainStyle of

eDaisyChainLoad : S := 'DAISYCHAINLOAD';

eDaisyChainTerminator : S := 'DAISYCHAINTERMINATOR';

eDaisyChainSource : S := 'DAISYCHAINSOURCE';

End;

PadList.Add('DaisyChainStyle = ' + S);

//增加DaisyChainStyle参数。

PadList.Add('Angle = '+ FloatToStr(Pad.Angle));

//增加焊盘Angle参数。

If Pad.Plated Then S := 'True' Else S := 'False';

PadList.Add('Plated = ' + S);

//增加焊盘Plated参数。

Pad.Free;

End;

{................................................................................}

// ExportToSpread过程完成把存放焊盘信息的APadList列表中内容输出到一工作图表中,并用Tab分隔。SpreadHandle为电子表格句柄,ARow为开始行,APadList为存放焊盘信息的列表。

Procedure ExportToSpread(SpreadHandle : TSPHandle; ARow : Integer; APadList : TStringList);

Const

cTab= #9;//换行

cEnter= #13;//回车

var

Buffer : PChar;

TempBuffer : PChar;

I: Integer;

Begin

If SpreadHandle <> 0 Then//当前有电子表。

Begin

GetMem(Buffer,1024); //申请1024字节内存。

GetMem(TempBuffer,1024); //申请1024字节内存。

StrPCopy(TempBuffer,'');//用空字符初始化内存。

StrPCopy(Buffer,''); //用空字符初始化内存。

For I := 0 to APadList.Count - 1 do //APadList为存放焊盘信息的列表。

Begin

StrPCopy(TempBuffer,APadList.Strings[i]);//把焊盘列表中信息放在内存中。

StrCat(Buffer,TempBuffer);//把TempBuffer中内存追加到Buffer中。

StrCat(Buffer,cTab);//把Buffer中内容加上换行符。

End;

StrCat(Buffer,cEnter);//焊盘列表中数据全部输出后,Buffer中追加回车符

SpreadAPI_InsertTabDelimitedText(SpreadHandle,ARow,1,Buffer);

//把SpreadHandle指向的工作图用TAB来确定界限的文本块分隔,从ARow行,1列开始。ARow参数是在当前印制板中第几个焊盘对象,即第一个焊盘对象从1行开始,第N个焊盘对象是N行开始。

FreeMem(TempBuffer,1024);//释放内存。

FreeMem(Buffer,1024); //释放内存。

End;

End;

{................................................................................}

//RefreshDesignDatabase过程刷新spread文档,使其每一列内容和宽度相适应。

Procedure RefreshDesignDatabase(SpreadHandle : TObjectHandle);

Var

Binderhandle : TObjecthandle;

Entityhandle : TObjecthandle;

P: PChar;

Begin

EntityHandle :=

ClientAPI_FindEntityByDataHandle(MessageRouter_GetState_CurrentEditorWindow);

//MessageRouter_GetState_CurrentEditorWindow函数返回当前在项层的文档的窗体句柄。当前在项层在文档的窗体句柄。

//ClientApi_FindEntityByDataHandle 函数使用一个编辑器窗体句柄来返回查找返回一个实体的句柄。

If EntityHandle = 0 Then Exit;

BinderHandle := ClientAPI_GetDocumentOwnerBinder(EntityHandle);

//ClientApi_GetDocumentOwnerBinder函数获得在其内部存有文档的封装对象的句柄,一个封装对象表现为包含实体的容器,一个实体可为一个设计文档或文件来。

ClientAPI_RepopulateDocumentEntity(BinderHandle,False);

//刷新当前实体。

//Spread单元自动格式化auto formatting of Spread cells

GetMem(P,1024);//申请1024字节内存

StrPCopy(P,'');//用空字符初始化内存

SetState_Parameter(P,'C1','-1');

//SetState_Parameter过程插入一个参数到指定的参数文本块中。

{初始列 Initial column }

SetState_Parameter(P,'C2','0');

{ 最后的列Final column}

SetState_Parameter(P,'ColumnWidth','AUTO');//宽度为自动适应。

MessageRouter_SendCommandToModule('Spread:FormatColumn',P,1024,SpreadHandle);

//发送命令给Spread服务器的FormatColumn过程,命令参数为P中存放的参数,内存大小为1024,目标对象句柄为SpreadHandle。

FreeMem(P,1024);

EntityHandle := ClientAPI_FindEntityByDataHandle(SpreadAPI_GetCurrentSpreadHandle);

//SpreadAPI_GetCurrentSpreadHandle函数返回一个当前在设计资源管理器99中打开的spread文档的句柄。

End;

此代码清单被完全地包含在创建一个新的spread文档代码中。此代码基本功能是创建一个spread文档,这里有一个WaitForCommit函数,此函数执行等待功能直到其能得到新的spread文档的句柄为止,接着使用印制板句柄,迭代程序查找焊盘对象的属性,属性被放入到一个TStringlist列表对象中,再用SpreadAPI_InsertTabDelimitedText函数把整个字符串从列表对象中传递到spread文档中,迭代程序继续运行直到没有更多的焊盘对象被从印制板文档中查找到,更多有关迭代程序信息,请参见PCB API章节和PCB API参考章节相关内容,更多的有关创建和维护文档实体的信息,请参见客户端API。

  4.2 提取印制板元器件信息到电子表格

请见SDK例子\SAMPLES\NO5\API\Spread\ExportComponentInfoToSpread。

此代码示范了如何把当前PCB板中元件信息提取出来并输出到电子表格中。代码中使用了很多涉及到在精通篇有关代码的基础知识,如Windows临时文件夹如何获取,元件信息的提取等内容,请读者仔细研究例子代码。

{....................................................................................}

//获取Windows临时文件夹。

function GetTempDirectory: String;

var

TempDir: array[0..255] of Char;

begin

GetTempPath(255, @TempDir);

Result := StrPas(TempDir);

end;

{....................................................................................}

//把整个存放元件信息列表中的内容输出到本地文本文件。

Procedure ExportComponentInfoToTempFile(TempFileName : TString; TotalInfoList : TStringList);

var

TempFile : TextFile;

i: Integer;

Csr: TSearchRec;

CFileAttrs: Integer;

begin

if FindFirst(GetTempDirectory + TempFileName, CFileAttrs, Csr) = 0 then

DeleteFile(GetTempDirectory + TempFileName);

//查找临时文件,如果找到则删除临时文件

AssignFile(TempFile,GetTempDirectory + TempFileName);//获得临时文件目录。

ReWrite(TempFile);//新建文。件

try

For I:=0 to TotalInfoList.Count-1 do

writeln(TempFile,TotalInfoList.Strings[I]);

finally

Closefile(TempFile);

end;

//把每一层的使用和显示信息输出到临时文件TempFile中。

end;

{....................................................................................}

Function WaitForCommit(BinderHandle : TObjectHandle; Docname :TString) : TObjectHandle;

Var

I : Integer;

Begin

Result := 0;

For I := 1 to 50 Do

Begin

ClientAPI_RepopulateDocumentEntity(BinderHandle,False);

//ClientApi_RepopulateDocumentEntity 过程在封装对象中刷新文档实体的内容依赖于

//Recursive参数值,如果参数为false,当前实体被刷新,否则实体的封装对象被刷新。

//它在当文档被增加到一个封装对象中您需要刷新封装对象来让设计资源管理器知道有新的文档时情况下很有用。

Result := ClientAPI_FindChildDocumentInBinder(Binderhandle,Docname);

//ClientApi_FindChildDocumentInBinder过程返回一个名称为Docname参数的文档,

//ADocumentEntity是包含容器的句柄。在ADocumentEntity句柄所表示的实体中查找名称为Docname的文档。

If Result <> 0 Then Break;

WaitForSingleObject(GetCurrentThread,100);

//GetCurrentThread得到当前的线程。

//WaitForSingleObject等待100毫秒。

End;

End;

{................................................................................}

//CreateASpreadDocument函数创建一工作表。

Function CreateASpreadDocument(Filename : TString) : TSPHandle;

Var

EntityHandle: TObjectHandle;

BinderHandle: TObjectHandle;

NewDocHandle: TObjectHandle;

DocumentEntity : TDocumentEntity;

DDBItem: TDDBItem;

S: TString;

Begin

Result := 0;

EntityHandle :=

ClientAPI_FindEntityByDataHandle(MessageRouter_GetState_CurrentEditorWindow);

//MessageRouter_GetState_CurrentEditorWindow函数返回当前在项层的文档的窗体句柄。

//当前在项层在文档的窗体句柄。

//ClientApi_FindEntityByDataHandle函数使用一个编辑器窗体句柄来返回查找返回一个实体的句柄。

If Entityhandle = 0 Then Exit;

BinderHandle := ClientAPI_GetDocumentOwnerBinder(EntityHandle);

//ClientApi_GetDocumentOwnerBinder函数获得在其内部存有文档的封装对象的句柄,

//一个封装对象表现为包含实体的容器,一个实体可为一个设计文档或文件来。

NewDocHandle := ClientAPI_FindChildDocumentInBinder(BinderHandle,Filename);

//ClientApi_FindChildDocumentInBinder过程在容器中查找文档。

If NewDocHandle <> 0 Then ClientApi_DestroyEntity(NewDocHandle);

//文件如果找到,则销毁NewDocHandle句柄。

ClientAPI_GetDocumentEntityAbsoluteAddress(EntityHandle,S);

//ClientApi_GetDocumentEntityAbsoluteAddress在关联的设计数据文档内获得一个文档

//实体的绝对地址,即得到当前文档的绝对地址。

DDBItem:= TDDBItem.Create('Admin',S);//创建一个文件

DDBItem.Address.Offset.Name := Filename;//文件名称为Filename

DDBItem.Address.EditorKind:= 'Spread';//文件类型为Spread

DDBItem.Address.Id:= cUnassignedID;//地址ID为cUnassignedID

DDBItem.Address.Attributes:= 0;

DDBItem.Write;//写。

DDBItem.Free;//释放。

NewDochandle := WaitForCommit(BinderHandle,Filename);

ClientAPI_OpenDocumentEntity(NewDocHandle,False);//打开实体,但不在窗体中。

Result := SpreadAPI_GetCurrentSpreadHandle;

//SpreadAPI_GetCurrentSpreadHandle函数返回一个当前在设计资源管理器99中打开的spread文档的句柄。

End;

{................................................................................}

//ExtractAttributesOfAComponentObject过程把元件的参数加到列表ComponentInfoList中。

Procedure ExtractAttributesOfAComponentObject(ComponentRowNumber : Integer;ComponentHandle : PCBTypes.TObjectHandle;ComponentInfoList : TStringList);

Var

Component: TPCBComponent;

ComponentName: TPCBText; //元件名称文本对象

ComponentComment: TPCBText; //元件备注文本对象

NameHandle: PCBTypes.TObjectHandle;//元件名称文本对象句柄

CommentHandle: PCBTypes.TObjectHandle;//元件备注文本对象句柄

NameContent: TString;//元件名称字符串

CommentContent: TString;//元件备注字符串

Begin

Component := TPCBComponent.Create(0); //创建一个元件对象。

Component.Objecthandle := Componenthandle;

//把查找的元件对象句柄赋予元件的对象句柄属性。

Component.Querydatabase(PCBTypes.eGetstate);

//用内部服务器数据同步外部服务器数据。

NameHandle := Component.Name;//取得元件名称句柄。

ComponentName := TPCBText.Create(NameHandle);//根据元件名称句柄创建文本对象。

ComponentName.Querydatabase(PCBTypes.eGetState);

//用内部服务器数据同步外部服务器数据,即把内部元件的名称信息读取文本对象中。

NameContent := ComponentName.List;//把元件名称字符串内容放到NameContent字符串变量中。

ComponentName.Free;//释放名称文本对象

CommentHandle := Component.Comment;//取得元件备注句柄。

ComponentComment := TPCBText.Create(CommentHandle);//根据元件备注句柄创建文本对象。

ComponentComment.Querydatabase(PCBTypes.eGetState);

//用内部服务器数据同步外部服务器数据,即把内部元件的备注信息读取文本对象中。

CommentContent := ComponentComment.List;//把元件备注字符串内容放到CommentContent字符串变量中。

ComponentComment.Free;//释放备注文本对象。

//Component.Pattern为流水号。

ComponentInfoList.Add('元件: ' + IntToStr(ComponentRowNumber));//元件N

ComponentInfoList.Add('元件名称='+ NameContent);

ComponentInfoList.Add('流水号='+ Component.Pattern);

ComponentInfoList.Add('元件备注='+ CommentContent);

Component.Free;//释放元件对象。

End;

{................................................................................}

// ExportToSpread过程完成把存放元件信息的AComponentList列表中内容输出到一工作图表中,

//并用Tab分隔。SpreadHandle为电子表格句柄,ARow为开始行,AComponentList为存放元件信息的列表。

Procedure ExportComponentInfoToSpread(SpreadHandle : TSPHandle; ARow : Integer; AComponentList : TStringList);

Const

cTab= #9;//换行

cEnter= #13;//回车

var

Buffer: PChar;

TempBuffer: PChar;

I: Integer;

Begin

If SpreadHandle <> 0 Then//当前有电子表。

Begin

GetMem(Buffer,1024); //申请1024字节内存。

GetMem(TempBuffer,1024); //申请1024字节内存。

StrPCopy(TempBuffer,'');//用空字符初始化内存。

StrPCopy(Buffer,''); //用空字符初始化内存。

For I := 0 to AComponentList.Count - 1 do // AComponentList为存放元件信息的列表。

Begin

StrPCopy(TempBuffer,AComponentList.Strings[i]);//把元件列表中信息放在内存中。

StrCat(Buffer,TempBuffer);//把TempBuffer中内存追加到Buffer中。

StrCat(Buffer,cTab);//把Buffer中内容加上换行符。

End;

StrCat(Buffer,cEnter);//元件列表中数据全部输出后,Buffer中追加回车符。

SpreadAPI_InsertTabDelimitedText(SpreadHandle,ARow,1,Buffer);

//把SpreadHandle指向的工作图用TAB来确定界限的文本块分隔,从ARow行,1列开始。

//ARow参数是在当前印制板中第几个元件对象,即第一个元件对象从1行开始,第N个元件对象是N行开始。

FreeMem(TempBuffer,1024);//释放内存。

FreeMem(Buffer,1024); //释放内存。

End;

End;

{................................................................................}

//RefreshDesignDatabase过程初始化Spread。

Procedure RefreshDesignDatabase(SpreadHandle : TObjectHandle);

Var

Binderhandle : TObjecthandle;

Entityhandle : TObjecthandle;

P: PChar;

Begin

EntityHandle :=

ClientAPI_FindEntityByDataHandle(MessageRouter_GetState_CurrentEditorWindow);

//MessageRouter_GetState_CurrentEditorWindow函数返回当前在项层的文档的窗体句柄。

//当前在项层在文档的窗体句柄。

//ClientApi_FindEntityByDataHandle 函数使用一个编辑器窗体句柄来返回查找返回一个实体的句柄。

If EntityHandle = 0 Then Exit;

BinderHandle := ClientAPI_GetDocumentOwnerBinder(EntityHandle);

//ClientApi_GetDocumentOwnerBinder函数获得在其内部存有文档的封装对象的句柄,

//一个封装对象表现为包含实体的容器,一个实体可为一个设计文档或文件来。

ClientAPI_RepopulateDocumentEntity(BinderHandle,False);

//刷新当前实体。

//Spread单元自动格式化auto formatting of Spread cells

GetMem(P,1024);//申请1024字节内存。

StrPCopy(P,'');//用空字符初始化内存。

SetState_Parameter(P,'C1','-1');

//SetState_Parameter过程插入一个参数到指定的参数文本块中。

{初始列 Initial column }

SetState_Parameter(P,'C2','0');

{ 最后的列Final column}

SetState_Parameter(P,'ColumnWidth','AUTO');//宽度为自动适应。

MessageRouter_SendCommandToModule('Spread:FormatColumn',P,1024,SpreadHandle);

//发送命令给Spread服务器的FormatColumn过程,命令参数为P中存放的参数,内存大小为

//1024,目标对象句柄为SpreadHandle。

FreeMem(P,1024);

EntityHandle := ClientAPI_FindEntityByDataHandle(SpreadAPI_GetCurrentSpreadHandle);

//SpreadAPI_GetCurrentSpreadHandle函数返回一个当前在设计资源管理器99中打开的spread文档的句柄。

End;

{................................................................................}

//主程序。

Function ExportComponentInfo : PCBTypes.TObjectHandle;

Var

BoardFileName: TString;//印制板DOS型路径名称。

TempFileName: TString;//输出临时文本文件名称。

SpreadHandle: TSPHandle;//Spread型文档句柄。

ComponentHandle: TObjectHandle;//元件对象句柄。

Board: TPCBBoard;//印制板对象句柄。

ComponentRowNumber : Integer;//元件统计总数。

TotalInfoList: TStringlist;//存放完整元件信息的列表。

ComponentInfoList: TStringlist;//存放元件信息的列表。

BoardUnit: TUnit;

P: PChar;

ComponentIteratorHandle : TObjectHandle;//迭代程序。

Begin

SetAllPCBProcAddresses;

//SetAllPCBProcAddresses过程初始化并且设置所有PCB编辑器调用。即取得所有AdvPcb.dll

//中输出的函数和过程的地址指针。

If PcbApi_GetCurrentBoardHandle = 0 Then Exit;

//如果当前激活的编辑器不是PCB编辑器则退出。

//PcbApi_GetCurrentBoardHandle函数返回当前在设计资源管理器中的PCB文档的句柄,

//如果印制板没有找到则返回值是空(nil)。

Board := TPCBBoard.Create(PcbApi_GetCurrentBoardHandle);//建立一个印制板对象。

Board.QueryDatabase(PCBTypes.eGetState);//用内部服务器数据同步外部服务器数据。

BoardFileName := ExtractFileName(ConvertToNormalFilePath(Board.FileName));

//ConvertToNormalFilePath函数转换一个抽象的地址到一个常规的DOS文件路径。

//ExtractFileName获取文件名称和扩展路径。

BoardFileName := ForceFileNameExtension(BoardFileName,'XLS');

//ForceFileNameExtension函数用新的扩展名称替代已存在的文件扩展名称。

BoardUnit:= Board.DisplayUnit;

Board.Free;

GetMem(P, 4048);//申请内存。

SetState_Parameter(P,'Server','Spread');//设置命令参数。

SetState_Parameter(P,'Action','Start'); //设置命令参数。

MessageRouter_SendCommandToModule('Client:SetupEDAServers', P, 4048, 0);

//发送命令给Client服务器的SetupEDAServers过程,命令参数存在P中,内存大小为4048。此过程设置EDA服务器。

FreeMem(P, 4048);//释放内存。

SetupApiCalls;//设置一个Spread API调用。

SpreadHandle := CreateASpreadDocument(BoardFileName);//创建一个XLS型的spread文档。

If SpreadHandle = 0 Then Exit;

ComponentIteratorHandle := PcbApi_CreateIterator(PcbApi_GetCurrentBoardHandle,

eComponentObject,//元件对象

eProcessAll,//处理所有

eIgnoreLayer);

//建立对象迭代程序。

ComponentHandle := PcbApi_GetFirstObject(ComponentIteratorHandle);//查找第一个元件对象。

//PcbApi_GetFirstObject函数使用给定的迭代程序(iterator)句柄返回第一个发现的PCB对象句柄。

ComponentRowNumber := 0;//元件统计总数初始化为0。

TotalInfoList := TStringList.Create;//建立存放整个元件对象的列表。

While (ComponentHandle <> 0) Do//查找到有元件对象。

Begin

Inc(ComponentRowNumber);//元件对象数目统计。

ComponentInfoList := TStringList.Create;//建立存放当前元件对象的列表。

ExtractAttributesOfAComponentObject(ComponentRowNumber,ComponentHandle,

ComponentInfoList);

//调用ExtractAttributesOfAComponentObject过程来把当前元件中信息输出到列表ComponentInfoList中。

ExportComponentInfoToSpread(SpreadHandle,ComponentRowNumber,ComponentInfoList);

TotalInfoList.Add(ComponentInfoList.Text);

//ExportComponentInfoToTotalInfoList(TotalInfoList,ComponentInfoList);

//把ComponentInfoList列表中信息输出到一个XLS型的spread文档中。

ComponentInfoList.Free;//列表释放。

ComponentHandle := PcbApi_GetNextObject(ComponentIteratorHandle);//查找下一个元件对象。

End;

SpreadAPI_SetColumnName(SpreadHandle,1,'序号');//设置第一列为序号。

SpreadAPI_SetColumnName(SpreadHandle,2,'名称');//设置第二列为名称。

SpreadAPI_SetColumnName(SpreadHandle,3,'流水号');//设置第三列为流水号。

SpreadAPI_SetColumnName(SpreadHandle,4,'备注'); //设置第四列为备注。

TempFileName := ForceFileNameExtension(BoardFileName,'TXT');

//建立与印制板名称相同但扩展名为TXT的输出文本文件名称。

ExportComponentInfoToTempFile(TempFileName,TotalInfoList);

//把整个存放元件信息列表中的内容输出到本地文本文件。

TotalInfoList.Free;//释放存放整个元件信息的列表。

PcbApi_DestroyIterator(ComponentIteratorHandle);//销毁迭代程序。

RefreshDesignDatabase(SpreadHandle);//刷新spread文档,使其每一列内容和宽度相适应。

End;

{....................................................................................}

Procedure Command_ExportComponentInfoToSpread(Window : TServerWindow; Parameters : PChar);

Begin

ExportComponentInfo;

End;

(e-works)

0
相关文章