在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注册事件函数
        .....