这段代码做什么?
在此代码例子中,一个新的具有关于一个原理图图表中的所有元件的信息的文本文档被创建,此文档通过迭代机制提取的所有元件的图元。代码中使用两个迭代程序类型,对象迭代程序和组迭代程序。外循环使用对象迭代程序,迭代程序搜索元件对象,内循环使用组迭代程序,组迭代程序搜索内置在元件对象的图元。
迭代程序句柄被传递到SchAPI_GetFirstIterator函数,SchAPI_GetFirstIterator返回在数据库中第一个发现的元件的句柄,通过SchAPI_GetNextIterator来约束一个While Do语句,SchAPI_GetNextIterator读取下一个元件的句柄,直到没有更多元件被查找到为止。在While Do语句内,每一个查找到的元件有它的容器,被传递到一个组迭代程序,此组迭代程序从此元件对象中读取图元。
在内循环中,组件句柄被使用SchAPI_GetLibraryComponentHandle函数从元件对读取,函数使用元件对象的LibReference字段(即元件在元件库中的名称)和此字段的字符串长度参数。一个元件仅是在库组件的一个表示,唯一的在原理图图表中编辑元件图元的方法是从元件库中获取此组件的句柄。
应用库组件句柄,使用SchAPI_GetLibraryPartCount函数读取子元件的总数。子元件的总数被使用,来重复读取一个库元件中所有的子元件信息,子元件总数循环值被传递到SchAPI_GetLibraryPartContainer函数,SchAPI_GetLibraryPartContainer函数读取子元件对象的容器句柄,一个元件对象有三个容器,一般DeMorgan 和 IEEE,在此例子中,我们仅对一般的元件图形表示感兴趣,因此,eCompDisplayNormal值被随着元件总数和组件句柄传递到SchAPI_GetLibraryPartContainer函数。
容器句柄被分配到SchAPI_CreateGroupIterator,组迭代程序遍历此元件容器来读取图元(元件子项目,每一根引脚)。在每一次组迭代程序处理时,元件的库引用信息(LibReference)和“元件流水号”(PartDesignator)信息被检索并且插入到此文本文档中。查找到的子元件项目(item)的句柄被组迭代程序传递到SchAPI_ReplicatePartItem函数,此SchAPI函数返回子元件项目item(图元)的一个拷贝,由于返回的元件item仅是此元件item的实际图元的一个拷贝,因而,您仅能调用QueryDatabase(eGetState)来检索关于此元件对象的子元件(即引脚)item的参数。eSetState模式将对子元件item不起作用。一旦您完成上子元件item检索完成,确保必须使用SchAPI_DestroyPartItem来回收分配给此图元的内存。
直到SchAPI_GetNextGroupIterator函数找不到更多的子元件item(引脚),内循环结束并且外循环继续,查找更多的元件直到没有更多的元件来被处理。文本文档被使用了由Protel 强大的RTL库提供的AssignDDB函数创建,显示在一个原理图文档中查找到的每一个元件对象的所有引脚位置,您需一个原理图图表的绝对地址来传递到AssignDDB函数,更多信息请参见客户端API章节。
6.5 删除错误标记例子
这个例子对进程参数进行检查,判断是否从当前原理图图表中或从一个项目中的所有原理图图表中删除错误标记,如果进程的参数为DocumentLevel = ‘Project’(大小写不敏感)将激活服务器来遍历在项目中的所有原理图图表并且删除所有错误标记,如果字符串不是“Project”,那么错误标记仅从当前原理图图表中被删除。
下面这段代码例子功能主要是删除错误标记。是通过对主程序参数块中的参数DocumentLevel进行判断,判断是否为Project,如果Project则对整个项目中所有原理图图表进行处理,否则仅对当前原理图图表进行处理。收集原理图图表的句柄放在AHandleList中,然后调用CollectErrorMarkers程序来对AHandleList中所存放在原理图图表分别进行处理,检索出所有错误标记对象句柄并放在BagOfErrormarkers列表中,最后调用DeleteErrorMarkerObjects删除错误标记对象。
请见SDK例子\SAMPLES\NO3\API\Sch\Complex Error Marker Eraser。
{....................................................................................}
//这段程序是对AhandleList列表所存放的原理图句柄列表分别进行处理,从每一原理图图表中查找错误标记对象,并且把错误标记对象加到BagOfErrorMarkers列表中,再调用DeleteErrorMarkerObjects来删除这些错误标记对象。
Procedure CollectErrorMarkers(AHandleList : TList);
Var
Iterator: TObjecthandle;//迭代程序对象
J : Integer;
CurrentSheet: TObjecthandle;//当前原理图句柄
Errormarker : TSchErrorMarker;//错误标记对象
BagOfErrormarkers : TList;//存放错误标记对象的句柄
//DeleteErrorMarkerObjects过程销毁BagOfErrormarkers列表中存放在要销毁的错误标记对象。
Procedure DeleteErrorMarkerObjects;
Var
I : Integer;
Begin
If BagOfErrorMarkers <> Nil Then
Begin
For I := 0 To BagOfErrormarkers.Count - 1 Do
SchAPI_DestroyObject(BagOfErrorMarkers.Items[I]);
//SchAPI_DestroyObject过程销毁一个指定的原理图对象,此循环销毁BagOfErrormarkers列表中存放在要销毁的错误标记对象。
End;
End;
Begin
//创建一个列表来收集错误标记对象
BagOfErrormarkers := TList.Create;
//对AHandleList列表中所有原理图进行检索,检索出错误标记对象放到BagOfErrorMarkers列表中。
For J := 0 to AHandleList.Count -1Do
Begin
CurrentSheet := AHandleList.Items[J];
//分别取得要处理的原理图句柄,对AhandleList列表中的原理图进行处理,AhandleList中存放要处理的原理图。
Iterator := SchAPI_CreateIterator(CurrentSheet,eErrorMarker);
//创建一个对象迭代程序,用来查找错误标对象。
If Iterator <> Nil Then //迭代程序对象创建成功。
Begin
ErrorMarker:= TSchErrorMarker.Create(Nil);
//创建错误标记对象。
ErrorMarker.Objecthandle := SchAPI_GetFirstObject(Iterator);
//查找第一个错误标记对象,找到后把其句柄给新建立的错误标记对象。
While ErrorMarker.Objecthandle <> Nil Do //如果有错误标记对象。
Begin
ErrorMarker.QueryDatabase(eGetState);
//用内部服务器数据同步外部服务器数据。
BagOfErrorMarkers.Add(ErrorMarker.Objecthandle);
//把错误标记对象句柄加到错误列表标记对象中,以便对进一步处理。
ErrorMarker.Objecthandle := SchApi_GetNextObject(Iterator);
//查找下一个错误标记对象。
End;
SchAPI_DestroyIterator(Iterator);
//销毁迭代程序对象。
End;
End;
If BagOfErrorMarkers.Count > 0 Then DeleteErrorMarkerObjects;
//如果错误标记对象中有超过0的总数,说明收集到错误标记对象,则调用DeleteErrorMarkerObjects过程来在原理图图表中删除这些错误标记。
BagOfErrormarkers.Free;
//列表释放。
End;
{....................................................................................}
//本章节程序的主程序。
Procedure Command_DeleteErrorMarkers(Window : TServerWindow; Parameters : PChar);
var
Value: String;//存放从参数表中检索出的参数值。
J: Integer;
Sheethandle: TObjectHandle;//当前原理图句柄。
HandleList : TList;//存放要处理的原理图句柄。
Begin
If MessageRouter_GetState_WindowKind(SchAPI_GetCurrentEditorWindow) <> 'Sch' Then Exit;
//检查当前的文档类型是否是Sch,即原理图文档,如果不是则退出。
//SchAPI_GetCurrentEditorWindow是返回当前文档对象的窗体句柄。
//MessageRouter_GetState_WindowKind函数使用编辑器窗体句柄返回表示编辑器窗体类型的字符串值。例如,Advanced PCB 编辑器返回“PCB”字符串,并且TextEdit服务器返回“TEXT” 字符串。
//检查进程参数来从一个原理图图表中或项目中删除错误标记。
HandleList := TList.Create;//创建存放要处理的原理图图表的列表。
Value:= '';
GetState_Parameter(Parameters, 'DocumentLevel', Value);
//从参数块“Parameters”中检索“DocumentLevel”参数,找到后放在字符串“Value”中。
If UpperCase(Value) = 'PROJECT' Then //如果参数值是PROJECT,表示对整个项目图表进行。
Begin
SheetHandle := SchAPI_GetCurrentSheetHandle;//取得当前句柄。
For J := 0 to SchAPI_GetDocumentCountInProject(SheetHandle) - 1 Do
HandleList.Add(SchAPI_GetDocumentHandleByIndex(J, SheetHandle, False));
//把整个项目中所有原理图图表中句柄放在列表HandleList中。
//SchAPI_GetDocumentCountInProject函数使用给定的一个原理图文档的句柄返回属于一个项目的子文档数量。
//SchAPI_GetDocumentHandleByIndex使用给定的Index、SchWindow和SetToTop参数返回一个文档的句柄。此函数有三个参数,Index表示一个项目中文档的索引,SchWindow表示一个原理图窗体的对象的句柄,SetToTop设置此文档在其它文档的顶部并且激活。
End
Else HandleList.Add(SchAPI_GetCurrentSheetHandle);
//不是对整个项目处理,而是对当前原理图进行处理。
If HandleList.Count > 0 Then CollectErrorMarkers(HandleList);
//如果在整个项目中有多个原理图或有当前原理图,则调用CollectErrorMarkers(HandleList)来判断这些原理图中是否有错误标记并进行相应的处理。
HandleList.Free;
End;
此段代码片段所使用了下列的重要的函数和过程。
|
MessageRouter_GetState_WindowKind |
SchAPI_GetDocumentCountInProject |
|
SchAPI_GetCurrentEditorWindow |
SchAPI_GetDocumentHandleByIndex |
|
GetState_Parameter |
Querydatabase |
|
SchAPI_GetCurrentSheetHandle |
MessageRouter_SendCommandToModule |
这段代码做什么?
过程参数被从设计资源管理器中传递到DeleteErrorMarkers服务器,这种传递参数的能力,表现出了设计资源管理器和它的即插即用服务器具有强大的能力。
这个服务器在设计资源管理器中检查已存在的原理图图表,一旦检查是有效的,全局的变量,如原理图图表总数(Sheet Count)和原理图图表句柄数组被初始化并且和分配值,接着主过程SearchAndCollectErrorMarkers被调用。
在迭代程序循环中,通过把原理图图表句柄分配到存放原理图句柄的列表HandleList中,按索引迭代程序循环变量,也就是说,如果仅有一个原理图图表,那么仅有一个原理图图表句柄被分配到迭代程序函数,否则,对于多个原理图图表,迭代程序将遍历项目中每一个原理图图表,查找并且读取错误标记,把错误标记放到BagOfErrormarkers列表中,一旦所有的原理图图表被处理完成,DeleteErrorMarkerObjects过程将被调用,DeleteErrorMarkerObjects过程从BagOfErrorMarkers列表中,使用SchAPI_DestroyObject函数来删除所有的错误标记。(e-works)