您的位置:程序门 -> vb ->



200分:高难,神秘莫测的newwindow2!


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


200分:高难,神秘莫测的newwindow2![已结贴,结贴人:hpygzhx520]
发表于:2007-08-24 10:35:47 楼主
问题的起源:设置自己喜欢的浏览器为系统绝对默认的浏览器。
(修改.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这个参数的时候如何正确打开呢?

请各路英雄详加指点,不胜感激!

发表于:2007-08-24 12:53:561楼 得分:100
http://support.microsoft.com/kb/q160957/
发表于:2007-08-24 13:06:242楼 得分:0
谢谢,请问是用dde的www_openurl吗?都是e文,不是很懂.如果是,linktopic应该怎样设置?设置为iexplorer ¦www_openurl?linkitem呢?

自己的程序做dde的客户端,那服务端呢?ie?可如果设置为自己的浏览器,ie都没机会启动呢……

请继续指点,谢谢
发表于:2007-08-24 23:42:123楼 得分:50
不懂....蹭蹭...顺便帮顶...
发表于:2007-08-26 23:11:594楼 得分:0
想了一下,应该我们的程序是作为dde服务器的,但怎么测试都不对,是用www_openurl吗?
发表于:2007-08-27 20:38:355楼 得分:0
实在没办法了,再顶!
发表于:2007-08-28 04:50:146楼 得分:10
学习
发表于:2007-08-28 16:12:077楼 得分:0
再顶!感觉是dde,因为外部程序会提示应用程序没有响应,但就是不知道到底发送了什么dde
发表于:2007-08-28 16:55:548楼 得分:0
搜索了一下,其他浏览器是 "接管其他程序的   dde   调用 ",却不是很明白,更不知道如何实现了
发表于:2007-08-28 18:34:539楼 得分:10
-embedding   :starts   the   web   browser   control   (no   home   page   is   displayed).

和参数没关系。传递路径不是通过命令行参数的。应该是通过什么回溯的方式。
比如象web迅雷,快车等的“下载”和“全部下载”等功能,就可以取到所有需要的信息。
发表于:2007-08-28 20:10:0110楼 得分:0
感谢关注,那如何实现呢?
发表于:2007-08-28 22:40:2411楼 得分:0
你先简单的作个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   if

private   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


发表于:2007-08-28 22:52:4712楼 得分:0
恩,我测试过www_urlecho、www_openurl似乎都没接收到消息
然后我子类化我的测试窗口,检测wm_dde_initiate,   wm_dde_ack,   wm_dde_poke,   wm_dde_terminate
结果一个消息都没有!
发表于:2007-08-29 17:07:4513楼 得分:0
再顶!
发表于:2007-08-29 17:15:2314楼 得分:0
貌似要用钩子吗?
发表于:2007-08-29 20:37:5715楼 得分:0
应该不是吧,自己的程序都没启动,怎么钩呢?
发表于:2007-08-29 21:50:4616楼 得分:20
新启动的窗口是一个activex对象,
启动以后直接操作对象。
发表于:2007-08-29 22:14:2317楼 得分:0
不是很理解……,请指点。谢谢
发表于:2007-08-29 22:21:3518楼 得分:10
iget(悟不透)   说到点子上了
程序之间的dde本身就类似这个原理,只不过更多应用是同名程序本身.比如wmp,当我们播放着一首音乐,此时我们click了硬盘或网络的一个wma连接或文件就自动wmp播放新曲目了呢?就是dde过去的命令,这个在注册表里可以看的一清2楚.
再有,楼主可以自己做个带命令行的vb小程序,再去挖掘webbroser中的这些问题可能更有帮助些,呵呵.我乱说说,不怪罪吧?
发表于:2007-08-29 22:28:1719楼 得分:0
恩,感谢关注,谢谢。
请看我的描述,我已经测试命令行参数了,就是-embedding

而我没办法监视webbrowser到底发送了什么dde……
发表于:2007-08-30 17:49:3720楼 得分:0
最新进展:
我监视客户端,也就是上面描述的   测试程序1   的dde消息,发现在点击连接的时候发送了wm_dde_initiate消息。经过查询,说会向所有应用程序发送这个消息,我另外用   测试程序2   检测,发现的确如此。问题似乎可以解决了,但需要注意到,测试程序2   必须事先启动才能检测到这个消息。但是上是每次点击一个连接的时候才会启动   测试程序2   ,等这个程序启动后,已经无法接收到这个消息了……
发表于:2007-08-30 19:27:0621楼 得分:0
我没时间做程序测试,只好纸上谈兵了/
感觉你对dde还是没有完全搞清楚:你可以带程序1中写dde
具体来说就是,当你click了一个web控件连接时,记录下url作为一个命令字符串;
然后将这个字符串作为command传送回程序1的启动函数,比如modual1的   sub   main(by   val   strcmd$).这样就可以在程序1里按照我上面的简单例子做判断执行.
发表于:2007-08-30 19:28:5322楼 得分:0
不确切,应该是:将这个字符串作为command传送回程序1的启动form
发表于:2007-08-30 19:32:0423楼 得分:0
晕,我想是楼上的没理解我的意思。说了是外部程序,我怎么能记录下url作为一个命令字符串?
发表于:2007-08-30 19:34:4224楼 得分:0
这样,如果程序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
发表于:2007-08-30 19:37:0925楼 得分:0
外部程序道理一样,程序1把命令记录下来了一切就ok了呀,呵呵
你可以用代码启动程序2(带命令)........
发表于:2007-08-30 19:43:4426楼 得分:0
消息能检测了,现在又进了一步.开心……
发表于:2007-08-30 19:45:2727楼 得分:0
兄弟,恭喜,呵呵
dde是个好东西,去年我写的播放器就是用dde检测音乐连接地址的
发表于:2007-08-30 19:46:1428楼 得分:0
哎,toury(理上网来)   ,首先感谢你的关注。
你想想qq迷你网页的情况吧,要不然总是……
这个问题需要dde和子类结合才能解决。估计如此
发表于:2007-08-30 19:48:3329楼 得分:0
差不多.
现在手里有项目,不然仔细研究一下,呵呵
祝你成功
发表于:2007-08-30 22:45:3330楼 得分:0
接收到wm_dde_initiate了,却无法应答,郁闷啊……
http://msdn2.microsoft.com/en-us/library/ms648996.aspx
wm_dde_ack应该向谁发送呢?
发表于:2007-08-30 22:54:2631楼 得分:0
既然接收到了消息,那就在subclass里做循环,指向你自己的程序试一下,其实就是消息钩子
发表于:2007-08-30 23:27:0532楼 得分:0
问题在于只能收到一次wm_dde_initiate,我必须想办法应答外部程序,比如qq迷你网页,qq迷你网页才会继续发送其他消息过来。
发表于:2007-08-31 02:58:5833楼 得分:0
给点参考你,没时间只大致写了下
frmmain
------------------------------------------------------
option   explicit
dim   withevents   web_v1   as   shdocvwctl.webbrowser_v1

private   sub   form_load()
    set   web_v1   =   webbrowser1.object
    on   error   resume   next
    webbrowser1.navigate   "http://www.sohu.com "
end   sub

private   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   sub

private   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

发表于:2007-08-31 03:06:1534楼 得分:0
xp   sp2下的ie6有了newwindow3事件可以轻松捕获连接的url,可惜不支持vb.
所以只好用老旧的webbrowser_v1来玩玩,呵呵
发表于:2007-08-31 22:36:2835楼 得分:0
感谢关注,但真不知道是我笨还是你没理解我的意思.
要是是我自己的程序里面的webbrowser,我爱怎样就怎样了.又何必如此麻烦……
就拿qq迷你网页来说,我能获得他的webbrowser吗?(就算用枚举能获得,当ie和qq迷你网页以及其他使用webbrowser的程序存在的时候,你又如何知道是哪个程序的webbrowser给你发请求?)何况是点击之后才调用我的程序,这个时候该发生的事件已经发生了,又怎么可能获得url?
我研究出60-70%了,就是dde配合子类。
发表于:2007-09-02 10:53:3136楼 得分:0
这个问题真的很复杂
仔细跟踪消息,发现webbrowser(也就是外部程序,比如qq迷你网页)并没有发送什么消息,简直是悲哀。
当我的程序建立ddecallback后,启动的时候会向向ddemlansiclient这个类发送一个wm_dde_initiate消息,但ddemlansiclient这个类好象是一个系统自动创建的不可见窗口。用来测试的webbrowser所在的窗口只有在ddecallback启动后才会收到一个每个消息都一模一样的消息。根本没有任何用处。因为外部程序对dde的处理我们是无法控制的。
真是难啊……
发表于:2007-09-05 17:31:1337楼 得分:0
高手们呢?帮帮忙啊……
谢谢
发表于:2007-09-05 18:12:5438楼 得分:0
不懂,頂一下
发表于:2007-09-06 11:44:5239楼 得分:0
我现在不得不怀疑之前的努力,的确似乎与dde无关。我用ddespy监视系统,设置为用遨游打开,竟然一点dde的消息都没有!


快速检索

最新资讯
热门点击