Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   Überwachte Ausdrücke optimieren? (https://www.delphipraxis.net/189852-ueberwachte-ausdruecke-optimieren.html)

stahli 30. Jul 2016 10:42

Überwachte Ausdrücke optimieren?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich nutze folgendes Interface:

Delphi-Quellcode:
  IsoGuid = interface
    ...
    property TS1: TDateTime read _get_TS1 write _set_TS1;
    property TS2: TDateTime read _get_TS2 write _set_TS2;
    property C: LongWord read _get_C write _set_C;
    property AsString: String read get_AsString write set_AsString;
  end;
In den überwachten Ausdrücken wird nur der Klassenname und die Speicheradresse angegeben.
Man kann auch keine Members aufklappen.

Gibt es vielleicht eine Möglichkeit, die Darstellung für mein Interface in den überwachten Ausdrucken zu optimieren?
Mich würden regelmäßig bestimmte Werte interessieren (oder zumindest einer).

Es wäre cool, wenn man so eine Art Template definieren oder Attribute festlegen könnte, um die gewünschte Darstellung zu erreichen (ohne das ständig neu schreiben zu müssen).

Mavarik 30. Jul 2016 16:59

AW: Überwachte Ausdrücke optimieren?
 
Du kannst Dir mit der ToolsAPI einen eigenen Viewer bauen...

Mavarik

jaenicke 31. Jul 2016 12:34

AW: Überwachte Ausdrücke optimieren?
 
Das Stichwort sind Visualizer:
http://docwiki.embarcadero.com/RADSt...er_Visualizers

stahli 2. Aug 2016 16:43

AW: Überwachte Ausdrücke optimieren?
 
Danke für die Info.

Ich habe mir das gestern mal angesehen.
Aber irgendwie ist Erstellung eigener Visualizer nur halb erklärt.
http://docwiki.embarcadero.com/RADSt...sualisierungen
http://edn.embarcadero.com/article/40268

Einige vollständigere Beispiele gibt es im Netz jedoch. Z.B. hier:
http://www.petronet.ir/documents/101..._2010_Handbook


Mir ist allerdings grundsätzlich unklar, ob man diese überhaupt für Interfaces realisieren kann.
Was müsste man denn als Typ angeben, damit der passende Visualizer benutzt wird?
"TMyGuid($2F31204) as IMyGuid" geht ja nicht.

Weiß jemand zufällig, ob/wie man das für Interfaces/Klassen lösen kann?

himitsu 2. Aug 2016 17:03

AW: Überwachte Ausdrücke optimieren?
 
Im Notfall kannst du vermutlich IInterface als Typ verwenden können und machst dann intern ein
Delphi-Quellcode:
if Supports
.
Wenn das trifft, dann deine Anzeige und sonst bildest du die Default-Anzeige nach, falls du den Original-Visualizer nicht aufrufen kannst.

Stevie 2. Aug 2016 17:19

AW: Überwachte Ausdrücke optimieren?
 
Zitat:

Zitat von stahli (Beitrag 1344013)
Mir ist allerdings grundsätzlich unklar, ob man diese überhaupt für Interfaces realisieren kann.
Was müsste man denn als Typ angeben, damit der passende Visualizer benutzt wird?
"TMyGuid($2F31204) as IMyGuid" geht ja nicht.

Weiß jemand zufällig, ob/wie man das für Interfaces/Klassen lösen kann?

Wenn du dir den von dir selber verlinkten Artikel, die Kommentare in der ToolsAPI.pas zu IOTADebuggerVisualizer und eventuell mal
die mitgelieferten Visualizer angeschaut hättest, wüsstest du, dass die unterstützten Types über ihren TypeName angegeben werden. ;)

stahli 2. Aug 2016 23:37

AW: Überwachte Ausdrücke optimieren?
 
Da habe ich (mit wenig Zeit) natürlich versucht, aber mir fällt das etwas schwerer als Dir und die mitgelieferten Beispiele hatte ich nicht gefunden.

Ich bin jetzt aber etwas weiter.
Aus dem String "TsoGuid($2F21204) as IsoGuid" extrahiere ich zunächst den Pointer um dort das Interface abzuholen.
Ich weiß nicht, ob der Pointer auf das Objekt oder das Interface verweist. Beide versuchten Casts funktionieren jedoch nicht.
Debugging ist etwas schwierig, da das ja zur Designtime läuft.


Hier mal ein Auszug (auf Grund der Versuche etwas chaotisch).

Delphi-Quellcode:
var
  P: Integer;
  S, SR: string;
  Adr: Integer;
  lGuid: IsoGuid;
  tmpGuid: TsoGuid;
  O: TObject;

    CodeSite.Send(Expression + ' - ' + TypeName + ' - ' + EvalResult);
    // AUSGABE: Guid - IsoGuid - TsoGuid($2F21204) as IsoGuid
    if (TypeName = 'IsoGuid') then
    begin
      Result := 'IsoGuid! => ' + EvalResult;
      SR := EvalResult;
      P := Pos('(', SR);
      S := Copy(SR, 1, P - 1);
      SR := Copy(SR, P + 1);
      if (S = 'TsoGuid') then
      begin
        P := Pos(')', SR);
        S := Copy(SR, 1, P - 1);
        SR := Copy(SR, P + 1);
        Adr := StrToInt(S);
        if (SR = ' as IsoGuid') then
        begin
//          O := TObject(Adr);
//          tmpGuid := TsoGuid(Adr);
//          if Supports(tmpGuid, IsoGuid, lGuid) then
//            Result := '---> IsoGuid'
//          else
//            Result := ':-( ' + IntToHex(Adr, 8) + ' - ' + EvalResult;
//            Result := ':-( ' + O.ClassName;
           Result := IsoGuid(Adr).AsString;
        end;
      end;
      Exit;
    end;
Kann mir jemand nochmal einen Tipp zu dem korrekten Cast geben?
Falls ich zum Ziel komme fasse ich das dann gern für Interessenten hier zusammen.

Stevie 3. Aug 2016 08:50

AW: Überwachte Ausdrücke optimieren?
 
Du brauchst nix casten. Benutz die OTA. Wie das geht kannst du in den mitgelieferten Visualizers für z.B. TStrings sehen.
Kann man fast 1 zu 1 kopieren.

TiGü 3. Aug 2016 08:52

AW: Überwachte Ausdrücke optimieren?
 
Warum nicht einfach in den überwachten Ausdrücken das schreiben:
TsoGuid(Guid), wobei Guid deine Interface-Instanz ist.
Ist zwar so hart hingecastet, aber zum schnellen Debuggen, um die Werte der Member-Variablen zu prüfen reicht es doch?!?

stahli 3. Aug 2016 09:02

AW: Überwachte Ausdrücke optimieren?
 
@Stevie
Vielen Dank. Schaue ich mir heute Abend an.

@TiGü
Die Guid verwende ich andauernd in meinem Projekt.
Da ist es hilfreich, wenn die IDE den Inhalt automatisch korrekt anzeigt.
Scheint ja auch so, dass es lösbar ist.

stahli 3. Aug 2016 22:42

AW: Überwachte Ausdrücke optimieren?
 
Ich komme so leider auch nicht weiter.

Den Formularvisualizer möchte ich nicht nutzen. Nur den StringReplacer.

Über OTA ermittle ich den aktuellen Thread.
Über CurThread.Evaluate(Expression...) wird der Ausgabetext ermittelt.
Das ergibt aber den ungewollten "TsoGuid($2FB1204) as IsoGuid".

Im folgenden Code wird der Text erfolgreich abgerufen, nur, dass ich den eben nicht ändern kann:
Gewünscht wäre: IsoGuid.AsString
Zitat:

Guid - IsoGuid - TsoGuid($2FB1204) as IsoGuid
-1
-2
-3
-4a "TsoGuid($2FB1204) as IsoGuid"
-5
--
Delphi-Quellcode:
    CodeSite.Send(Expression + ' - ' + TypeName + ' - ' + EvalResult);
    // Guid - IsoGuid - TsoGuid($2F21204) as IsoGuid
    if (TypeName = 'IsoGuid') then
    begin
      Result := 'IsoGuid! => ' + EvalResult;
      CodeSite.Send('-1');
      if Supports(BorlandIDEServices, IOTADebuggerServices, DebugSvcs) then
        CurProcess := DebugSvcs.CurrentProcess;
      if CurProcess <> nil then
      begin
        CodeSite.Send('-2');
        CurThread := CurProcess.CurrentThread;
        if CurThread <> nil then
        begin
          CodeSite.Send('-3');
          repeat
          begin
            Done := True;
            EvalRes := CurThread.Evaluate(Expression, @ResultStr, Length(ResultStr), CanModify, eseAll, '', ResultAddr,
              ResultSize, ResultVal, '', 0);
            case EvalRes of
              erOK:
                begin
                  Result := ResultStr;
                  CodeSite.Send('-4a "' + Result + '"');
                end;
              erDeferred:
                begin
                  CodeSite.Send('-4b');
                  FCompleted := False;
                  FDeferredResult := '';
                  FDeferredError := False;
                  FNotifierIndex := CurThread.AddNotifier(Self);
                  while not FCompleted do
                    DebugSvcs.ProcessDebugEvents;
                  CurThread.RemoveNotifier(FNotifierIndex);
                  FNotifierIndex := -1;
                  if not FDeferredError then
                  begin
                    if FDeferredResult <> '' then
                      Result := FDeferredResult
                    else
                      Result := ResultStr;
                  end;
                end;
              erBusy:
                begin
                  CodeSite.Send('-4c');
                  DebugSvcs.ProcessDebugEvents;
                  Done := False;
                end;
            end;
            CodeSite.Send('-5');
          end
          until Done = True;
        end;
      end;
      CodeSite.Send('--');

Also müsste CurThread.Evaluate irgendwie überschrieben werden. Aber dann müsste die als einziges bekannte Adresse ja auch in das Interface-Object gecastet werden.
Dann könnte ich das aber doch auch gleich (wie im vorigen Beitrag) in Visualizer direkt tun - nur dass das dort (noch) nicht funktionierte.

Sorry, ist etwas schwierig für mich. :-(

Stevie 4. Aug 2016 09:35

AW: Überwachte Ausdrücke optimieren?
 
Delphi-Quellcode:
CurThread.Evaluate(Expression+'.AsString', ...

stahli 4. Aug 2016 11:15

AW: Überwachte Ausdrücke optimieren?
 
Oha, so einfach. :shock: Also funktioniert das über die RTTI.
Jetzt erschließt sich mir auch, was ich gestern an eigenartigen Beispielen gefunden hatte. ;-)

Muss dann heute Abend nur noch funktionieren.

Stevie 4. Aug 2016 12:01

AW: Überwachte Ausdrücke optimieren?
 
Zitat:

Zitat von stahli (Beitrag 1344145)
Oha, so einfach. :shock: Also funktioniert das über die RTTI.

Nein, über den Debugger ;)

IOTAThread.Evaluate macht das, was du auch während des Debuggens über Strg+F7 machen kannst.

stahli 4. Aug 2016 21:32

AW: Überwachte Ausdrücke optimieren?
 
Liste der Anhänge anzeigen (Anzahl: 5)
Stevie, Du hast einen Kaffee oder Milch bei mir gut! :stupid:

Also falls es mal jemand braucht:

Normalerweise sieht man beim Debuggen nur den Typ und die Speicheradresse von Objekten und Interfaces.
Man kann sich natürlich auch deren Eigenschaften anzeigen lassen, muss das aber jedes mal explizit angeben.

Durch Einrichtung eines DebugVisualizers kann man die Standardausgabe ändern.
So lasse ich jetzt automatisch eine Guid der Interfaces anzeigen, wenn ich diese in den überwachten Ausdrücken aufnehme oder mit der Maus darüber gehe.

Neben den einfachen "Wertersetzern" kann man auch "externe Viewer" einrichten, durch die man komplexere Formulare einbinden kann wie bei den TStringList.
http://docwiki.embarcadero.com/RADSt...sualisierungen

Mir reicht jedoch die Wertersetzung. Die pas liegt hier bei.
"soGuid" müsstet Ihr lediglich durch Eure Klassennamen ersetzen sowie ggf. "AsString" wenn Ihr etwas anderes anzeigen wollt.

Eurer Projektgruppe müsst Ihr lediglich ein Package hinzufügen.
Im Package unter "Erfordert" von Hand "designide" hinzufügen und das Package installieren.

Unter Optionen/Debugger-Optionen/Visualisierungen muss das Package aktiviert sein.

Also insgesamt kein großer Aufwand mit einem ggf. recht hohen Nutzen.

jaenicke 5. Aug 2016 05:15

AW: Überwachte Ausdrücke optimieren?
 
Vielen Dank! Mit dem Thema wollte ich mich schon länger einmal beschäftigen, habe es aber zeitlich nie geschafft...
Mit dem Beispiel werde ich das nun doch einmal ändern. :thumb:

Rollo62 5. Aug 2016 19:06

AW: Überwachte Ausdrücke optimieren?
 
Dito.

Jetzt hast du bei mir einen Kaffee MIT Milch gut :thumb:

Rollo

stahli 25. Feb 2021 23:52

AW: Überwachte Ausdrücke optimieren?
 
Hier ein Beispiel für Überwachungsformulare: https://www.delphipraxis.net/206854-...n-threads.html


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:53 Uhr.

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