2012-04-18 11 views
5

Tengo un formulario que tiene un componente TWebBrower que carga un documento HTML. Los datos sobre el documento HTML se actualiza cada pocos segundos, a veces varias veces cada segundo y actualizar el valor en Delphi usando:Optimizar la pintura de TWebBrowser para reducir el uso total de la CPU

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

El problema es que quiero cerrar la ventana/navegador web para evitar que la pintura/actualizando hasta que todas mis actualizaciones estén completas. ¿Hay alguna manera de hacer esto? ¿Llamaría a

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

Me gustaría algo de ayuda en la optimización de este código para que mi uso total de la CPU no sea continuamente alto.

+0

'interfaz IViewObject' tiene las funciones' Freeze' y 'UnFreeze' que pueden ser útiles para esto. Trataré de preparar un ejemplo. – TLama

+0

Creo que necesitamos ver código real aquí (incluido el HTML). 'WM_SETREDRAW' realmente funciona (en una prueba muy limitada que hice). pero como 'innerHTML' funciona de forma asíncrona, creo que sería un problema sincronizarlo ... – kobik

+0

@kobik, pero si dices que' innerHTML' es asincrónico, me temo que incluso 'IViewObject' no ayuda. Tendría que ser algún control para el estado listo. – TLama

Respuesta

4

Dado que su problema principal es la frecuencia de actualización, entonces necesita disminuirlo. Para esto, puede simplemente almacenar la última vez que actualizó el documento HTML y, en el siguiente cambio de datos, verificar si ha transcurrido un cierto período desde ese momento.

Aquí está el código que muestra cómo hacerlo. El FUpdatePeriod en el siguiente ejemplo es el período de actualización en milisegundos. Luego, si llama al UpdateChanges periódicamente, el innerHTML (pseudocódigo aquí) se actualizará solo cuando haya transcurrido al menos 1000 ms desde su último cambio.

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

gracias por esta solución. –

1

Esta es una respuesta lateral; Pero cuando tuvimos problemas de parpadeo con TWebBrowser los solucionamos cambiando a usar Google Chrome (DCEF) embedded en nuestra aplicación.

Aunque originalmente también sentí que podía "optimizar" TWebBrowser y reducir su parpadeo, descubrí que el problema es solo nativo de Internet Explorer. Además de instalar una nueva versión de Internet Explorer o reescribir todo tu JavaScript para que tu página web no parpadee, porque no tiene elementos activos en el diseño HTML (100% javascript gratis = sin parpadeo), la única solución es dejar de usar Internet Explorer. , y así dejar de usar TWebbrowser.

En segundo lugar, el parpadeo también puede producirse si su página web TWebBrowser está accediendo a los métodos nativos de Delphi como devoluciones de llamada desde el javascript. Estas devoluciones de llamada, si toman mucho tiempo, siempre causarán parpadeo en TWebBrowser incrustado, incluso si el único javascript que se está ejecutando es la invocación de la devolución de llamada delphi. La técnica de la que estoy hablando (devoluciones de llamada) está documentada en here.

+0

P, mi pregunta puede ser un poco demasiado vaga. No tengo problemas de parpadeo, mi mayor preocupación es que el navegador web absorbe mucha potencia de la CPU cuando estoy llamando a innerHTML y querría terminar todas las llamadas a innerHTML antes de pintarlo. gracias –

+0

consideraré usar google chrome y ver si habrá una mejora. Gracias –

+1

Voy a editar su pregunta, entonces. No debe hacer una pregunta sobre X cuando realmente quiere decir Y. :-) –

Cuestiones relacionadas