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

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -