现在的位置: 首页 > 综合 > 正文

关于PB使用IE组件的问题

2012年03月04日 ⁄ 综合 ⁄ 共 6516字 ⁄ 字号 评论关闭

我用pb10,IE的ole控件做了个嵌入式浏览器,
在其中执行一些比较简单的URL调用(使用navigator2函数),以及页面解析。
此ole控件是在窗口上的,我发觉有一下一些问题:
1.窗口关闭后,内存并不释放,造成打开一个页面后,就要耗费50m左右的内存
2.在ole组件中多次调用navigator2函数打开新的页面,内存耗费不断加大,20个调用循环,内存耗费超过100m,估计是有多页的缓存在其中,该如何清除?
3.在循环中对ole组件调用navigator2函数,循环结束后,程序无故会终止,提示为:
aa.exe程序产生错误,会被windows关闭,您需要重新启动程序,正在创建错误日志。
单层的for next循环不会出措。

----------------------------------------------------------------------

不懂  顶楼主热心人

--------------------------------------------------------

帮你UP

--------------------------------------------------------

我以前做过简单的程序,好象没有这个问题,你试试用其它版本的PB,如pb804,pb903等。 另外试试不要用数组,我以前实验过,pb不能释放数组申请的内存,除非你关闭整个程序, 你可以建一个userobject, 用openuserobject()来打开,关闭的时候用colseuserobject().
要想遍历就用control[]属性

--------------------------------------------------------

楼主我有个问题啊,如果用这个控件打开一个网页,如何判断这个网页是否打开成功,比如 404,400等错误,如何能得到哪?谢谢

--------------------------------------------------------

顶一下
回楼上,可能通过ole控件有个什么navigatecomplete2事件,你在那里写代码试试看;
但是页面是否被完全载入我也没有办法获取到。

--------------------------------------------------------

to lzheng2001(1加1):
谢谢!
其实网页里边的collection元素基本上都是数组,不知道是不是这个原因,
不过你说的用openuserobject的方式倒可试试看。

--------------------------------------------------------

有个办法可以使程序不关闭了,不要在应用的open事件中操作ole控件,在应用打开后,
其他地方来调用,可以延迟出错的时间,
不过最终在应用关闭的时候,还是会出错的。
怪哉。

--------------------------------------------------------

把你的代码贴出来看看

--------------------------------------------------------

主要是我在应用open事件中调用了一个timer对象的一个事件,这个事件和timer对象的timer事件的代码是基本一样的:
event timer2()

if of_checkonline()=-1 then return           //检测是否连接上internet

this.stop()
popmsg('水区Timer2')
w_main.of_csdn_extcheck(ids,defaultwait)        //defaultwait 为等待时间 ids是datastore
popmsg('close')
this.start(gi_csdn_extcheck)

--------------------------------------------------------

主体代码在w_main.of_csdn_extcheck()

string ls_url,ls_null,ls_tables,ls_href,ls_status
long li,lj,li_row,ll,lk,li_rtn,li_count,li_find
oleobject tables,table,rows,items
any la_tables
uo_ielu_ie1,lu_ie2,lu_ie3

setnull(ls_null)
//navigator
popmsg('读取主页面...')
openuserobject(lu_ie1)
ls_url="http://community.csdn.net/Expert/ForumsList.asp?typenum=1&roomid=14"
lu_ie1.ole_ie.object.navigate2(ls_url,0,ls_null,ls_null,'')

//wait for wait seconds
wait(ai_wait)

//split
try
tables=lu_ie1.ole_ie.object.Document.body.getElementsByTagName("table")
catch (nullobjecterror nullerr)
popmsg2(nullerr.getmessage())
closeuserobject(lu_ie1)
return -1
catch (oleruntimeerror oleerr)
popmsg2(oleerr.getmessage())
closeuserobject(lu_ie1)
return -1
end try

//把新问题设置为旧问题
for lk=1 to ads_ds.rowcount()
ls_status=ads_ds.getitemstring(lk,'Status')
if ls_status='0' then
ads_ds.setitem(lk,'Status','1')
end if
next
popmsg('分析主页面...')
for li=1 to tables.length
rows=tables.item[li -1].rows
for lj=1 to rows.length
items=rows.item[lj -1]
if integer(items.cells.length)<>6 then continue
if trim(string(items.innerText))='问 题用户名分数回复时间功能' then continue

//排除已经收录的问题
ls_href = string(items.cells[0].children(1).href)
select count(*)
 into :li_count
 from Questiones
 where HRef = :ls_href
 ;
 if sqlca.sqlcode = -1 then
popmsg2(sqlca.sqlerrtext)
closeuserobject(lu_ie1)
return -1
end if
if li_count>0 then exit

//??为什么有时候出现解析出两个相同的连接?csdn的问题?
li_find=ads_ds.find("href='"+ls_href+"'",1,ads_ds.rowcount())
if li_find>0 then exit

//插入新问题
li_row=ads_ds.insertrow(0)
ads_ds.setitem(li_row,'pout',"扩充话题")
ads_ds.setitem(li_row,'question',string(items.cells[0].innertext))
ads_ds.setitem(li_row,'userid',string(items.cells[1].innertext))
ads_ds.setitem(li_row,'credit',integer(items.cells[2].innertext))
ads_ds.setitem(li_row,'response',integer(items.cells[3].innertext))
ads_ds.setitem(li_row,'qtime',string(items.cells[4].innertext))
ads_ds.setitem(li_row,'href',string(items.cells[0].children(1).href))
next
next

//保存修改
li_rtn=ads_ds.update()
if li_rtn=-1 then
rollback;
closeuserobject(lu_ie1)
return -1
else
commit;
end if

//重新排序
ads_ds.sort()

//hide or show
w_csdn_qcheck.of_hide()

//自动回复
oleobject iframes,textareas
string frname,frsrc,temp,ls_value
popmsg('回复处理...')

try
for lk=1 to ads_ds.rowcount()
ls_href = ads_ds.getitemstring(lk,'href')
openuserobject(lu_ie2)
lu_ie2.ole_ie.object.navigate2(ls_href,0,ls_null,ls_null,'')
//wait
wait(ai_wait)
//查找Frame
iframes=lu_ie2.ole_ie.object.Document.body.getElementsByTagName("IFRAME")

//分析
for li=iframes.length to 1 step -1
frname=string(iframes.item[li -1].name)
if frname='XmlReply' then
frsrc = string(iframes.item[li -1].src)
frsrc = trim(frsrc)
exit
end if
next

//查找Form
openuserobject(lu_ie3)
lu_ie3.ole_ie.object.navigate2(gs_csdncomm+frsrc,0,ls_null,ls_null,'')
//wait
wait(ai_wait)
//回复
popmsg('回复处理...'+string(lk)+'/'+string(ads_ds.rowcount()))
textareas =lu_ie3.ole_ie.object.Document.getElementsByName("ReplyContent")
if autoanswer(ls_value)=-1 then
closeuserobject(lu_ie1)
closeuserobject(lu_ie2)
closeuserobject(lu_ie3)
return -1
end if
textareas.item[0].value=ls_value

//提交回复
lu_ie3.ole_ie.object.Document.XmlRePly.submit()

//转移问题
update Questiones
set Status = '2',
 Status2 = '1'
where HRef = :ls_href
;
if sqlca.sqlcode = -1 then
rollback;
msg(sqlca.sqlerrtext)
closeuserobject(lu_ie1)
closeuserobject(lu_ie2)
closeuserobject(lu_ie3)
return -1
end if
commit;
closeuserobject(lu_ie2)
closeuserobject(lu_ie3)
next
catch (nullobjecterror nullerr2)
popmsg2(nullerr2.getmessage())
closeuserobject(lu_ie1)
closeuserobject(lu_ie2)
closeuserobject(lu_ie3)
return -1
catch (oleruntimeerror oleerr2)
popmsg2(oleerr2.getmessage())
closeuserobject(lu_ie1)
closeuserobject(lu_ie2)
closeuserobject(lu_ie3)
return -1
end try

//重新检索
ads_ds.retrieve()
if isvalid(w_csdn_qcheck ) then w_csdn_qcheck.of_hide()
closeuserobject(lu_ie1)
return 1

--------------------------------------------------------

我有时间试试.
楼主现在内存问题是否解决了?  只剩下非法关闭的问题吗?

--------------------------------------------------------

用了openuserobject后,好像内存问题稍微好一点了,不过随着多次调用timer事件,内存还是会不断增加,从8:40到10:00内存占用到了90m,虚拟内存250m。
一般第一次timer事件的时候,内存占用在50m左右,虚拟内存40m左右。

非法关闭问题还在,只是在系统关闭的时候才会出现,对系统运行倒没有什么影响了,其实我就是把应用的open事件中调用timer去掉了而已。

晕哦。

--------------------------------------------------------

如果打开页面数多,内存占用肯定越大, 当然如果关闭了,理论上应该要释放掉页面占用的内存, 你可以定时调用GarbageCollect ( )看是否有帮助.

我可以用vb测试一下与pb比较看看是哪里的问题

--------------------------------------------------------

好的,谢谢!

--------------------------------------------------------

确认了GarbageCollect ( )没有效果,定时调用还会造成应用无响应。手工调用也没有效果。

--------------------------------------------------------

今天用pb804测试了一下,内存没有问题!
我用一个webbrowser控件,浏览了10几个网页,内存可以自动回收,没有发现问题!

--------------------------------------------------------

是吗,难道是pb10的问题,不应该吧。
那就结贴吧

--------------------------------------------------------

不管了!新建一个应用,用了pb8和pb10都试过了,最简单的打开一个窗口,然后打开一个网页,关闭窗口后内存都无法回收。

--------------------------------------------------------

不会的! 我用pb804,楼主难道敢用PB而不打补丁! 不要开玩笑了.

--------------------------------------------------------

我用的8.0.3 9704 

抱歉!评论已关闭.