2012-04-18 10 views
5

Ich habe ein Formular mit einer TWebBrower Komponente, die ein HTML-Dokument lädt. Die Daten auf dem HTML-Dokument wird alle paar Sekunden aktualisiert, manchmal mehrmals pro Sekunde und ich den Wert in Delphi aktualisieren mit:Optimieren Sie das Malen von TWebBrowser, um die CPU-Gesamtnutzung zu reduzieren

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

Das Problem ist, ich das Fenster/Web-Browser sperren wollen, es zu verhindern, dass von der Malerei/Aktualisierung, bis alle meine Updates abgeschlossen sind. Gibt es eine Möglichkeit, dies zu tun? Wäre ein Anruf an

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

Ich möchte etwas Hilfe bei der Optimierung dieses Codes, so dass meine gesamte CPU-Auslastung nicht kontinuierlich hoch ist.

+0

'IViewObject'-Schnittstelle hat die' Freeze'- und 'UnFreeze'-Funktionen, die dafür nützlich sein können. Ich werde versuchen, ein Beispiel vorzubereiten. – TLama

+0

Ich denke, wir müssen hier echten Code sehen (einschließlich der HTML). 'WM_SETREDRAW' funktioniert tatsächlich (in einem sehr begrenzten Test, den ich gemacht habe). aber da 'innerHTML' asynchron arbeitet, denke ich, dass es ein Problem wäre, es zu synchronisieren ... – kobik

+0

@kobik, aber wenn du sagst, dass' innerHTML' asynchron ist, dann habe ich Angst, selbst 'IViewObject' hilft nicht. Es müsste eine Überprüfung für den Bereitschaftszustand sein. – TLama

Antwort

4

Da Ihr Hauptproblem die Aktualisierungsfrequenz ist, müssen Sie sie verringern. Dazu können Sie einfach die letzte Aktualisierung des HTML-Dokuments speichern und bei der nächsten Datenänderung überprüfen, ob seit dieser Zeit ein bestimmter Zeitraum verstrichen ist.

Hier ist der Code, der zeigt, wie dies zu tun ist. Die FUpdatePeriod im folgenden Beispiel ist die Aktualisierungszeit in Millisekunden. Dann, wenn Sie die UpdateChanges periodisch aufrufen, wird die innerHTML (Pseudocode hier) nur aktualisiert, wenn mindestens 1000 ms seit seiner letzten Änderung verstrichen sind.

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

danke für diese Lösung. –

1

Dies ist eine Seitwärtsantwort; Aber als wir Probleme mit TWebBrowser hatten, haben wir sie behoben, indem wir in unsere Anwendung Google Chrome (DCEF) embedded gewechselt haben.

Während ich ursprünglich fühlte, dass ich TWebBrowser optimieren konnte, und reduzieren Sie es ist Flimmern, fand ich heraus, dass das Problem nur native Internet Explorer ist. Abgesehen von der Installation einer neuen Version von Internet Explorer oder dem Umschreiben Ihres gesamten JavaScript-Codes, damit Ihre Webseite niemals flackert, weil sie keine aktiven Elemente im HTML-Layout enthält (100% Javascript free = kein Flimmern), besteht die einzige Lösung darin, den Internet Explorer zu beenden und beenden Sie die Verwendung von TWebbrowser.

Zweitens kann Flicker auch verursacht werden, wenn Ihre TWebBrowser-Webseite auf native Delphi-Methoden als Rückrufe von Javascript zugreift. Wenn diese Callbacks viel Zeit in Anspruch nehmen, verursachen sie auch im eingebetteten TWebBrowser immer Flimmern, auch wenn das einzige JavaScript, das gerade ausgeführt wird, der Aufruf des Delphi-Callbacks ist. Die Technik, über die ich spreche (Rückrufe) ist dokumentiert here.

+0

P, meine Frage könnte ein bisschen zu vage sein. Ich habe keine Flimmerprobleme, meine größte Sorge ist, dass der Webbrowser eine Menge CPU-Leistung verbraucht, wenn ich innerHTML aufruft und alle Aufrufe von innerHTML beenden möchte, bevor ich ihn bemale. danke –

+0

Ich werde über google chrome nachdenken und sehen, ob es eine Verbesserung geben wird. danke –

+1

Ich werde dann Ihre Frage bearbeiten. Du solltest keine Frage zu X stellen, wenn du wirklich Y meinst :-) –