信息化 频道

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

  6.9 报告原理图图表例子

此例子显示原理图文档的子项目。您需要一个迭代程序对象来导向查找机制,在一个设计数据中执行项目(Item)的线性的搜索。

请见SDK例子\SAMPLES\NO2\API\Client\Report Child Schematic Sheets。

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

Procedure ReportSchematics;

Var

DocumentName : TString;//实体对象的抽象地址。

DocumentAddress : TDDBAddress;//抽象地址对象。

Iterator: TObjectHandle;//迭代程序对象。

DocHandle : TObjectHandle;//查找到的实体对象句柄。

DDBItem : TDDBItem;//项目对象。

SchematicChildList : TStringList; //创建存放当前原理图和所属子原理图名称的列表。

I : Integer;

SchematicsString : String;//合成原理图和下属原理图名称字符串。

Begin

DocumentAddress := TDDBAddress.Create('');//创建一个抽象地址对象。

Iterator := ClientApi_CreateIterator(0, [eDocument], eAll);

//创建一个迭代程序对象,查找所有实体文档(eDocument)。

DocHandle := ClientApi_GetFirstEntity(Iterator);//得到第一个查找到的文档对象。

While DocHandle <> 0 Do //如果已查找到对象。

Begin

ClientApi_GetDocumentEntityAbsoluteAddress(DocHandle, DocumentName);

//把查找到的实体对象的抽象地址提取出来,赋予抽象地址字符串DocumentName。

DocumentAddress.Import_FromParameters(DocumentName);

//Import_FromParameters使用抽象地址参数字符串设置一个TDDBAddress对象。

If StringsEqual(UpperCase(DocumentAddress.EditorKind), 'SCH') Then

//如果当前是原理图,编辑器的类型为SCH表示是原理图。

If DocumentAddress.HasChildItems Then //HasChildItems判断是否有子文档。

Begin

DDBItem := TDDBItem.Create('Admin',DocumentName);//创建一个项目。

DDBItem.Read;

//ReadHeader函数读入快捷方式键连接或检索子项目(在当前项目下的项目)并且返回一个TQueryError值。如果函数调用没有成功,一个“eQEBadConnection”值被返回。

SchematicChildList := TStringlist.Create;

//创建存放当前原理图和所属子原理图名称的列表。

SchematicChildList.Add(DocumentAddress.Display_Caption);

//DocumentAddress.Display_Caption如果设计数据库是一个MS Access数据库,返回值是设计数据库所在的完整路径(一个一般的MS Windows路径名称)。如果设计数据库是一个非MS Access数据库,返回值是下列格式:“DB=”+ 设计数据库根路径 + “File=”+ 设计文档偏移路径。返回字符串。

//把查找到的当前原理图对象的完整路径加到列表SchematicChildList中。

SchematicChildList.LoadFromStream(DDBItem.ChildList);

//把当前原理图的子原理图图表加到列表中。

SchematicsString := '';

For I := 0 To SchematicChildList.Count - 1 Do

SchematicsString := SchematicsString + ' ' + SchematicChildList.Strings[I];

//把当前原理图路径和其下属的所有子原理图(如果有的话)名称字符串加在一起,合成一个字符串SchematicsString。

If SchematicChildList.Count > 0 Then

ShowInfo(DocumentAddress.Offset.Name + '有下列子原理图' + #13 +

SchematicsString);

//DocumentAddress.Offset.Name表示当前查找到的原理图的名称。

//如果当前原理图有子原理图则显示合成的字符串。

SchematicChildList.Free;//释放存放当前原理图和所属子原理图名称的列表。

DDBItem.Free;//释放项目对象。

End;

DocHandle := ClientApi_GetNextEntity(Iterator);//查找下一个原理图对象。

End;

ClientApi_DestroyIterator(Iterator);//释放迭代程序对象。

DocumentAddress.Free;//释放抽象地址对象。

End;

这段代码做什么?

此段代码片段中重要的函数和类。

ClientApi_CreateIterator

ClientApi_GetFirstEntity

ClientApi_GetNextEntity

ClientApi_DestroyIterator

ClientApi_GetDocumentEntityAbsoluteAddress

Import_FromParameters

TDDBAddress

TDDBItem

ChildList

此代码设立一个在设计数据库中查找文档的迭代机制。

首先建立一个TDDBAddress,接下来建立一个迭代程序用于查找所有文档,如果在当前DDB包中查找到有原理图文档,则使用ClientApi_GetDocumentEntityAbsoluteAddress把查找到的文档实体对象的抽象地址读取出来,再通过DocumentAddress.Import_FromParameters(DocumentName)把抽象地址读到TDDBAddress对象中,接下来判断DocumentAddress是否有子原理图,如果有,根据抽象地址建立一个项目对象DDBItem,调用项目对象的read过程读取出此原理图下属子原理图信息,再则建立一个存储当前原理图和其下属子原理图名称的列表SchematicChildList,执行SchematicChildList.LoadFromStream(DDBItem.ChildList)把当前原理图对象的子原理图信息加到列表SchematicChildList中。再把列表中内容合成字符串并显示出来。

6.10 OpenTextDocumentEntity

请见SDK例子\SAMPLES\NO2\API\Client\OpenTextDocumentEntity。

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

Procedure OpenAndShowTextDocument(Documentname : String);

Var

EntityHandle : TObjectHandle;//当前实体对象的句柄。

ReportHandle : TObjectHandle;//在当前实体对象所在的容器中查找到的文档对象句柄。

BinderHandle : TObjectHandle;//当前实体对象的容器的句柄。

S : TString;//抽象地址字符串变量。

newDocname : TString;//要查找的文档名称。

ReportEntity : TDocumentEntity;//文档对象实体。

Begin

EntityHandle :=

ClientAPI_FindEntityByDataHandle(MessageRouter_GetState_CurrentEditorWindow);

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

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

If EntityHandle = 0 Then Exit;//如果无实体对象则退出。

BinderHandle := ClientApi_GetDocumentOwnerBinder(EntityHandle);

//得到当前实体对象的容器对象句柄。

NewDocName := ExtractWholeFileNameFromPath(DocumentName);

//ExtractWholeFileNameFromPath函数提取DocumentName字符串中名称和扩展名称。

EntityHandle := ClientApi_FindChildDocumentInBinder(BinderHandle, NewDocName);

//在当前实体所在的容器中查找NewDocName文档对象。

ShowInfo('容器句柄(Binder Handle) = ' + IntToStr(BinderHandle) + '' + #13 + '实体句柄(Entity Handle) = '+ IntToStr(EntityHandle));

If EntityHandle <> 0 Then //如果查找到文档对象,则把对象打开并设置为当前对象。

Begin

ClientApi_GetDocumentEntityAbsoluteAddress(EntityHandle, S);

//把查找到的文档对象实体的抽象地址赋予字符串S。

S := ExtractWholeFileNameFromPath(S);

//ExtractWholeFileNameFromPath函数从字符串S中提取文档对象的文件名称和扩展名称。

ReportHandle := ClientApi_FindChildDocumentInBinder(BinderHandle, S);

//在当前实体所在的容器中查找文档对象S。

If ReportHandle = 0 Then Exit;//如果未找到则退出。

ReportEntity := TDocumentEntity.Create(ReportHandle);//找到后创建一个文档对象。

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

If ReportEntity.ObjectHandle = 0 Then

//ObjectHandle表示实体的窗体句柄,为零表示当前没有窗体打开。

ClientApi_OpenDocumentEntity(ReportHandle, False)

//在窗体中打开查找到的文档,如果参数不为False而是True,则在设计资源管理器中直接打开。

Else

Begin

ClientApi_PerformAutoZoomForDocumentEntity(ReportHandle);//查找到的文档在窗体中以整页尺寸方式显示,自动地缩放到合适大小。

ClientApi_SetAsCurrentDocument(ReportHandle); //置为当前激活。

End;

MessageRouter_SendCommandToModule('TextEdit:MoveCursorToTopOfDocument', Nil, 0,

MessageRouter_GetState_CurrentEditorWindow);

//移动光标到文档的顶层。

ReportEntity.Free;//对象实体释放。

End

Else

ShowInfo('要查找的文档不存在!’);

End;

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

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

Var

ADocumentName : String;

Begin

If GetState_Parameter(Parameters,'DocumentName',ADocumentName) Then

OpenAndShowTextDocument(ADocumentName)

Else ShowInfo('无效的参数,参数为DocumentName=Memory.Sch这样的型式。');

//GetState_Parameter函数参数块中检索一个参数值,如果找到返回True,否则返回False。参数被传递到一个空字符为终止符和数组中。

End;

这个程序通过提取从参数传递来的要查找的文档名称,调用OpenAndShowTextDocument过程来查找文档。

OpenAndShowTextDocument过程先取得当前实体句柄,如果当前实体句柄为零,则退出。根据当前实体的句柄,ClientApi_GetDocumentOwnerBinder取得其上级容器的句柄,然后调用过程ExtractWholeFileNameFromPath(DocumentName)来取得要查找文档的文件名称和扩展名称,执行ClientApi_FindChildDocumentInBinder(BinderHandle, NewDocName)来在当前实体所属的上级容器中查找文档,如果查找到,则调用ShowInfo来显示容器句柄和查找到的文档实体的句柄。

接下来调用ClientApi_GetDocumentEntityAbsoluteAddress(EntityHandle, S)来把查找到的实体文档的抽象地址赋予字符串S,ExtractWholeFileNameFromPath(S)获取文档的名称和扩展名称,ReportHandle := ClientApi_FindChildDocumentInBinder(BinderHandle, S)在当前实体所在的容器中查找文档对象S,如果查找到,调用TDocumentEntity.Create(ReportHandle)建立文档对象,并通过QueryDatabase(eGetState)同步数据。如果ReportEntity.ObjectHandle为0,方法ClientApi_OpenDocumentEntity(ReportHandle, False)在窗体中打开文档对象,如果不为0,ClientApi_PerformAutoZoomForDocumentEntity在窗体中打开文档并缩放到整页大小显示,并通过调用方法ClientApi_SetAsCurrentDocument来把查找到的文档置为当前文档。

这个程序的查找范围是当前实体所在的上级容器,如果要查找的文档不在当前实体上级容器中,即要查找的实体和当前实体不属同一个容器,则查找不到,即使这个要查找的文档在设计数据库中。

改进方法可以参照SearchAndOpenDocumentsAmend例子。(e-works)

0
相关文章