功能需求:在vb窗口中请求一http页面(该页面不需要可见),该页面会不间断收到服务器发送来的数据(相当于一个tcp链接)目前用webbrowser已经实现该功能,但每次webbrowser收到数据触发DocumentComplete事件都会影响窗口其他控件的操作,比如刚好下拉了一个combobox,页面收到数据时该combobox会自动收起。因此想换一个控件来实现,试了试inet,该控件似乎只能返回第一次请求的页面内容,而且页面中的内容无法执行,比如返回的body中有一个onload函数,该onload函数就没有执行。socket暂时不考虑,因为这种http传数据的机制服务器端已经建好,现在只是GUI端的问题。有两个问题:
1、webbrowser触发DocumentComplete事件影响其他控件的问题有办法解决吗?
2、有没有别的合适的控件能实现我需要的功能?

解决方案 »

  1.   


    xmlhttp也试过了,和inet控件效果一样,代码如下,帮看看这么写对不对Private xmlHttp As New MSXML2.XMLHTTP30Public Sub Navigate(strUrl As String)
        xmlHttp.open "POST", strUrl, True
        xmlHttp.setRequestHeader "CONTENT-TYPE", "application/x-www-form-urlencoded"
        xmlHttp.onreadystatechange = Me
        xmlHttp.send
    End Sub
      

  2.   


    两个webbrowser?怎么用?
    DocumentComplete事件影响其他控件的问题就能解决?
      

  3.   

    wininet.dll有几个HTTP的API,你可以看看。
      

  4.   


    这个也看过了,用它做个异步的程序应该没问题,只是如下问题该如何解决:
    请求返回的http内容中的<body onload="fun()">...</body>那个onload事件该如何触发呢?或者触发后fun()该如何执行呢?inet和xmlhttp也就是fun()没有执行。
    用浏览器肯定没问题,onload事件会触发,fun()会执行,不知浏览器背后的代码是怎么做的?
      

  5.   

    无论inet或XMLHTTP组件或wininet API只提供对远程服务资源的下载,并不提供解析功能。 解析执行功能是由客户端浏览器来完成的。 如果简单固定的页面,你可以自己在下载数据完成后自己解析后模拟浏览器操作。 如果复杂的页面你还只能使用webbrowser控件,
      

  6.   

    有一种有待验证的方法就是使用 MSHTML组件。 这种方法据说可行,但没实际验证过,具体效果怎样不太清楚。1、引用MSHTML组件, 引用一个支持IStream, IPersitStreamInit接口的tlb2、下载页面内容,并通过 CreateStreamOnHGobal() API将下载的数据流创建一个 IStream对象。3、利用IPersitStreamInit.Load 方法将IStream装入MSHTML对象模型,之后你就可以利用mshtml组件处理了以后大致伪代码如下:
    dim objStream as IStream
    dim objPersit as IPersitStreamInit
    dim objDoc as  mshtml.Document....创建IStreamset objDoc = new mshtml.document
    set objPersit = objDoc
    objPersit.InitNew
    objPersit.Load objStream
      

  7.   

    将Webbrowser控件Visable属性设置为False
      

  8.   


    设为false就收不到DocumentComplete事件了
      

  9.   

    将 WebBrowser 控件放在另外一个窗体上试试。
      

  10.   


    这个之前也试过了,一样不行。不过奇怪的是电脑重启后DocumentComplete事件影响其它控件操作的问题没有了(也没做过修改,不知何故),只是每次触发DocumentComplete事件鼠标都会自己变为等待状态的图标,然后自己恢复,不断触发DocumentComplete事件,鼠标就会不停闪烁。
      

  11.   

    经测试, 在VB6 + VISTA下能测试通过。 其他系统环境没有测试HTML 代码, 目标路径在 c:\test.htm<script language = "vbscript" type ="text/vbscript">
    sub load_func()
    text1.value = "1000000"
    end sub
    </script><html>
    <body onload = "load_func()"> 
        <input id="Text1" type="text" />
        <input id="Submit1" type="submit" value="submit" onclick="Submit1_onclick()" />
        
        <script language="vbscript" type = "text/vbscript">
        sub Submit1_onclick()
    rnd -1 * timer
            text1.value = rnd() * 10000000
        end sub
        </script>
        
    </body>
    </html>
    VB6 工程引用MSHTML组件,引用一个支持IStream,IPersistStreamInit接口的tlb
    测试代码如下Private Sub Command1_Click()
         
        Dim objStream       As IStream
        Dim objStreamInit   As IPersistStreamInit
        Dim objDoc          As New MSHTML.HTMLDocument
        Dim objDoc3         As MSHTML.IHTMLDocument3
        Dim objSubmit       As MSHTML.IHTMLInputButtonElement
        Dim objText         As MSHTML.IHTMLInputElement
      
        On Error GoTo Err_Click1
        
        Set objStream = CreateFileStream("c:\test.htm")
        Set objStreamInit = objDoc
        
        objStreamInit.InitNew
        objStreamInit.Load objStream
      
        While objDoc.ReadyState <> "complete"
             DoEvents
        Wend
        
        Set objDoc3 = objDoc
        Set objSubmit = objDoc3.getElementById("Submit1")
        Set objText = objDoc3.getElementById("Text1")
        
        Debug.Print "初始赋值:" & objText.Value
        objSubmit.Click
        Debug.Print "随机赋值: " & objText.Value
        
        Exit Sub
       
    Err_Click1:
        MsgBox Err.Description
    End Sub
    测试输出
    初始赋值:1000000
    随机赋值: 1587733.03031921
      

  12.   

    谢谢bdzwj,这段代码确实可行,但我在实际应用中还有问题。我的第一次请求返回的html内容为:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
        <head>
            <base href="http://www4.xxx.com.cn:80/">
            <script type='text/javascript' src='/dwr/engine.js'> </script>
            <script type='text/javascript' src='/dwr/util.js'> </script>
            <script type='text/javascript' src='/dwr/interface/TradeConfirmation.js'> </script>
        </head>
        <body onload="dwr.engine.setActiveReverseAjax(true);TradeConfirmation.addScriptSession();">
            <span id="futReturnMsg3"></span>
            <span id="quotation"></span>
        </body>
    </html>
    这段内容按您说的方法objStreamInit.Load objStream后,objDoc.ReadyState一直不为"complete",这个问题该如何解决,我这样的请求内容这个方法可行吗?
      

  13.   

    另外,如下代码也能实现该功能    Dim objMSHTML          As New MSHTML.HTMLDocument
        Dim objDoc          As New MSHTML.HTMLDocument
        Dim objDoc3         As MSHTML.IHTMLDocument3
        Dim objSubmit       As MSHTML.IHTMLInputButtonElement
        Dim objText         As MSHTML.IHTMLInputElement    Set objDoc = objMSHTML.createDocumentFromUrl("c:\test.htm", vbNullString)    While objDoc.ReadyState <> "complete"
             DoEvents
        Wend
        
        Set objDoc3 = objDoc
        Set objSubmit = objDoc3.getElementById("Submit1")
        Set objText = objDoc3.getElementById("Text1")
        
        Debug.Print "初始赋值:" & objText.Value
        objSubmit.Click
        Debug.Print "随机赋值: " & objText.Value
      

  14.   

    把 while objdoc.readystate <> "complete" 替换成while objdoc.readystate = "loading" 试试
      

  15.   


    谢谢回复,我现在用如下代码能实现onload事件的触发并执行script
    Set objDoc = objMSHTML.createDocumentFromUrl("c:\test.htm", vbNullString)现在的问题是如何实现异步调用呢?就如webbrowser的DocumentComplete事件一样,当服务器推送数据过来时通知我即可。
      

  16.   

    把objDOC 利用withevents关键字设置成模块级变量, 你就能捕获DOCUMENT所触发的事件了, MSHTML各个组件中的事件接口很丰富,绝对能满足你的使用的。
      

  17.   


    代码如下,回调函数没有执行啊。是否要在哪里设置一下?
    Public WithEvents objDoc          As MSHTML.HTMLDocumentPrivate Sub objDoc_ondataavailable()
        '...    
    End Sub
      

  18.   

    搞定了,监听onreadystatechange即可,直到readyState="complete"
      

  19.   


    高兴得太早了,问题没有完全解决,收不到服务器推送过来的数据,服务器debug了一下,发现抛出了ClientAbortException的异常,看来MSHTML的链接没有保持住。不知如何解决?另开贴吧,这个贴先结了。