2015-10-16 4 views
6

Dies diese Q auf meiner Antwort folgt:in den Delphi-IDE auf ein Objekt eine Referenz-

Can I change the display format for strings in the watch list?

Es stellt sich heraus, dass die Umsetzung der IDE der Uhr irgendwann zwischen D7 und XE3, Window hat sich von der Verwendung einer TListView zu einer TVirtualStringTree geändert.

Obwohl ich ein Update zu meiner Antwort gepostet habe, das mit XE4 funktioniert, indem ich die VST ignoriere und den Watch-Wert aus der Zwischenablage abrufe, möchte ich trotzdem den Watch-Wert vom VST abrufen können. Ich glaube, ich weiß, wie man das macht , sobald ich einen Verweis auf die VST habe, aber das Problem ist, dass mein Versuch, einen zu bekommen, fehlschlägt.

Folgendes ist ein MCVE des Codes, den ich in meinem benutzerdefinierten Paket verwende. Hoffentlich ist das, was es tut, selbsterklärend. Das Problem ist, dass der Code im Block

if WatchWindow.Components[i] is TVirtualStringTree then begin 
    [...] 
    end; 

nie ausgeführt wird, trotz des Klassennamen "TVirtualStringTree" erscheint in Memo1. Offensichtlich schlägt die Komponente mit diesem Klassennamen den "ist" -Test fehl. Ich vermute, dass der Grund dafür ist, dass der TVirtualTreeView, der in die IDE kompiliert wurde, eine andere Version ist als die, die ich benutze, v.5.3.0, welches der nächste Vorgänger ist, den ich für XE4 finden könnte.

Also, meine Frage ist, ist das die wahrscheinliche Erklärung, und kann ich irgendetwas dagegen tun? Ich vermute, wenn jemand die Version von TVirtualStringTree, die für XE4 von einem Hut verwendet wurde, gedeihen kann, könnte das mein Problem lösen.

type 
    TOtaMenuForm = class(TForm) 
    Memo1: TMemo; 
    procedure FormCreate(Sender: TObject); 
    private 
    WatchWindow : TForm; 
    VST : TVirtualStringTree; 
    end; 

procedure TOtaMenuForm.FormCreate(Sender: TObject); 
var 
    i : Integer; 
    S : String; 
begin 

    WatchWindow := Nil; 
    VST := Nil; 

    // Iterate the IDE's forms to find the Watch Window 
    for i := 0 to Screen.FormCount - 1 do begin 
    S := Screen.Forms[i].Name; 
    if CompareText(S, 'WatchWindow') = 0 then begin 
     WatchWindow := Screen.Forms[i]; 
     Break; 
    end; 
    end; 

    Assert(WatchWindow <> Nil); 

    if WatchWindow <> Nil then begin 
    Memo1.Lines.Add('Looking for VST'); 
    for i := 0 to WatchWindow.ComponentCount - 1 do begin 
     Memo1.Lines.Add(IntToStr(i) + ':' + WatchWindow.Components[i].ClassName); 
     if WatchWindow.Components[i] is TVirtualStringTree then begin 
     VST := TVirtualStringTree(WatchWindow.Components[i]); 
     Memo1.Lines.Add('found VST'); 
     Break; 
     end; 
    end; 
    if VST = Nil then 
     Memo1.Lines.Add('VST not found'); 
    end; 
end; 

Btw, ich merke, dass Lösungen, die von Implementierungsdetails von IDE verbunden sind, sind wahrscheinlich zerbrechlich sein, aber das ist nur für die Unterhaltung (ich mochte die Herausforderung des String-Daten immer aus einer Komponente, die sein aus geht Möglichkeit, die Speicherung zu vermeiden).

+3

Die VST-Version ist nicht das einzige Problem. Der Operator "is" schlägt fehl, wenn Ihr Code mit anderen RTTI als den IDEs kompiliert wird. Daher unterscheidet sich eine VST-Komponente in Ihrer Binärdatei von einer VST-Komponente in der IDE. Auch wenn Ihr Code dieselbe VST-Version verwendet, stimmt die RTTI immer noch nicht überein. Hier kommen Laufzeitpakete ins Spiel. Ihre Binärdatei muss mit dem Laufzeitpaket verknüpft sein, damit sie dieselbe RTL wie die IDE teilt und sie muss mit demselben Paket verknüpft sein, das die IDE für ihre VST-Komponente verwendet. Aber wenn VST direkt in die IDE kompiliert wird und nicht aus einem Paket importiert wird, sind Sie SOL ... –

+3

... müssten Sie auf den 'is'-Operator verzichten und stattdessen einen' ClassName() '-Vergleich verwenden. Damit können Sie zumindest die VST-Komponente der IDE erkennen. Aber * Zugriff * es ist nicht sicher, es sei denn, Sie haben die gleiche Version, so dass die Speicherlayouts immer noch übereinstimmen. –

+0

@RemyLebeau: Danke. In der Tat hatte ich versucht, das "i" -Ergebnis zu ignorieren und es auf der Basis des Klassennamens hart zu werfen, aber das AVs, wenn ich versuche, die Methoden des Objekts aufzurufen. Fwiw, ich habe die gleiche "is" -Technik in D7 verwendet, wo das Überwachungsfenster eine TListView ist, und das hat gut funktioniert, um die Referenz zu erhalten und zu verwenden. – MartynA

Antwort

0

Kann sein Sie können versuchen, nur veröffentlichte Eigenschaften von in TVirtualStringTree eingebetteten IDE-Implementierung über RTTI-Methoden zu verwenden, was Sie wollen?

+0

Eigentlich löste ich dieses Problem mit dem, was ich in meiner zweiten Antwort auf dieses q beschrieben habe: http://stackoverflow.com/questions/33121397/can-i-change-the-display-format-for-strings-in- die-Watch-Liste/33127943 # 33127943 – MartynA

Verwandte Themen