信息化 频道

<连载>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;

0
相关文章