Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Resize + SetBounds beschleunigen (https://www.delphipraxis.net/165749-resize-setbounds-beschleunigen.html)

stahli 14. Jan 2012 01:52

Resize + SetBounds beschleunigen
 
Liste der Anhänge anzeigen (Anzahl: 1)
In einem Designer stelle ich Controls dar (Panel-Ableitungen, an die Datenobjekte gebunden sind), die wieder andere Controls enthalten.
Wird die Rastergröße geändert, werden die Controls an das Raster angepasst.

Das geht zu langsam, wenn einige hundert Controls dargestellt werden.

AQTime hat mir schon gute Dienste geleistet, aber in der XE-Version geht keine Zeilenanalyse.

Ich habe mir mal notdürftig etwas zusammengeschrieben. Die meiste Zeit geht bei den SetBounds der SubControls drauf.

Gibt es eine Möglichkeit, das zu beschleunigen?
Ich könnte mir vorstellen, vorübergehend die Verabeitung von CMInvalidate zu verhindern, weiß aber nicht recht, ob der Ansatz etwas taugt oder ob es einfacherere Lösungen gibt.


Delphi-Quellcode:
procedure TodvKoGame.Resize;
var
  W: Integer;
  KOG: TodKoGame;
  dt: TDatetime;

  procedure d(i: Integer);

    procedure Swap(var i, j: tda);
    var
      H: tda;
    begin
      H := i;
      i := j;
      j := H;
    end;

    procedure Sort;
    var
      i, j: Integer;
    begin
      for i := Low(da) to High(da) - 1 do
        for j := i + 1 to High(da) do
          begin
            if da[j].dt > da[i].dt then
              Swap(da[i], da[j]);
          end;
    end;

  begin
    dt := now - dt;
    da[i].nr := i;
    da[i].dt := da[i].dt + dt;
    if i = high(da) then
      begin
        inc(dc);
        if dc = 240 then
          begin
            Sort;
            for i := Low(da) to High(da) do
              codesite.send(pchar(FormatDateTime('ss.zzz', da[i].dt) + ': ' + inttostr(da[i].nr)));
            dc := 0;
          end;
      end;
    dt := now;
  end;

begin
  PaintBackground;
  KOG := KoGame;
  if KOG <> nil then
    begin
//      inc(xxxr);
//      outputdebugstring(pchar('Resize: ' + inttostr(xxxr)));
      dt := now;
      if odvLinkIn1.BevelOuter <> bvNone then
        odvLinkIn1.BevelOuter := bvNone;
      d(1);

      if odPanelGameParty1.BevelOuter <> bvNone then
        odPanelGameParty1.BevelOuter := bvNone;
      d(2);

      if odvLinkIn2.BevelOuter <> bvNone then
        odvLinkIn2.BevelOuter := bvNone;
      d(3);

      if odPanelGameParty2.BevelOuter <> bvNone then
        odPanelGameParty2.BevelOuter := bvNone;
      d(4);

      if odvLinkOutWin.BevelOuter <> bvNone then
        odvLinkOutWin.BevelOuter := bvNone;
      d(5);

      if odvLinkOutLose.BevelOuter <> bvNone then
        odvLinkOutLose.BevelOuter := bvNone;
      d(6);

      W := Pred(Width);
      d(7);

      odvLinkIn1.Visible := True;
      d(8);

      odPanelGameParty1.Visible := True;
      d(9);

      if KOG.ToLeft then
        odvLinkIn1.SetBounds(W - 24, Succ(LineTop), 24, Pred(LineTop)) // <---
      else
        odvLinkIn1.SetBounds(0, Succ(LineTop), 24, Pred(LineTop)); // <---
      d(10);

      if KOG.ToLeft then
        odPanelGameParty1.SetBounds(1, Succ(LineTop), W - 24, Pred(LineTop))
      else
        odPanelGameParty1.SetBounds(24, Succ(LineTop), W - 24, Pred(LineTop));
      d(11);

      odvLinkIn2.Visible := True;
      d(12);

      odPanelGameParty2.Visible := True;
      d(13);

      if KOG.ToLeft then
        odvLinkIn2.SetBounds(W - 24, LineBottom - LineTop, 24, Pred(LineTop))
      else
        odvLinkIn2.SetBounds(0, LineBottom - LineTop, 24, Pred(LineTop));
      d(14);

      if KOG.ToLeft then
        odPanelGameParty2.SetBounds(2, LineBottom - LineTop, W - 24, Pred(LineTop))
      else
        odPanelGameParty2.SetBounds(24, LineBottom - LineTop, W - 24, Pred(LineTop));
      d(15);

      odvLinkOutWin.Visible := True;
      d(16);

      if KOG.ToLeft then
        odvLinkOutWin.SetBounds(1, (Height div 2) - (Pred(LineTop) div 2) - 1, 24, Pred(LineTop))
      else
        odvLinkOutWin.SetBounds(Width - odvLinkOutWin.Width - 1, (Height div 2) - (Pred(LineTop) div 2) - 1, 24, Pred(LineTop));
      d(17);

      odvLinkOutLose.Visible := True;
      d(18);

      if KOG.ToLeft then
        odvLinkOutLose.SetBounds(Width - odvLinkOutLose.Width - 1, (Height div 2) - (Pred(LineTop) div 2) - 1, 24, Pred(LineTop))
      else
        odvLinkOutLose.SetBounds(0, (Height div 2) - (Pred(LineTop) div 2) - 1, 24, Pred(LineTop));
      d(19);

//      outputdebugstring(pchar('Resize: ' + inttostr(xxxr) + ' ready'));
    end
  else
    begin
//      outputdebugstring(pchar('Resize: ' + '---------------------------'));
//      odvLinkIn1.Visible := False;
//      odPanelGameParty1.Visible := False;
//      odvLinkIn2.Visible := False;
//      odPanelGameParty2.Visible := False;
//      odvLinkOutWin.Visible := False;
//      odvLinkOutLose.Visible := False;
    end;
end;

Zitat:

-beim erstmaligen Aufbau-
04.863: 11
04.863: 15
04.860: 10
04.838: 14
04.831: 19
04.831: 17
02.439: 1
02.412: 5
02.398: 6
02.391: 3
00.000: 4
00.000: 12
00.000: 13
00.000: 7
00.000: 8
00.000: 16
00.000: 9
00.000: 18
00.000: 2
-beim Resize-
12.922: 10 // !!!
10.607: 15 // !!!
10.600: 19 // !!!
10.592: 14 // !!!
10.585: 11 // !!!
10.570: 17 // !!!
04.863: 1
04.863: 2
04.860: 3
04.838: 4
04.831: 5
04.831: 6
02.439: 7
02.412: 8
02.398: 9
00.001: 16
00.000: 13
00.000: 18
00.000: 12

Bummi 14. Jan 2012 07:35

AW: Resize + SetBounds beschleunigen
 
hast Du es mal mit
Delphi-Quellcode:
SendMessage(handle,WM_SETREDRAW,0,0);

tuwasMitAnnlenControls

RedrawWindow(handle, 0, 0, RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN);
versucht

stahli 14. Jan 2012 20:22

AW: Resize + SetBounds beschleunigen
 
Danke, aber das hat mich leider geschwindigkeitstechnisch nicht voran gebracht.

Ich mache es jetzt so, dass ich beim Resize die InnerControls ausblende und die Controls im Designer temporär "leer" darstelle.
Gleichzeitig werden diese in eine Liste aufgenommen und nach und nach mit dem Inhalt ergänzt.

Das ist auch noch nicht ganz optimal, aber zumindest erträglich.


Wenn jemand später mal noch Tipps dazu hat, dann immer her damit. :-)

Furtbichler 15. Jan 2012 08:20

AW: Resize + SetBounds beschleunigen
 
Kannst Du dein Control nicht in eine Bitmap rendern, während des Resize nur die Bitmap blitten und nach dem Ende des Resize einmalig alles zeichnen?

stahli 15. Jan 2012 11:06

AW: Resize + SetBounds beschleunigen
 
Das wäre deutlich aufwendiger zu programmieren und würde letztlich ja auch nicht viel bringen.
Der User könnte mit den Controls auch noch nicht arbeiten, obwohl sie eigentlich ja schon (fast) korrekt aussehen.
Da ist es mir lieber, man sieht erst mal nur die Rahmen und merkt, dass der Rest folgt.

Die einzige Lösung, die ich sehe wäre sicherlich, auf SubControls zu verzichten und alles selbst zu zeichnen und die Regionen für die Maus selbst zu behandeln.
Das will ich aber möglichst vermeiden, zumal ich die SubControls in mehreren Komponenten einsetze, die dann jeweils das gleiche Verhalten implementieren (Verbindungen untereinander darstellen und bearbeiten, Spieler darstellen usw.).

Furtbichler 15. Jan 2012 13:48

AW: Resize + SetBounds beschleunigen
 
Zitat:

Zitat von stahli (Beitrag 1146028)
Der User könnte mit den Controls auch noch nicht arbeiten, obwohl sie eigentlich ja schon (fast) korrekt aussehen.

Nö, sieht aber besser aus. Bei der Lösung, die leider ein bissel lahm ist, kann er doch auch nicht während des Resize arbeiten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:30 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz