🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.internet.web
Article #250

Re: TCPPWebBrowser SLOW for a certain time of day

#250
From: Eduardo Jauch
Date: Tue, 06 Feb 2007 18:51
473 lines
13902 bytes
Hans Galema escreveu:
> So TCppWebBRowser is slow, IE is slow and Firefox is fast.

   Well... I think so.
> 
>> Was not my code I think, but anyway, I do this:
> 
>> void TjanelaPrincipal::CarregarFrame(WideString url)
>> {
>>   TVariant FrameName( "iContent" );
>>
>>   paginaCarregada = false;
>>   Browser->Navigate( url, TNoParam(), &FrameName );
>>
>>   while( !paginaCarregada )
>>   {
>>     Application->ProcessMessages();
>>   }
>> }
> 
> Is that code that loads a htmppage in one of the frames of an existing
> page? Why didn't you tell?
> 

Yes. I don't know.

> What is the use of paginaCarregada ? I think you can omit it all the way.
> 
> And at least the loop with  Application->ProcessMessages(); looks not 
> needed.

Without this, the OnDocumentComplete NEVER is fired... Because the 
message NEVER come to my program (I tried...)

And if I don't use the looping, my code continues after "browse" the 
page, and i get all wrong simple because the page is not yet completed 
downloaded.

By the way, the code with the CurDispatch, i get on the BCB 6 help.

>
>> void __fastcall TjanelaPrincipal::BrowserNavigateComplete2(TObject 
>> *Sender,
>>       LPDISPATCH pDisp, Variant *URL)
>> {
>>   if (!CurDispatch)
>>     CurDispatch = pDisp;
>> }
> 
> You did explain nothing of CurDispath? What is it? Where did you assign it?
> Why this code?
>

Ok. paginaCarregada and CurDispatch are global variables.
Because the page have frames, i use CurDispatch to hold the pDisp value 
guve by OnNavigateComplete2.

The OnNavigateComplete2 can occour before the entire page is loaded.

> 
>> void __fastcall TjanelaPrincipal::BrowserDocumentComplete(TObject 
>> *Sender,
>>       LPDISPATCH pDisp, Variant *URL)
>> {
>>   if (pDisp == CurDispatch)
>>   {
>>     CurDispatch = NULL;
>>
>>     FrameDoc = Frame( WideString("iContent") );
> 
> You did not explain the function Frame().

Function Frame:

IHTMLDocument2 * TjanelaPrincipal::Frame(WideString nome)
{
   if( !Browser->Document ) return NULL;

   IHTMLDocument2 *Doc = NULL;
   Browser->Document->QueryInterface( IID_IHTMLDocument2,(LPVOID*)&Doc );

   if( !Doc ) return NULL;

   IHTMLFramesCollection2 *Frames;
   Doc->get_frames(&Frames);
   Doc->Release();

   if( !Frames ) return NULL;

   TVariant IndexOrName = nome;
   TVariant Frame_;
   Frames->item(&IndexOrName, &Frame_);
   Frames->Release();

   IHTMLDocument2 *FrameDoc;

   if( (V_VT(&Frame_) == VT_DISPATCH) && (V_DISPATCH(&Frame_) != NULL) )
   {
     IHTMLWindow2 *Window;
     V_DISPATCH(&Frame_)->QueryInterface(IID_IHTMLWindow2,(LPVOID*)&Window);

     if( !Window ) return NULL;

     Window->get_document(&FrameDoc);
     Window->Release();
   }
   else
     return NULL;

   return FrameDoc;
}

This functions return the IGTMLDocument2 of the Frame given the name of 
the frame.

>>
>>     if( FrameDoc )
>>       FrameDoc->get_all( &All );
>>     else
>>     {
>>       ShowMessage("ERRO!!! \'Frame\' n�o encontrado!");
> 
> You are making a return without
> 
>     paginaCarregada = true;
> 
>>       return;
>>     }
>>
>>     if( !All )
>>     {
>>       FrameDoc->Release();
>>       ShowMessage("ERRO!!! \'All\' n�o encontrado!");
> 
> You are making a return without
> 
>     paginaCarregada = true;
> 
>>       return;
>>     }
>>
>>     paginaCarregada = true;
>>   }
>>   else
>>   {
>>     paginaCarregada = false;
>>   }
>> }
>>

For the these two coments, the only ansewr that i can give is that I 
don't implemented code for error yet. So, if there a error when loading 
FrameDoc or All, I show a message and restart the program...
It's very crude, but I'm in "testing" only.

>>
>> Any better ideas to do this?
> 
> Well you never told what you wanted to happen, nor explained the
> start of the scenario.


Well... I load a page. Then, I find it's frame named 'iContent' and it 
itens collection (All)

I do this ONLY if the page is complete loaded. I will explain why soon... ;)

Then, i start to load the frames that are loaded normally by clicking on 
some link, In this page, there are a flash menu that does it, until i 
load the page that contains the login info.

I load the info and continue, until get a specific page (It's necessary 
enter a certain amount of data on forms before came to this specific 
page. When i do this, i start a loop:

   IHTMLInputElement *pInput;
   int situacao;

   do
   {
/*
   The first for, set check on all the check box on the actual page
*/
     for( int i = 0; i < requerentes->Count; i++ )
     {
       pInput = InputElement( "requerenteAgendado[" + IntToStr(i) + 
"].informacoesChecadas" );
       if( !pInput )
       {
         ShowMessage( "ERRO. Verifique a p�gina." );
         iniciar_bt->Enabled = true;
         return;
       }

       pInput->put_status(1);
       pInput->Release();
     }

//Goes to the next page
     CarregarFrame( "javascript: forwardCalendario()" );

//Agendamento is the function I posted before
     situacao = Agendamento();

     switch( situacao )
     {
       case -1:
         ShowMessage( "ERRO. Verifique a p�gina." );
         iniciar_bt->Enabled = true;
         break;
       case 1:
         ShowMessage( "AGENDADO!!!!!!" );
         break;
       case 0:
         CarregarFrame( "javascript: confirmarInformacoesDeVisto()" );
         break;
     }
   }while( situacao == 0 );

Before you ask, pInputElement, pSelectElement, pOptionElement are 
functions to retrieve the 'IHTMLInputElement *', and 'IHTMLSelectElement 
*', 'IHTMLOptionElement *' given the name of the element. You can see 
then on the Agendamento function too.


> 
>> I cannot put my code direct in BrowserDocumentComplete, for various 
>> reasons....
> 
> Should we guess?

Oh, no! I can tell :)
Only did not think was necessary...
Anyway, if you look at Agendamento function again, you will notice that 
I have a looping, within a looping within a looping...
My English is not so good, but what I mean is something like this:

for(...)
{
   for(...)
   {
     for(...)
     {
     }
   }
}

Each of the for are for looping through one combo box 
(IHTMLSelectElement) on the page. When i find the element I need on the 
first select, I call the javascript associated with the select and go to 
the next for.

This deletes all of the elements, because theses javascripts load 
another page.

I created meses and datas (two classes) to hold all the elements of the 
first select (meses) and second select (datas)

This is make by calling the member function "datas.AdicionarData"
When i do that, internally, the object set what the elements are good 
for me. Can get more than one, and this is important.

I'll explain Agendamento now:

//-------------------------------
//Get the first select (combo)
   pSelect = SelectElement("mesDisponivel");
//Get the number of itens on the select
   pSelect->get_length( &pItens );

//looping to get all the itens and pass to meses class
   for( i = 1; i < pItens; i++ )
   {
     pOption = OptionElement( pSelect, i );

     if( !pOption ) return -1;

     pOption->get_text( &opcao );
     pOption->Release();

     meses.AdicionarData( opcao );
     info_mm->Lines->Add( "M�S: " + AnsiString(opcao) );
   }
   pSelect->Release();

//-------------------------------


//Looping to get the elements returned by the meses class

   int prxMes;
   int prxData;
//meses.MesesAptos -> Number of itens on first select that are good
   for( m = 0; m < meses.MesesAptos; m++ )
   {
     //get the first select (combo).
     //Do this, because whe find one element good, will call javascript
     //and the variable will be reseted automatically by TCppWebBrowser

     pSelect = SelectElement( "mesDisponivel" );
     if( !pSelect ) return -1;

     //get the NEXT good item
     prxMes = meses.IndiceProximaData;
     if( prxMes == -1 ) return 0;

     //select the item on the first combo (select)
     pSelect->put_selectedIndex( prxMes );
     pSelect->Release();

     //reset the datas class (does this for every item on the first
     //combo)
     datas.Reiniciar();

     //call a javascript that refresh the pages, putting the values on
     //the second combo.
     CarregarFrame( "javascript: popularListaDiasDisponiveis()" );


     //do the same before, but to datas and with second combo)
     pSelect = SelectElement( "diaDisponivel" );
     if( !pSelect ) return -1;

     pSelect->get_length(&pItens);
     for(i = 1; i < pItens; i++)
     {
       pOption = OptionElement( pSelect, i );

       if( !pOption ) return -1;

       pOption->get_text( &opcao );
       pOption->Release();

       datas.AdicionarData( opcao ); //save the date
       info_mm->Lines->Add( "  Data: " + AnsiString(opcao) );
     }
     pSelect->Release();

     //Now, find the good itens on second combo
     for( d = 0; d < datas.DatasAptas; d++)
     {
       pSelect = SelectElement( "diaDisponivel" );
       if( !pSelect ) return -1;

       prxData = datas.IndiceProximaData;
       if( prxData == -1 ) break;

       pSelect->put_selectedIndex( prxData );
       pSelect->Release();

       //Load the javascript that refresh the page, loadind elements on
       //the third combo
       CarregarFrame( "javascript: popularListaHorariosDisponiveis()" );

       pSelect = SelectElement( "seqHorarioAgendamentoDisponivel" );
       if( !pSelect ) return false;

       pSelect->get_length( &pItens );

       for( i = 1; i < pItens; i++ )
       {
         pOption = OptionElement( pSelect, i );
         if( !pOption ) break;

         pOption->get_text(&opcao);
         pOption->Release();

         if(opcao.Length() == 38)
           qtde = opcao.SubString(28, 2);
         else
           qtde = opcao.SubString(28, 1);

         qtde_n = qtde.ToInt();

         //requerents are other class i create to control.
         //have information i use to fill the forms that I said before
         if(qtde_n >= requerentes->Count)
         {
           pSelect->put_selectedIndex(i);

           //if find a good item on the third combo, execute this java
           CarregarFrame( "javascript: confirmarAgendamento()" );

           //If the page is the same, then the item don't work,
           pSelect = SelectElement( "seqHorarioAgendamentoDisponivel" );
           if( pSelect )
           {
             i = 1;
             //set i to 1, because if  item has already "taken", it 
//desapears of the list and i must begin again.
           }
           else
           {
             return 1; //Conseguiu AGENDAR
           }
         }
       }
       //if no able to kake a good item on the third combo,
       //try the next on the second combo

       pSelect->Release();
     }
     //if no able to kake a good item on the second combo,
     //try the next on the first combo

   }

   return 0; //Acabou a lista

}


So, if i try to use the OnDocumentComplete to do somethink like this, 
the things will go on very Difficult... Because I will call it within it.
I tried.

>> One is that I use this code:
>>
>> int TjanelaPrincipal::Agendamento(void)
> 
> You did not tell where/when you call that function
See above

> 
>> {
>>   IDispatch *pDisp;
>>   IHTMLInputElement *pInput;
>>   IHTMLSelectElement *pSelect;
>>   IHTMLOptionElement *pOption;
>>   TAGIntervalo *pIntervalo;
>>   WideString opcao;
>>   AnsiString qtde;
>>   long pItens;
>>   int i, m, d, h, qtde_n;
> 
> That looks like C programming. Why not declare the variables at the
> moment where you first use them?

Because I are an old C programing and like to do this way. Old habits...
> 
>>   meses.Reiniciar();
>>   datas.Reiniciar();
> 
> We do not see what that code does.

   For not create and recreate these class every time i enter the 
Agendamento function, i create this member function that reset the data 
on them.

> 
>>   pSelect = SelectElement("mesDisponivel");
> 
> You did not explain that function nor the rest of the code.

See above.

> 
>> Any ideas???
> 
> You would be better off if you managed to produce a htmlpage
> that you could put on the internet and that we could use too.
> 
> Hans.

I can't do this, because the page has lots of javasript that i not 
understand yet...

I'm trying to use NMHTTP (or Indy10 when I get to install sucessfuly it)
But for now, the program works... For litle periods... ;)

The code, on the way i put here, works.
But during the day, most of time, it's impossible to work... Because the 
pages are loaded so slowly...
Technical Details
Message-ID: <45c8cacb@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news2.google.com!news3.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
References: <45c8ad84@newsgroups.borland.com> <45c8b4ee@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: feeec,19ca628026a7cd6e
X-Google-Attributes: gidfeeec,public
X-Google-Language: ENGLISH,ASCII
Date: Tue, 06 Feb 2007 16:51:58 -0200
From: Eduardo Jauch <eduardo.jauch@gmail.com>
User-Agent: Thunderbird 1.5.0.9 (Windows/20061207)
MIME-Version: 1.0
Newsgroups: borland.public.cppbuilder.internet.web
Subject: Re: TCPPWebBrowser SLOW for a certain time of day
References: <45c8ad84@newsgroups.borland.com> <45c8b4ee@newsgroups.borland.com>
In-Reply-To: <45c8b4ee@newsgroups.borland.com>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit
NNTP-Posting-Host: 201.24.228.186
Message-ID: <45c8cacb@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1170787019 201.24.228.186 (6 Feb 2007 10:36:59 -0800)
Lines: 473
Path: arc1-ca.pugleaf.net!g2news2.google.com!news3.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail