请教:NetMeeting的“程序共享”的实现原理因最近在尝试完成一个“多媒体教室”的项目。现已把“音视频”“聊天”“白板”“传输文件”等等都完成了,惟独就是“程序共享”还找不着北。我希望能够实现的是,NetMeeting那样的效率。于是,我也揣摩了NetMetting的实现原理。我感觉它是用Windows-Hook来拦截指定进程的全部消息的。接着,分析进程的消息是否改变了窗口内容;如果改变了,就取得“更新区域”来获得最小绘制区,然后,就实时捕获到了窗口的变化,而且这样的效率也是最高的。因为我还做过一个观察:在使用NetMeeting的“程序共享”时,观察客户端的网络监视器,发现:如果服务端被共享的程序没有改变,则网络监视器的网络数据流量几乎为0。这也充分说明了NetMeeting的“程序共享”是立即反应的,而不是流式的。我现在也在使用Windows-Hook来试图实现之。目前已经能够拦截指定进程的全部消息了,但是,我发觉使用这个技术有个弊端:如果程序是使用自定义消息来画DC的,那么,就根本不能为力。
现请教各位朋友,谁能够说说NetMeeting的“程序共享”实现原理。我不需要代码,我只要知道思路和实现原理就可以了。或者,也希望有朋友能够说说他自己的思路(理论上可行就好),使我能够实现我的需求。
谢谢大家!

解决方案 »

  1.   

    to: pzm(阿 满) 这个办法我也想过,但是,考虑可以画DC的API实在是太多了(TextOut....),再加上DirextDraw,GDI+,OpenGL等等,所以,我感觉不太可能。我就是很想知道NetMeeting的“程序共享”是如何实现的.....
      

  2.   

    这个API
       InvalidateRect()
    就应该可以
      

  3.   

    我没有用过netmeeting,不过前一段时间做过一个远程监控的程序,不知netmeeting的程序共享是不是两个人通过网络看到同一个程序的画面?
    如果是的话,我想netmeeting是通过mirror driver做到的(显示驱动镜象)
      

  4.   

    to:pzm(阿 满) 
    InvalidateRect()只能使区域无效,即触发擦背景的事件。
    如果某个程序不使用这个函数,而直接画DC,就不能捕获了。比如,用一个Timer来画DC,同时不擦背景。
    TO:shootingstars(流星) 
    mirror driver很有可能!!这个东西我以前粗略看过。现在,我想判断一点:如果使用mirror driver的话,是采用显存流式捕获,还是显存区变化才捕获?还有,就是压缩-发送的问题(当然,这些都算是小问题了)。
      

  5.   

    其实我对mirror driver并不是很了解,如果搂主有什么心得还望和大家讨论讨论。
    前段时间研究了一下vnc的代码,它就是采用的hook各个程序的消息来更新屏幕的。如果搂主采用这种方式,可以借鉴它的代码,它使用的压缩算法是比较适宜屏幕压缩的。
    我奇怪的是为什么vnc不采用mirror driver,楼主如果有mirror driver方面的资料的话能否发给我看看,谢谢[email protected]
      

  6.   

    我也想学一下,楼主麻烦也传给我好吗,[email protected]
      

  7.   

    TO: shootingstars(流星) 前段时间,我就仔细看过一遍mirror driver,心得目前还谈不上,Video不是我的专长。代码在DDK里面就有啊。非常详细的。“vnc的代码,它就是采用的hook各个程序的消息来更新屏幕的”。这个方法我目前正在试,但是,在理论我就觉得这种方法不足以捕获到程序的所有屏幕变化信息。(当然,我不希望使用timer来每隔一点时间去抓一张图,我希望在捕获所有的改变)至于mirror driver,很遗憾,它目前的版本只能适用于2000/XP,9X/NT都不支持,所以,我打算放弃它了。
      

  8.   

    用钩子确实不能保证截获所有的屏幕变化,最明显的是控制台窗口,还有IE的滚动窗口等。
    当然,vnc也意识到了这个问题,所以vnc采用了轮讯窗口的机制来补充,比如vnc默认轮讯控制台窗口(也就是每次传输屏幕信息之前先监测控制台窗口是否变化,如果变化则传输控制台信息),虽然这也不是万全之策,但采用了这种方式后绝大部分的屏幕更新都可以监测到了。
      

  9.   

    TO: shootingstars(流星) 如果采用轮询制,那么,就要变成“流式播放”了我就是最担心这个东西的效率啊。。
      

  10.   

    如果采用轮询制,是否可以在程序中首先保存上一次的图像, 然后
    和这次的图像进行比较, 判断是否有改变.如果有改变, 是否可以自定义
    一种压缩格式, 传递一个和上次的偏移量, 而不是直接将新的图像完全
    传送过去.
    这样网络流量比较小, 但是CPU就用的比较多.
      

  11.   

    没有研究过,但我知道Netmeeting极容易让人蓝屏(2000/xp),而且与DX也可能是显卡驱动有冲突
      

  12.   

    没有研究过,但我知道Netmeeting极容易让人蓝屏(2000/xp),而且与DX也可能是显卡驱动有冲突,觉得它应该与显卡,显存有很紧密的关系
      

  13.   

    TO:ilovevc(ilovevc) 
    其实我也同意你的观点,甚至都一直这么去做的。但是,我观察Netmeeting却是不怎么消耗CPU的。不知道它是怎么实现的......
      

  14.   

    那么,是否可以使用Video Compression Manager里面的函数
    来捕获窗口, 保存成一个流呢. 例如:
    capCreateCaptureWindow 函数, 然后压缩, 例如:
    ICCompress 来压缩.具体不知道, 没有作过. 不过我也很想知道是否这种方法可行否.
      

  15.   

    to: ilovevc(ilovevc) 
    这种方法我做过,但是不合适
    1。流式播放,即使窗口没有任何改变,它也会发送数据,对网络消耗大;
    2。视频捕获是有固定格式的,如果程序的窗口尺寸在99.999%的情况都是非视频格式尺寸,所以不能用。
      

  16.   

    接下来就不清楚了. 不过我大致用Depends查看了一下netmeeting
    使用的dll, 好像也没有太多有用的信息.其实pcanywhere的共享桌面作得不比netmeeting差.
    是否考虑从pcanywhere上面得到某些启示.另外, 从实用的角度, 我觉得,
    第一, 当然,需要能够感知屏幕的变化, (这个是技术的最难点)
    第二, 主要是网络流量,
    最后才考虑CPU和内存, 毕竟现在的CPU的运算速度太猛了, 不用白不用.另外, 好像Video Compression Manager里面有些函数可以用来作压缩
    图片使用, 这样就不必要自己来实现压缩算法了.>>如果程序是使用自定义消息来画DC的,那么,就根本不能为力
    你说的"自定义消息"是不是就是Custom Draw ? 这个有什么特别吗?
      

  17.   

    另外, netmeeting能够在远端看到例如realplayer等非GDI的
    窗口的内容吗? 这些窗口一般通过print-screen是无法得到内容的.如果不能, 按照 "shilong(银羽·以吻赠剑) " 说的, 是否netmeeting
    是直接操作底层的显卡的显存?
      

  18.   

    我指的自定义消息,例如:
    用一个Timer,每隔1秒钟执行一次TextOut(),同时又不擦DC背景,这样,WINDOWS-HOOK就非常难捕获了。我现在就是想找到一种能够完全跟踪和捕获窗口内容变化(无论是DC,还是EDIT之类的控件)的方法,
    就是找不到......
      

  19.   

    DirectX的程序呢?
    使用DirectX的程序和普通程序没什么明显区别,但是没有消息可以供HookCommand what is yours
    Conquer what is not