在GIS的产品开发中,OCX组件可以作为提供用户二次开发的不错选择。GIS的核心部分可以通过LIB方式提供。 本文简述在lib-ocx-exe中如何响应各种事件。
lib中(事件的发源地):
class ToolObserver
{
public:
virtual ~ToolObserver() {};
virtual void Update(CTool* tool, void* info) =0; //info 各种tool中传出去的消息,可以是任何类型
};
在ToolsManager中提供RegisterObserver(string toolName, ToolObserver* o)等方法,将外部的observer保存在vector中。
在需要触发的地方,调用observer->update方法,将信息传递出去。
ocx中(事件的中转站):
//用户单击并选中一个图形
class SelectSingleShapeEventObserver : public ToolObserver
{
private:
CHqGisOCXCtrl* ocx;
public:
SelectSingleShapeEventObserver(CHqGisOCXCtrl* ocx){this->ocx = ocx;}
public:
void Update(CTool* tool, void* info)
{
if(0 == ocx || 0 == tool) return;
CSelectTool* t = dynamic_cast<CSelectTool*>(tool);
if(0 == t) return;
ocx->CallSelectSingleShapeEvent(); //进一步向外部传递该事件
}
};
向ToolsManager注册
...............
m_ToolsMgr->RegisterObserver("Select", new SelectSingleShapeEventObserver(this));
.............
void CHqGisOCXCtrl::CallSelectSingleShapeEvent()
{
try {
FireSelectSingleShape(); //通过Fire方式,点燃
}
catch(...) {
//AfxMessageBox("警告:处理外部定义的事件中捕获到异常信息!");
}
}
在由ocx向外传递事件的方法中,可以通过fire点燃方式, 也可以通过 函数指针 方式进行/
如下:
typedef long (*FN_Listener)(long);
//利用 函数指针 实现回调
。。。。。。
FN_Listener fun_listener;
//外部exe中需要将static函数的地址传递给fun_listener(通过long)
。。。。。。
long CHqGisOCXCtrl::SetListenerFunction(long FunctionAddress)
{
fun_listener = (FN_Listener)FunctionAddress; //将long转换为函数指针
return 1;
}
..........
void CHqGisOCXCtrl::CallToolChangeEvent()
{
try {
if(fun_listener !=0 ) (*fun_listener)(12345); //执行外部的static函数
}catch(...) {}
}
..........
外部exe中(真正需要处理事件的地方):
static long ToolChangeEvent(long value) //响应事件的目的地
{
//m_ClientToolName = "";
return 54321;
}
.....
m_GisOCX.SetListenerFunction((long)ToolChangeEvent); //向ocx注册事件函数
.....
浙公网安备 33010602011771号