惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
Jina AI
Jina AI
月光博客
月光博客
博客园 - Franky
小众软件
小众软件
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Visual Studio Blog
有赞技术团队
有赞技术团队
V
V2EX
IT之家
IT之家
阮一峰的网络日志
阮一峰的网络日志
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
腾讯CDC
D
DataBreaches.Net
Hugging Face - Blog
Hugging Face - Blog
Martin Fowler
Martin Fowler
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
WordPress大学
WordPress大学
C
Check Point Blog
Microsoft Azure Blog
Microsoft Azure Blog
Microsoft Security Blog
Microsoft Security Blog

博客园 - say3say4的私人空间

期待 突破 解决 jboss和log4j的冲突问题 未来50家最具商业潜力网站名单(互联网周刊) java 和 c++ 之间通过 控制台 输入输出 传递数据 转贴_vc++ 编译 occi 接口的 环境设置 - say3say4的私人空间 结合开源项目(postgis mapserver ) 研究 oracle spatial oracle9i spatial 开发 occi (基于oci的c++接口) ajax应用体现_无需安装 msn等桌面软件 研习了一下google map api SWIG 万能语言粘合剂 AJAX和webgis在实际项目中的运用(电业局用电检查系统) ant中最基本的设置 虚拟机VMWARE和移动硬盘的合作_移动办公 对DWR的学习告一段落,开发了结合具体应用的DEMO 不错的网站 回忆AOP 被google搜索到了 地震、停水、禽流感 关于讨论ajax,B/S框架,B/S界面的一个有用的站点
在C++中使用事件回调机制(通过Observer模式、函数指针等实现)
say3say4的私人空间 · 2005-12-07 · via 博客园 - say3say4的私人空间

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