Delphi Xe - Thread and WebBrowser get source rersults in AV -
i want create thread monitors webbrowser check if text appears in page source. have multiple webbrowsers on form, i've made sscce 1 webbrowser (the av still present).
i made timer waits 10 seconds after document loaded , created thread on timer event (to make sure document completed), seems not problem. av present whether document loaded or not. timer not present in example below. i've made step-by-step execution , av occurs comment iall.outerhtml
. iall seems contain right stuff, calling outerhtml results av.
can find error?
the unit source code below:
unit unit1; interface uses winapi.windows, winapi.messages, system.sysutils, system.variants, system.classes, vcl.graphics, vcl.controls, vcl.forms, vcl.dialogs, vcl.olectrls, shdocvw, activex, strutils, mshtml, vcl.stdctrls; type twebbrowser = class(shdocvw.twebbrowser, iolecommandtarget) curdispatch: idispatch; private tfdocloaded: boolean; tfedaddress: string; function querystatus(cmdgroup: pguid; ccmds: cardinal; prgcmds: polecmd; cmdtext: polecmdtext): hresult; stdcall; function exec(cmdgroup: pguid; ncmdid, ncmdexecopt: dword; const vain: olevariant; var vaout: olevariant): hresult; stdcall; published property fdocloaded: boolean read tfdocloaded write tfdocloaded; property fedaddress: string read tfedaddress write tfedaddress; end; tform1 = class; twatcherthread = class(tthread) private thbrowser: tform1; protected procedure execute; override; public constructor create(abrowser: tform1); end; tform1 = class(tform) webbrowser1: twebbrowser; label1: tlabel; procedure formcreate(sender: tobject); procedure webbrowser1navigatecomplete2(asender: tobject; const pdisp: idispatch; const url: olevariant); private { private declarations } mywatcher: twatcherthread; function checkifthereis(awebbrowser: twebbrowser): boolean; function getwebbrowserhtml(const abrowser: twebbrowser): string; public { public declarations } end; var form1: tform1; implementation {$r *.dfm} function twebbrowser.querystatus(cmdgroup: pguid; ccmds: cardinal; prgcmds: polecmd; cmdtext: polecmdtext): hresult; stdcall; begin result := s_ok; end; function twebbrowser.exec(cmdgroup: pguid; ncmdid, ncmdexecopt: dword; const vain: olevariant; var vaout: olevariant): hresult; stdcall; begin result := s_ok; if ncmdid = olecmdid_showscripterror result := s_ok; end; function tform1.checkifthereis(awebbrowser: twebbrowser): boolean; var src: string; begin result := false; try src := getwebbrowserhtml(awebbrowser); if posex('<span>mail</span>', src) > 0 result := true; except on e : exception result := false; end; end; function tform1.getwebbrowserhtml(const abrowser: twebbrowser): string; var iall: ihtmlelement; begin result := ''; try if not assigned(abrowser.document) exit; if (abrowser.document ihtmldocument2).body <> nil begin iall := (abrowser.document ihtmldocument2).body; while iall.parentelement <> nil iall := iall.parentelement; result := iall.outerhtml; // <- here av after doc loaded end; except on e : exception // end; end; procedure tform1.webbrowser1navigatecomplete2(asender: tobject; const pdisp: idispatch; const url: olevariant); var wb: twebbrowser; begin wb := twebbrowser(asender); if wb.curdispatch = nil wb.curdispatch := pdisp; wb.fdocloaded := true; end; procedure tform1.formcreate(sender: tobject); begin webbrowser1.navigate('www.yahoo.com'); mywatcher := twatcherthread.create(self); mywatcher begin freeonterminate := true; resume; end; end; constructor twatcherthread.create(abrowser: tform1); begin thbrowser := abrowser; inherited create(true); end; procedure twatcherthread.execute; var i: integer; pt: twebbrowser; begin inherited; repeat //parsing list of existing webbrowsers -> each following begin/end section begin if thbrowser.webbrowser1.fdocloaded = true if thbrowser.checkifthereis(thbrowser.webbrowser1) // must called way (passing webbrowser class function) because in original have more 1 webbrowsers begin thbrowser.label1.caption := 'there is!'; break; end; end; sleep(1000); until terminated; end; end.
you breaking vcl threading rules. access vcl controls must made main thread.
you breaking com threading rules calling methods of com web browser objects off thread created them.
it seems me thread serves no purpose here , should work in navigatecomplete2
.
i wonder whether or not visual component correct choice here. need display these web pages, or crawling?
Comments
Post a Comment