将MDI封装到OCX中

        从10月份开始,我几乎就没有时间上网了,更不用说在这里写点东西,快过春节了,最近又解决了一系列的技术难题(对于我来说),现在公司的同事很多都回家 了,比较清闲,所以我这里有时间总结一下这几个月的工作。可能是思想里比较重视春节吧,所以总是把春节前作为一年的结束,把正月看作一年的开始,而阳历的 元旦不太看重,没有特别的感觉。最近的一个月特别忙,目的就是希望在本年结束之前给自己一个交代。
       最近一致在忙活我们的第四版软件,这是一个通用的软件平台,什么东西都可以管,也可以应用于任何一个领域,因为在3月底必须给用户开始安装,因此必须在次 之前将所有的技术问题解决,完全通过测试才可以。因为这款产品还没有正式发布,因此我不便于透露产品有关的详细内容,这里仅就该产品用到的技术总结一下。
       1、产品实现了供二次开发的功能。也就是在产品提供给用户之后,用户根据产品SDK,利用VC给产品增加新的功能,比如增加新的菜单,增加新的工具条,增 加新的功能模块,创建用户自己的DLL,这些DLL可以调用系统的API,实现相应的功能。关于这方面的技术在我自己的BLOG中已经讲述过了(2006 年2月份)。
       2、给产品增加脚本的支持。很多人都熟悉微软的Office系列软件,可以自己通过VB脚本编写一个功能模块,实现一些计算和处理,非常方便,如果让自己 的数据库管理软件实现这个功能岂不是非常好?编写企业级管理软件的朋友经常会面临用户需求的变化,当用户需求变化时,经常需要修改程序代码,如果能够通过 脚本实现用户的需求,那么程序员的工作量无疑会降低不少,很多需求用户自己都可以搞定。最终的好处是产品的运行和维护成本降低了。这个功能目前实现的非常 好,在我得BLOG中有这方面的内容( http://blog.csdn.net/sfcyyc/archive/2006/09/29/1306263.aspx),主要是利用.NET Framework中的VB或C#编译器,动态编译脚本代码。这里要非常感谢 Tim Dawsonwww.developerfusion.co.uk上 的一篇文章。
       3、将MDI程序封装到一个OCX中。由于自己对WEB编程的偏见,我没有很好的学习WEB编程,我现在连一个简单的ASP程序都不会写,而用户希望可以 通过WEB程序调用我们的数据,或显示我们的数据,或直接希望WEB版的程序。而且WEB版本的程序也存在很多好处,比如维护比较容易。而我们主要是进行 医学图像处理软件的开发,这种软件很难立刻C++,因此,我们公司的开发人员几乎都对VC非常熟悉,我们已经经过多年的开发积累了很多代码和组件,这些东 西通过ASP或C#实现几乎是不可能的,因此我们的目标就是以最简单的方式实现我们的程序在WEB上运行。我们的实现方式是通过OCX封装MDI程序,然 后在网页中调用。经过不到一周的努力,这个问题终于解决了。主要的方式就是通过将原来的MDI程序zaiEXE的编译成为一个扩展的DLL,然后在OCX 中调用这个DLL,这样,一个完整的MDI程序就出现在网页上,连高级的图像处理功能都可以在网页上实现。当然由于大量的相关DLL,我们只建议用户在局 域网内部调用这样的MDI客户端,在局域网外部,我们有另外一款完全通过ASP.NET实现的WEB程序,功能比MDI可能要少很多。这里非常感谢 Alexey Shalnov. 在CodeProject上的一篇文章 Hosting of MFC MDI applications from within WinForms and WPF applications
,该文章讲述了如何将一个MFC的MDI程序封装到WinFroms中,而我是采用其中的有关技术将MDI封装到了OCX中。其中还涉及到C++/CLR,Mixed DLL等等。
       4、在IE中的程序支持脚本。实际上如果将一个支持脚本的MDI封装在OCX中,然后在WEB网页中调用这个OCX,那么脚本支持是理所当然的,然而事实 并非如此,因为将OCX在WEB中调用时遇到一个问题。在MDI中可以很好的支持VB.NET或C#脚本,在Windows2000的IE浏览器中也可以 正常运行,但是在WindowsXP系统中的IE中却出现错误。后来经过整整一天的调试才发现这个问题,主要是由于通过C ++指针调用.NET的变量引起的,出问题之前的代码如下:
//下面的类封装了一个(CLR)Button的接口。
class CNetEventButtonPack : public CObject
{
public:
    CNetEventButtonPack()
    {
        m_iNetEvent=nullptr;
    }
    ~CNetEventButtonPack()
    {
        m_iNetEvent=nullptr;
    }
public:
    gcroot<IAgentUniButton ^> m_iNetEvent;
};
//然后在CButton中引用这个接口中对应的函数如下:
void CEventButton::OnLButtonDown(UINT nFlags, CPoint point)
{
    CButton::OnLButtonDown(nFlags,point);

    if(m_pobjPack)
    {
        CNetEventButtonPack * pPack = (CNetEventButtonPack *)m_pobjPack;
        pPack->m_iNetEvent->OnLButtonDown(nFlags, point.x , point.y );
    }

}
在普通的Windows程序中上述代码没有任何问题,编译、链接、运行完全正常,但是在WindowsXP下的IE中调用时就会产生错误,调试时根本无法 进入这个void CEventButton::OnLButtonDown(UINT nFlags, CPoint point),只是产生一个C++ 堆错误。后来感觉可能时指针调用pPack->m_iNetEvent不合理造成了代码地址的错误,后来试着将代码改为如下的样子就OK了:
class CNetEventButtonPack : public CObject
{
public:
    CNetEventButtonPack()
    {
        m_iNetEvent=nullptr;
    }
    ~CNetEventButtonPack()
    {
        m_iNetEvent=nullptr;
    }
private:
    gcroot<IAgentUniButton ^> m_iNetEvent;
public:
    void SetEventInterface(IAgentUniButton ^iButton)
    {
        m_iNetEvent = iButton;
    }
    void OnLButtonDown(int nFlags, int pointx , int pointy )
    {
        m_iNetEvent->OnLButtonDown(nFlags, pointx , pointy );
    }
   
};

void CEventButton::OnLButtonDown(UINT nFlags, CPoint point)
{
    CButton::OnLButtonDown(nFlags,point);

    if(m_pobjPack)
    {
        CNetEventButtonPack * pPack = (CNetEventButtonPack *)m_pobjPack;
        pPack->OnLButtonDown(nFlags, point.x , point.y );
    }

}

 将.NET变量完全封装在一个MFC类(Package)内部,对这个变量的访问都是通过(Package)类的成员函数实现,这个问题就解决了。我没有对C++/CLR互操作的问题做很详细的研究,但愿这个问题的解决对于有通用需求的朋友有帮助。
       5、还是这个MDI程序,他实在是功能太多了,明年我们会将他拆分一下,给他减轻一下负担。将数据库访问部分提取出来,可以单独运行在一个服务器上,然后 将逻辑运算部分提取出来,单独运行在一台服务器上,将表现层单独留在MDI中,这样MDI的功能就很简单了,维护起来也很方便。这样就是一个功能强大的分 布式数据库管理平台了。各个层之间如何通讯呢?通过.NET Remoting或者干脆使用WCF。
       6、有了独立的数据库访问层和逻辑层,那么我们的手机版的程序就轻而易举了。估计需要在2007年7月份开始实现。完全的WEB版程序也没有必要重复编写很多代码了,直接调用逻辑层就可以了。
       7、既然新的产品可以管理任何数据,那么这样的各个系统之间如何进行数据交换,A系统中的数据如何传递给B系统,传递过来之后又如何存储?这就是我们的UniObject协议所要解决的问题。
       还有其他很多有趣的问题,看来我们的2007年还是非常精彩的。
       祝春节愉快。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值