<连载>Protel二次开发从入门到精通
6.5 例子
此例子SwapLayers说明需要使用机器人来在当对象的层属性发生改变时,通知PCB编辑器的数据结构。在此代码例子中,当例子服务器运行时线对象被使用,一个光标提示用户来点击一个线对象,不管此线对象是在顶层或底层,将被分别地改变到底层或顶层。
请见SDK例子\SAMPLES\NO4\API\PCB\SwapLayerRobot。
{................................................................................}
Procedure ReDrawCurrentBoard;
Var
P : PChar;
Begin
GetMem(P, 255);//创建一个动态的内存变量并且指针到内存块的地址,大小为255。
StrPCopy(P,'');//复制一个空字符到一个空值终止的字符串,即用空值初始化内存块。
SetState_Parameter(P,'Action','All');
//SetState_Parameter过程插入一个参数到指定的参数文本块中,为动作,参数为All。
MessageRouter_SendCommandToModule('PCB:Zoom',P,255,0);
//MessageRouter_SendCommandToModule函数运行指定的过程在指定的模块内,如果成功则返回True,否则返回Flase.此函数允许一个服务器来运行一个在其它服务器中的进程。即调用PCB服务器中的Zoom缩放进程。
FreeMem(P,255);//释放变量
End;
{................................................................................}
Procedure SwapLayersForTracks;
Var
BoardHandle : TObjectHandle;//印制板对象句柄
TrackHandle : TObjectHandle;//线对象句柄
Layer : TLayer;//层
Begin
If MessageRouter_GetState_WindowKind(PCBAPI_GetCurrentEditorWindow) <> 'PCB' Then Exit;
//PcbApi_GetCurrentEditorWindow函数返回文档对象窗体句柄。
// MessageRouter_GetState_WindowKind函数使用编辑器窗体句柄返回表示编辑器窗体类型的字符串值。例如,Advanced PCB 编辑器返回“PCB”字符串,并且TextEdit服务器返回“TEXT” 字符串。
BoardHandle := PcbApi_GetCurrentBoardhandle;
//PcbApi_GetCurrentBoardHandle函数返回当前在设计资源管理器中的PCB文档的句柄,如果印制板没有找到则返回值是空(nil)。
TrackHandle := -1;
While TrackHandle <> 0 Do
Begin
Trackhandle := PcbApi_GetObjectAtCursor(BoardHandle,//印制板句柄
[eTrackObject],//线对象类型
Alllayers,//所有层
'选择线对象(Select Track)');//提示
//PcbApi_GetObjectAtCursor函数返回所点击的对象的句柄,当此函数调动激活时,一个光标出现在印制板上来提示用户点击任何PCB对象,所能点击的PCB对象依赖于参数提供,此函数调用将返回所选择的PCB对象句柄。此函数依赖于底层函数PcbApi_GetObjectAtXYAskUserIfAmbiguous支持来提取指定的PCB对象。
If(Trackhandle <> 0) Then
Begin
//PcbApi_EventRouter_SendMessage过程发送消息到PCB编辑器来通知机器人PCB编辑器环境已被改变。
PcbApi_EventRouter_SendMessage(c_FromSystem, c_Broadcast,
PCBM_CycleStart, BoardHandle);
//发送消息,一个周期的开始
PcbApi_EventRouter_SendMessage(TrackHandle ,c_Broadcast,
PCBM_ProcessStart, c_NoEventData);
//发送消息,一个进程的开始。
PcbApi_EventRouter_SendMessage(TrackHandle ,c_Broadcast,
PCBM_BeginModify , c_NoEventData);
//发送消息,一个PCB对象将要被修改。
//以下代码执行对一个PCB对象的修改
Layer := GetObjectlayer(TrackHandle);//得到当前线对象的所在的层。
If(Layer = eTopLayer) Then SetObjectLayer(Trackhandle,eBottomLayer)
//如果是顶层则改为底层
Else If(Layer = eBottomLayer) Then SetObjectLayer(Trackhandle,eTopLayer);
//如果底层则改为顶层
PcbApi_EventRouter_SendMessage(TrackHandle ,c_Broadcast,
PCBM_EndModify, c_NoEventData);
//发送消息,一个PCB对象已被修改。
PcbApi_EventRouter_SendMessage(c_FromSystem ,c_Broadcast,
PCBM_YieldToRobots, c_NoEventData);
//发送消息,机器人被激活。
PcbApi_EventRouter_SendMessage(c_FromSystem,c_Broadcast,
PCBM_ProcessEnd , c_NoEventData);
//发送消息,一个进程的结束。
PcbApi_EventRouter_SendMessage(c_FromSystem,c_Broadcast,
PCBM_CycleEnd, c_NoEventData);
//发送消息,一个周期的结束。
ReDrawCurrentBoard;//重绘当前印制板
End;
End;
End;
这段代码做什么?
PcbApi_GetObjectAtCursor函数通过用户使用光标来在线对象上点击线对象,返回其句柄。PcbApi_EventRouter_SendMessage函数发送消息到PCB编辑器,在PCB编辑器中内部的机器人能响应并且做它们自己的处理,当内部的机器人得到这些PCB消息,并且每次更新特定的线对象时,PCB编辑器数据被通知到。
当修改一个PCB对象的层时,不是必须使用PCB编辑器的QueryDatabase(eSetState)方法,改变一个PCB对象的层更多的涉及到交换,例如此对象的颜色,这就是使用机器人的原因。
在此代码例子中,两个PCB消息被发送到PCB编辑器,来指示周期和线对象进程交换已开始。一个带有当前线对象句柄的PCBM_BeginModify消息被发送到PCB编辑器,实际的线对象的层从顶层交换到底层或反过来,一个带有新分配层的线对象的句柄的PCBM_EndModify消息接着被发送到PCB编辑器,PCBM_YieldToRobots消息被发送到PCB编辑器来指示PCB环境需要更新,其包含更新线对象的层属性,最后的两个消息是停止此活动的过程和周期。(e-works)