5 votes

Optimiser la peinture de TWebBrowser pour réduire l'utilisation totale du CPU

J'ai un formulaire qui a un TWebBrower qui charge un document HTML. Les données du document HTML sont mises à jour toutes les quelques secondes, parfois plusieurs fois par seconde, et je mets à jour la valeur dans Delphi en utilisant :

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

Le problème est que je veux verrouiller la fenêtre/navigateur Web pour l'empêcher de peindre/de mettre à jour jusqu'à ce que toutes mes mises à jour soient terminées. Existe-t-il un moyen de le faire ? Est-ce qu'un appel à

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

J'aimerais avoir de l'aide pour optimiser ce code afin que l'utilisation totale du CPU ne soit pas continuellement élevée.

4voto

TLama Points 40454

Puisque votre principal problème est la fréquence de mise à jour, vous devez la réduire. Pour cela, vous pouvez simplement enregistrer la dernière mise à jour du document HTML et, au prochain changement de données, vérifier si une certaine période s'est écoulée depuis ce moment.

Voici le code qui montre comment faire. Le site FUpdatePeriod dans l'exemple suivant est la période de mise à jour en millisecondes. Ensuite, si vous appelez la fonction UpdateChanges périodiquement, le innerHTML (pseudo-code ici) ne sera mis à jour que lorsqu'au moins 1000 ms se seront écoulées depuis sa dernière modification.

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.

1voto

Warren P Points 23750

C'est une réponse indirecte ; mais lorsque nous avons eu des problèmes de scintillement avec TWebBrowser, nous les avons résolus en passant à l'utilisation de Google Chrome (DCEF) intégré dans notre application.

Alors qu'au départ, je pensais moi aussi pouvoir "optimiser" TWebBrowser et réduire son scintillement, j'ai découvert que le problème est tout simplement propre à Internet Explorer. A part l'installation d'une nouvelle version d'Internet Explorer, ou la réécriture de tout votre JavaScript pour que votre page web ne scintille jamais, parce qu'elle n'a pas d'éléments actifs dans la mise en page HTML (100% sans javascript = pas de scintillement), la seule solution est d'arrêter d'utiliser Internet Explorer, et donc d'arrêter d'utiliser TWebbrowser.

Deuxièmement, le scintillement peut également être causé si votre page web TWebBrowser accède à des méthodes natives Delphi en tant que callbacks depuis le javascript. Ces callbacks, s'ils prennent beaucoup de temps, provoqueront toujours un scintillement dans le TWebBrowser intégré, même si le seul javascript qui est exécuté est l'invocation du callback Delphi. La technique dont je parle (callbacks) est documentée. aquí .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X