2012-04-18 21 views
5

Ho un modulo che ha un componente TWebBrower che carica un documento HTML. I dati relativi al documento HTML viene aggiornata ogni pochi secondi, a volte più volte al secondo e aggiornare il valore in Delphi usando:Ottimizza la colorazione di TWebBrowser per ridurre l'utilizzo totale della CPU

DOMDocument.getElementById(elementID).innerHTML := someValue; 

Il problema è che voglio bloccare la finestra/browser web per evitare che la pittura/aggiornamento fino a quando tutti i miei aggiornamenti sono completi. C'è un modo per fare questo? Sarebbe una chiamata a

SendMessage(WebBrowser.Handle,WM_SETREDRAW,0,0); 

vorrei qualche aiuto per ottimizzare il codice in modo che il mio utilizzo totale della CPU non è continuamente alta.

+0

L'interfaccia 'IViewObject' ha le funzioni' Freeze' e 'UnFreeze' che potrebbero essere utili per questo. Proverò a preparare un esempio. – TLama

+0

Penso che abbiamo bisogno di vedere il codice reale qui (incluso l'HTML). 'WM_SETREDRAW' funziona davvero (in un test molto limitato che ho fatto). ma dal momento che 'innerHTML' funziona in modo asincrono, penso che sarebbe un problema sincronizzarlo ... – kobik

+0

@kobik, ma se si dice che' innerHTML' è asincrono allora temo che anche 'IViewObject' non sia d'aiuto. Dovrebbe essere un po 'di controllo per lo stato pronto. – TLama

risposta

4

Poiché il problema principale è la frequenza di aggiornamento, è necessario ridurlo. Per questo è possibile semplicemente archiviare l'ultima volta che si è aggiornato il documento HTML e alla successiva modifica dei dati controllare se è trascorso un determinato periodo da quel momento.

Ecco il codice che mostra come eseguire questa operazione. Lo FUpdatePeriod nell'esempio seguente è il periodo di aggiornamento in millisecondi. Quindi se si chiama periodicamente lo UpdateChanges, lo innerHTML (pseudo-codice qui) verrà aggiornato solo quando sono trascorsi almeno 1000 ms dall'ultima modifica.

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls, MSHTML, OleCtrls, SHDocVw; 

type 
    TForm1 = class(TForm) 
    WebBrowser1: TWebBrowser; 
    procedure FormCreate(Sender: TObject); 
    private 
    FLastUpdate: Cardinal; 
    FUpdatePeriod: Cardinal; 
    procedure UpdateChanges(const AData: WideString); 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    FUpdatePeriod := 1000; 
end; 

procedure TForm1.UpdateChanges(const AData: WideString); 
begin 
    if (GetTickCount - FLastUpdate > FUpdatePeriod) then 
    begin 
    (WebBrowser1.Document as IHTMLDocument2).body.innerHTML := AData; 
    FLastUpdate := GetTickCount; 
    end; 
end; 

// now remains to call the UpdateChanges periodically 

end. 
+0

grazie per questa soluzione. –

1

Questa è una risposta laterale; Ma quando abbiamo avuto problemi di sfarfallio con TWebBrowser, li abbiamo sistemati passando all'utilizzo di Google Chrome (DCEF) embedded nella nostra applicazione.

Anche se originariamente pensavo di poter "ottimizzare" TWebBrowser e ridurre il suo sfarfallio, ho scoperto che il problema è solo nativo di Internet Explorer. Oltre all'installazione di una nuova versione di Internet Explorer, o alla riscrittura di tutti i JavaScript, la pagina Web non sfarfalla mai, perché non ha elementi attivi nel layout HTML (100% javascript gratuito = nessun sfarfallio) l'unica soluzione è smettere di usare Internet Explorer e quindi smetti di usare TWebbrowser.

In secondo luogo, lo sfarfallio può anche essere causato se la pagina Web TWebBrowser accede ai metodi nativi di Delphi come richiami dal javascript. Questi callback, se impiegano molto tempo, causano sempre uno sfarfallio nel TWebBrowser incorporato, anche se l'unico javascript che viene eseguito è l'invocazione del callback delphi. La tecnica di cui sto parlando (callback) è documentata here.

+0

P, la mia domanda potrebbe essere un po 'vaga. Non ho problemi di sfarfallio, la mia più grande preoccupazione è che il browser web assorba molta potenza della cpu quando chiamo innerHTML e vorrei terminare tutte le chiamate a innerHTML prima di dipingerlo. grazie –

+0

considererò l'utilizzo di google chrome e vedrò se ci sarà un miglioramento. grazie –

+1

Ho intenzione di modificare la tua domanda allora. Non dovresti fare una domanda su X quando intendi veramente Y. :-) –