网络安全 频道

了解二十个最危险的安全漏洞

  7. 友情提示
  7.1 检查编辑器窗体是否为原理图类型

如果原理图编辑器服务器没有被安装在设计资源管理器中,当一个自定义的服务器尝试向原理图编辑器发请求时,设计资源管理器可能会崩溃。

因此这里有两个已写好的代码片段,您应该在进行任何Sch API调用前,把它插入到代码中。

·第一个代码片段当前编辑器窗体是否是原理图图表类型。

If MessageRouter_GetState_WindowKind(SchAPI_GetCurrentEditorWindow) <> 'Sch' Then Exit;

//检查当前的文档类型是否是Sch,即原理图,如果不是则退出。

//SchAPI_GetCurrentEditorWindow是返回当前文档对象的窗体句柄。

//MessageRouter_GetState_WindowKind函数使用编辑器窗体句柄返回表示编辑器窗体类型的字符串值。例如,Advanced PCB 编辑器返回“PCB”字符串,并且TextEdit服务器返回“TEXT” 字符串。

·第二个代码片段检查当前文档是否是一个库文档。

If MessageRouter_GetState_WindowKind(SchAPI_GetCurrentEditorWindow) <> 'SchLib' Then Exit;

·第三个代码片段将强制在设计资源管理器中加载原理图编辑器服务器,如果在设计资源管理器中此服务器没有被激活(停止)的话。

hModule := GetModuleHandle('AdvSch');

If hModule = 0 Then

Begin

P := AllocateParameterBlock(256);

//AllocateParameterBlock函数创建一个用空字符填充的内存块。返回指向已分配的内存句柄。

SetState_Parameter(P,'Action','Start');

SetState_Parameter(P,'Server','Sch');

//上述代码SetState_Parameter(P,'Action','Start')是在P指针所指向的参数块中插入“Action”参数,值为“Start”。SetState_Parameter过程插入一个参数到指定的参数文本块中,过程有三个参数,P为指定到一个参数文本块的指针,Name为指定要被插入的参数名称,Value为指定要被插入的参数值。

MessageRouter_SendCommandToModule('Client:SetupEDAServers',P,256,cProcessWindow_DontCare);

//MessageRouter_SendCommandToModule函数定义如下:

//FunctionMessageRouter_SendCommandToModule(Process : TString;Parameters: PChar;

MaxParameterSize: Integer;EditorWindow: HWnd) : Boolean;

//MessageRouter_SendCommandToModule函数运行指定的过程在指定的模块内,如果成功则返回True,否则返回Flase.此函数允许一个服务器来运行一个在其它服务器中的进程。

//Process参数为指定完整的进程名称。举例来说,“Macro:RunMacro”,此参数对大小写不敏感。

//Parameters为传递给进程的参数块。MaxParameterSize为参数分配的内存大小。

//EditorWindow为目标文档对象窗体句柄。无文档则为cProcessWindow_DontCare。

FreeParameterBlock(P,256);

//FreeParameterBlock过程释放先前为参数分配的内存,P指定指向参数内存块的指针,256为指定指向参数内存块的指针。

End;

  7.2 产生一个包含元器件名称和引用库的输出报告文本文件

此代码例子根据原理图图表名称产生了一个文本文件,扩展名称是Txt,此文本文件中报告在原理图文档中查找到的元件的元件名称、引用库、流水号信息。

请见SDK例子\SAMPLES\NO3\API\Sch\Generate a Text document。

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

Implementation

Var

Partslist : TStringList;//元件列表。

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

//以下这段代码是根据当前原理图文档来取得其容器对象,并刷新容器对象,代码主要是用在对象发生改变后。

Procedure Repopulate;

Var

EntityHandle: ClientTypes.TObjectHandle;

BinderHandle: ClientTypes.TObjectHandle;

Begin

//更新设计树和容器。

EntityHandle :=ClientAPI_FindEntityByDataHandle(MessageRouter_GetState_CurrentEditorWindow);

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

//ClientApi_FindEntityByDataHandle 函数使用一个编辑器窗体句柄来返回查找返回一个实体的句柄。此实体能表现为设计资源管理器编辑器窗体内的一个文档。您能通过使用ClientAPI_QueryEntity 或ClientAPI_QueryDocumentEntity 查询此实体来检查文档类型,名称等等。

If EntityHandle = 0 Then Exit; //无对象则退出。

BinderHandle := ClientApi_GetDocumentOwnerBinder(EntityHandle);

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

ClientApi_RepopulateDocumentEntity(BinderHandle,False);

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

End;

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

Procedure WriteAndEmbedTextFileIntoDDB;

Var

CurrentSheet: TObjectHandle;

ComponentHandle : TObjectHandle;

Iterator: TObjectHandle;

PartHandle: TObjectHandle;

I : Integer;

SchPart : TSchPart;

F : TextFile;

S : TString;

CurrentSheetEntity: ClientTypes.TObjecthandle;

Begin

If MessageRouter_GetState_WindowKind(SchAPI_GetCurrentEditorWindow) <> 'Sch' Then Exit;

//检查当前的文档类型是否是Sch,即原理图,如果不是则退出。

//SchAPI_GetCurrentEditorWindow是返回当前文档对象的窗体句柄。

//MessageRouter_GetState_WindowKind函数使用编辑器窗体句柄返回表示编辑器窗体类型的字符串值。例如,Advanced PCB 编辑器返回“PCB”字符串,并且TextEdit服务器返回“TEXT” 字符串。

CurrentSheet := SchAPI_GetCurrentSheetHandle;

//SchAPI_GetCurrentSheetHandle函数返回当前原理图文档的指针(句柄)。

Iterator := SchAPI_CreateIterator(CurrentSheet,ePart);

//SchAPI_CreateIterator函数给定两个参数,返回一个迭代程序对象的句柄,对象句柄到当前图表文档和对象种类。此函数用于搜索指定对象种类的对象。

If Iterator <> Nil Then //如果迭代程序对象建立成功。

Begin

Partslist := TStringList.Create;//创建存放元件属性的列表。

PartHandle := SchAPI_GetFirstObject(Iterator);

//SchAPI_GetFirstObject函数使用给定的迭代程序句柄返回第一个查找到的原理图对象。

While PartHandle <> Nil Do

Begin

SchPart := TSchPart.Create(Nil);

//创建一个原理图元件对象。

SchPart.ObjectHandle := PartHandle;

//把查找到的元件对象的句柄赋予新建的原理图对象。

SchPart.Querydatabase(eGetState);

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

ComponentHandle := SchAPI_GetLibraryComponentHandle(

SchPart.LibReference,kShortStringLength);

// SchAPI_GetLibraryComponentHandle函数用给定的库引用字符串和字符串的长度参数返回一个库组件的句柄,即元件所引用的元件库的句柄。

Partslist.Add(StrPas(SchPart.LibReference) + ' Designator = '

+ GetStringFromTextObject(SchPart.PartDesignator));

//把元件库的引用库名称(SchPart.LibReference)和设计流水号信息(SchPart.PartDesignator)加到元件信息列表Partslist中。

SchPart.Free;

PartHandle := SchApi_GetNextObject(Iterator);

//SchAPI_GetNextObject函数使用给定的迭代程序句柄返回下一个发现的对象。此函数被用于连接SchAPI_GetFirstObject函数。

Partslist.Add('');

//一个元件之间加一个空行。

End;

SchAPI_DestroyIterator(Iterator);

//在当前原理图全部查找完成后销毁迭代程序对象。

Partslist.Add('Report created on '+ DateToStr(Date) + ' ' + TimeToStr(Time));

//输出报表产生时间

End;

//原理图实体的绝对的地址的扩展名称被修改…

CurrentSheetEntity := ClientApi_FindEntityByDataHandle(

SchAPI_GetCurrentEditorWindow);

//ClientApi_FindEntityByDataHandle 函数使用一个编辑器窗体句柄来返回查找返回一个实体的句柄。此实体能表现为设计资源管理器编辑器窗体内的一个文档。您能通过使用ClientAPI_QueryEntity 或ClientAPI_QueryDocumentEntity 查询此实体来检查文档类型,名称等等。

ClientApi_GetDocumentEntityAbsoluteAddress(CurrentSheetEntity,S);

//在关联的设计数据文档内获得一个文档实体的绝对地址。

S := ForceFileNameExtension(S, 'TXT');

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

AssignDDB(F,S,'Admin');//产生并且放入文件到DDB中。AssignDDB过程联合F到一个设计数据库的实体直到F被关闭为止。

Rewrite(F);

Writeln(F,'Schematic Parts Report...');

Writeln(F,'=========================');

Writeln(F,'');

Writeln(F,'');

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

Writeln(F,PartsList.Strings[I]);

Writeln(F,'');

CloseFile(F);

Repopulate;//刷新对象。

Partslist.Free;

End;

更多的关于AssignDDB函数调用参考明细和客户端API和RTL参考,请参见相关迭代程序章节内容。

  7.3 文件查找

您可以仔细读一读FileFind例子,FileFind工程在“\SAMPLES\NO3\Servers\FileFind”目录下,此FileFind非常类似一个查找对话框,可在任何在设计资源管理器中打开的设计数据库中查找设计文档,“FileFind”服务器也是通过服务器制作向导产生的。

  7.4 作用域不兼容性

如果您使用了客户端API和原理图API,编译器有时或许会抱怨有不兼容的类型。例如,当您试图在您的源代码中使用客户端API函数“DocumentEntity.QueryDataBase(eGetState)”,您尝试进行编译,编译器提示说‘Incompatible types(不兼容的类型).’。

解决方法是使用“DocumentEntity.QueryDataBase(ClientTypes.eGetState);”这样,编译器就知道如何来解决类型问题。(e-works)

0
相关文章