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

推荐订阅源

Martin Fowler
Martin Fowler
Jina AI
Jina AI
J
Java Code Geeks
Microsoft Security Blog
Microsoft Security Blog
Recent Announcements
Recent Announcements
I
InfoQ
L
LangChain Blog
The Cloudflare Blog
IT之家
IT之家
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog
A
About on SuperTechFans
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Last Week in AI
Last Week in AI
Blog — PlanetScale
Blog — PlanetScale
罗磊的独立博客
云风的 BLOG
云风的 BLOG
Microsoft Azure Blog
Microsoft Azure Blog
Engineering at Meta
Engineering at Meta
F
Fortinet All Blogs
博客园 - 聂微东
美团技术团队
博客园_首页

博客园 - 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注册事件函数
        .....