问题的起源:设置自己喜欢的浏览器为系统绝对默认的浏览器。
(修改.http等关联不是重点)探索过程:
请看测试程序1:
Private Sub Form_Load()
WebBrowser1.Navigate "www.sina.com.cn"
End Sub
就这么一行代码,其他不做任何处理。当WebBrowser1打开网页后,随便点一个会打开新窗口的超链接,这个时候会发生什么事情?通常情况是IE打开了这个窗口。我们都知道新窗口是在WebBrowser1_NewWindow2事件中发生的,但为什么会打开IE呢?那一定是通过某种途径通知了IE。
继续研究,发现通知到这里:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0002DF01-0000-0000-C000-000000000046}\LocalServer32
起值="C:\Program Files\Internet Explorer\iexplore.exe"
调用的方式大约是Shell C:\Program Files\Internet Explorer\iexplore.exe -Embedding为了证明我的猜测,请看测试程序2:
Private Sub Form_Load()
MsgBox Command
End Sub
用以监视调用参数,将其编译为c:\app2.exe,然后将上述注册表的值修改为c:\app2.exe,再在测试程序1中随便点一个会打开新窗口的超链接,这个时候又会发生什么事情?没有打开IE了,app2.exe执行了,并且MsgBox显示-Embedding,由此证明了调用的流程:没有处理WebBrowser1_NewWindow2的情况下,调用了HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{0002DF01-0000-0000-C000-000000000046}\LocalServer32所指向的程序,带参数-Embedding那问题就来了,当LocalServer32=IE或MT的时候,IE和MT等浏览器为什么能正确打开呢?请注意这里带的参数是-Embedding而并不是暴露的URL地址。似乎唯一的解释就是IE和MT等在发现带-Embedding这个参数调用的时候从某个接口等获得了WebBrowser1_NewWindow2的ppDisp或URL。而我们自己写的程序如何做到这一点呢?就象上面的测试程序2,当检测到-Embedding这个参数的时候如何正确打开呢?请各路英雄详加指点,不胜感激!

解决方案 »

  1.   

    http://support.microsoft.com/kb/q160957/
      

  2.   

    谢谢,请问是用DDE的WWW_OpenURL吗?都是E文,不是很懂.如果是,linktopic应该怎样设置?设置为iexplorer|WWW_OpenURL?linkitem呢?自己的程序做DDE的客户端,那服务端呢?IE?可如果设置为自己的浏览器,IE都没机会启动呢……请继续指点,谢谢
      

  3.   

    想了一下,应该我们的程序是作为DDE服务器的,但怎么测试都不对,是用WWW_OpenURL吗?
      

  4.   

    再顶!感觉是DDE,因为外部程序会提示应用程序没有响应,但就是不知道到底发送了什么DDE
      

  5.   

    搜索了一下,其他浏览器是"接管其他程序的 DDE 调用",却不是很明白,更不知道如何实现了
      

  6.   

    -embedding :Starts the Web browser control (no home page is displayed).和参数没关系。传递路径不是通过命令行参数的。应该是通过什么回溯的方式。
    比如象WEB迅雷,快车等的“下载”和“全部下载”等功能,就可以取到所有需要的信息。
      

  7.   

    你先简单的作个DDE测试:
    FORM1,上面一个PICTURE控件picDDE
    设:
    With Me
        .LinkMode = 1: .LinkTopic = "FormDDE":  .Visible = False:  .WindowState = 1
      End With If App.PrevInstance Then ' 程序已经运行
              Me.LinkTopic = ""
              Me.LinkMode = 0   '
              Me.Caption = "MYSTART"
              LinkAndSendMessage command' 有命令行参数就传递过去
              End
     Else                     ' 程序未运行
            msgbox "no run!"
    end ifPrivate Sub LinkAndSendMessage(ByVal Msg As String)
      Dim t&
      
      picDDE.LinkMode = 0                         
      picDDE.LinkTopic = App.EXEName & "|FormDDE" 
      picDDE.LinkMode = 2                        
      picDDE.LinkExecute Msg
      
      t = picDDE.LinkTimeout
      picDDE.LinkTimeout = 1
      picDDE.LinkMode = 0
       picDDE.LinkTimeout = t
    End Sub
      

  8.   

    恩,我测试过WWW_URLEcho、WWW_OpenURL似乎都没接收到消息
    然后我子类化我的测试窗口,检测WM_DDE_INITIATE, WM_DDE_ACK, WM_DDE_POKE, WM_DDE_TERMINATE
    结果一个消息都没有!
      

  9.   

    新启动的窗口是一个activex对象,
    启动以后直接操作对象。
      

  10.   

    iget(悟不透) 说到点子上了
    程序之间的DDE本身就类似这个原理,只不过更多应用是同名程序本身.比如WMP,当我们播放着一首音乐,此时我们CLICK了硬盘或网络的一个WMA连接或文件就自动WMP播放新曲目了呢?就是DDE过去的命令,这个在注册表里可以看的一清2楚.
    再有,楼主可以自己做个带命令行的VB小程序,再去挖掘WEBBROSER中的这些问题可能更有帮助些,呵呵.我乱说说,不怪罪吧?
      

  11.   

    恩,感谢关注,谢谢。
    请看我的描述,我已经测试命令行参数了,就是-Embedding而我没办法监视webbrowser到底发送了什么DDE……
      

  12.   

    最新进展:
    我监视客户端,也就是上面描述的 测试程序1 的DDE消息,发现在点击连接的时候发送了WM_DDE_INITIATE消息。经过查询,说会向所有应用程序发送这个消息,我另外用 测试程序2 检测,发现的确如此。问题似乎可以解决了,但需要注意到,测试程序2 必须事先启动才能检测到这个消息。但是上是每次点击一个连接的时候才会启动 测试程序2 ,等这个程序启动后,已经无法接收到这个消息了……
      

  13.   

    我没时间做程序测试,只好纸上谈兵了/
    感觉你对DDE还是没有完全搞清楚:你可以带程序1中写DDE
    具体来说就是,当你CLICK了一个WEB控件连接时,记录下URL作为一个命令字符串;
    然后将这个字符串作为COMMAND传送回程序1的启动函数,比如MODUAL1的 SUB MAIN(BY VAL strCmd$).这样就可以在程序1里按照我上面的简单例子做判断执行.
      

  14.   

    不确切,应该是:将这个字符串作为COMMAND传送回程序1的启动FORM
      

  15.   

    晕,我想是楼上的没理解我的意思。说了是外部程序,我怎么能记录下URL作为一个命令字符串?
      

  16.   

    这样,如果程序1已经启动则写代码转向新URL,没有启动则启动实例直接打开新URL.
    实际上,如果你是在程序的WEB控件上点了连接,那肯定是已经开了程序1的实例,呵呵
    之所以要判断是因为,你可以在系统的[运行]窗口直接敲:程序1.exe -"http://xxx.com/yy.htm"
    If App.PrevInstance Then ' 程序已经运行
              Me.LinkTopic = ""
              Me.LinkMode = 0   '
              Me.Caption = "MYSTART"
              LinkAndSendMessage command' 有命令行参数就传递过去
              End
     Else                     ' 程序未运行
            运行程序1实例,且直接把网址传给WEB控件
    end if
      

  17.   

    兄弟,恭喜,呵呵
    DDE是个好东西,去年我写的播放器就是用DDE检测音乐连接地址的
      

  18.   

    哎,toury(理上网来) ,首先感谢你的关注。
    你想想QQ迷你网页的情况吧,要不然总是……
    这个问题需要DDE和子类结合才能解决。估计如此
      

  19.   

    接收到WM_DDE_INITIATE了,却无法应答,郁闷啊……
    http://msdn2.microsoft.com/en-us/library/ms648996.aspx
    WM_DDE_ACK应该向谁发送呢?
      

  20.   

    既然接收到了消息,那就在SUBCLASS里做循环,指向你自己的程序试一下,其实就是消息钩子
      

  21.   

    问题在于只能收到一次WM_DDE_INITIATE,我必须想办法应答外部程序,比如QQ迷你网页,QQ迷你网页才会继续发送其他消息过来。
      

  22.   

    给点参考你,没时间只大致写了下
    frmMain
    ------------------------------------------------------
    Option Explicit
    Dim WithEvents Web_V1 As SHDocVwCtl.WebBrowser_V1Private Sub Form_Load()
      Set Web_V1 = WebBrowser1.Object
      On Error Resume Next
      WebBrowser1.Navigate "http://www.sohu.com"
    End SubPrivate Sub Web_V1_NewWindow(ByVal URL As String, ByVal Flags As Long, ByVal TargetFrameName As String, PostData As Variant, ByVal Headers As String, Processed As Boolean)
      Processed = True
      Debug.Print URL, Flags, TargetFrameName, PostData, Headers
      WebBrowser1.Navigate2 URL
    End SubPrivate Sub WebBrowser1_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean)
      Dim str$, pos%
      '过滤广告页
      pos = InStr(URL, "ima")
      If pos > 0 Then Cancel = True
    End Sub
      

  23.   

    XP SP2下的IE6有了NewWindow3事件可以轻松捕获连接的URL,可惜不支持VB.
    所以只好用老旧的WebBrowser_V1来玩玩,呵呵
      

  24.   

    感谢关注,但真不知道是我笨还是你没理解我的意思.
    要是是我自己的程序里面的webbrowser,我爱怎样就怎样了.又何必如此麻烦……
    就拿QQ迷你网页来说,我能获得他的webbrowser吗?(就算用枚举能获得,当IE和QQ迷你网页以及其他使用webbrowser的程序存在的时候,你又如何知道是哪个程序的webbrowser给你发请求?)何况是点击之后才调用我的程序,这个时候该发生的事件已经发生了,又怎么可能获得URL?
    我研究出60-70%了,就是DDE配合子类。
      

  25.   

    这个问题真的很复杂
    仔细跟踪消息,发现webbrowser(也就是外部程序,比如QQ迷你网页)并没有发送什么消息,简直是悲哀。
    当我的程序建立DDECallBack后,启动的时候会向向DDEMLAnsiClient这个类发送一个WM_DDE_INITIATE消息,但DDEMLAnsiClient这个类好象是一个系统自动创建的不可见窗口。用来测试的webbrowser所在的窗口只有在DDECallBack启动后才会收到一个每个消息都一模一样的消息。根本没有任何用处。因为外部程序对DDE的处理我们是无法控制的。
    真是难啊……
      

  26.   

    我现在不得不怀疑之前的努力,的确似乎与DDE无关。我用DDESPY监视系统,设置为用遨游打开,竟然一点DDE的消息都没有!
      

  27.   

    请问楼主,你的问题是怎样解决的,我现在也碰到了这个问题,弄了几天,都没有进展,能不能告诉我是怎么样接受到URL链接地址的
      

  28.   

    试试:定义一个全局变量:dim url as StringPrivate Sub WebBrowser1_NewWindow2(ppDisp As Object, Cancel As Boolean)
        Set ppDisp = W1.Object
        ppDisp.Navigate url
    End SubPrivate Sub WebBrowser1_StatusTextChange(ByVal Text As String)
        url= Text
    End Sub
      

  29.   

    试试:定义一个全局变量:dim url as StringPrivate Sub WebBrowser1_NewWindow2(ppDisp As Object, Cancel As Boolean)
      Set ppDisp = WebBrowser1.Object
      ppDisp.Navigate url
    End SubPrivate Sub WebBrowser1_StatusTextChange(ByVal Text As String)
      url= Text
    End Sub不好意思,上帖 W1 是我的程式中的变量,没改过来。