Ausführlicher Delphi-Explorations-CodeSite-Anwendungsleitfaden
Obwohl Delphi uns äußerst leistungsstarke Debugging-Funktionen bietet, ist das Auffinden von Fehlern immer noch eine mühsame Aufgabe. Normalerweise verbringen wir ungefähr gleich viel Zeit mit dem Schreiben von Code und dem Debuggen von Code, möglicherweise sogar mehr. Um unnötige Zeit- und Energieverschwendung zu vermeiden, benötigen wir manchmal immer noch die Hilfe professioneller Debugging-Tools, um die Effizienz beim Blockieren von Fehlern zu verbessern. In diesem Artikel stellen wir das berühmte Debugging-Tool CodeSite PRo 2.0 vor (es gewann 2000 den zweiten Platz beim Delphi Informant Readers' Choice Award für das beste Debugging-Tool). Die offizielle Website ist www.raize.com. Die Hauptfunktion von CodeSite besteht darin, Entwicklern die Verwendung von Code zu ermöglichen, um Laufzeitdetails zur weiteren Analyse an spezielle Empfänger zu senden. Genauer gesagt können wir über die von CodeSite implementierte TCodeSite-Klasse Laufzeitinformationen verpacken und an den CodeSite Dispatcher (CodeSites Nachrichtenverteiler) senden, der diese Nachrichten zur Anzeige an einen oder mehrere Empfänger weiterleiten kann. Der Standardnachrichtenempfänger ist CodeSite Viewer. Die Effizienz von CodeSite zeigt sich darin, dass es sich von einem einfachen Dialogfeld unterscheidet, das Meldungen anzeigt oder Haltepunkte zum Überprüfen von Variablen setzt. Es ähnelt natürlich eher der Ereignisprotokollfunktion (Event Log). ist zweifellos leistungsfähiger als das Ereignisprotokoll. Es gibt viele, und seine Meldungen sind nachhaltig, das heißt, sie können gespeichert werden, was eine nachträgliche Analyse erleichtert. Bevor wir die spezifische Verwendung von CodeSite vorstellen, werfen wir zunächst einen Blick auf seine drei Komponenten. CodeSite-Objekt Wie bereits erwähnt, erfolgt das Senden von CodeSite-Nachrichten aus einer laufenden Anwendung mithilfe einer Instanz der TCodeSite-Klasse (definiert in der CSIntf-Einheit). Die Nachricht wird an die CodeSite gesendet Dispatcher. Sie können beispielsweise die SendMsg-Methode des Objekts verwenden, um eine einfache Zeichenfolgennachricht zu senden. Das TCodeSite-Objekt implementiert eine große Anzahl von Methoden, um verschiedene Arten des Informationsversands ohne Datenkonvertierung zu unterstützen. Die SendObject-Methode des Objekts verfügt beispielsweise über zwei Parameter: einer ist die Nachrichtenzeichenfolge und der andere ist ein Verweis auf die Objektinstanz . Diese Methode ruft alle veröffentlichten Attribute des Objekts ab und packt dann die Informationen dieser Attribute in CodeSite-Nachrichten. CodeSite Dispatcher In den meisten Fällen wird CodeSite Dispatcher unbemerkt im Taskleistenbereich ausgeführt. Seine einzige Funktion besteht darin, CodeSite-Nachrichten, die von verschiedenen TCodeSite-Objekten gesendet werden, an ihre Ziele weiterzuleiten. Standardmäßig werden CodeSite-Nachrichten an CodeSite Viewer gesendet. Wir müssen nicht einmal den CodeSite Dispatcher starten, da er automatisch von Objekten wie TCodeSite gestartet wird. Die TCodeSite-Klasse definiert eine DestinationDetails-Eigenschaft, mit der Entwickler konfigurieren können, wie gesendete CodeSite-Nachrichten vom CodeSite Dispatcher an verschiedene Ziele, beispielsweise Protokolldateien, weitergeleitet werden. Normalerweise besteht jedoch keine Notwendigkeit, diese Eigenschaft zu ändern. CodeSite Viewer Obwohl CodeSite das Senden von Nachrichten an verschiedene Ziele unterstützt, ist CodeSite Viewer in den meisten Fällen das primäre Sendeziel. Auch wenn CodeSite Viewer an andere Ziele wie Protokolldateien oder einen anderen Computer gesendet wird, ist er immer noch das wichtigste Tool zum Anzeigen und Analysieren von Nachrichten. CodeSite Viewer besteht aus den folgenden vier Bereichen: Nachrichtenliste, Nachrichtenanzeige, Aufrufliste und Scratch-Bereich. Der Hauptarbeitsbereich von CodeSite Viewer ist die Nachrichtenliste, die zur Anzeige aller an den Viewer gesendeten oder aus Protokolldateien geladenen Nachrichten verwendet wird. Nachrichtenbetrachter werden verwendet, um zusätzliche Informationen zu Nachrichten anzuzeigen. Wenn die aktuelle Nachricht beispielsweise von der SendObject-Methode gesendet wird, zeigt der Nachrichten-Viewer die aktuellen Werte aller veröffentlichten Eigenschaften des Objekts an. Der Aufrufstapelbereich zeigt eine Stapelansicht basierend auf csmEnterMethod-Nachrichten an. Scratch Panels dienen der Darstellung nicht nachhaltiger Informationen. Das Scratch-Bedienfeld ist sehr nützlich, wenn wir bestimmte Informationen verfolgen, diese aber nicht im Nachrichtenprotokoll aufzeichnen möchten, beispielsweise wenn wir eine große Anzahl wiederholter Nachrichten anzeigen möchten, beispielsweise die aktuelle Position der Maus. Zu diesem Zeitpunkt können wir die WritePoint-Methode des TCodeSite-Objekts verwenden und den Parameter „Line ID“ angeben, um die Anzahl der Scratch-Panel-Zeilen anzugeben, die zur Aufnahme von Mausinformationen verwendet werden. Lassen Sie uns anhand eines einfachen Beispiels demonstrieren, wie Sie vom Programm aus eine Nachricht an CodeSite Viewer senden: (1) Erstellen Sie ein neues Projekt und wechseln Sie dann vom Komponentenfenster zur CodeSite-Seite (CodeSite installiert nach der Installation von TCSGlobalObject zwei Komponenten im System und TCSObject). Wählen Sie die TCSGlobalObject-Komponente aus und platzieren Sie sie im Formular. Die TCSGlobalObject-Komponente ermöglicht Entwurfszeitinteraktion mit dem globalen TCodeSite-Objekt (die globale TCodeSite wird in der CSInft-Einheit initialisiert). (2) Fügen Sie eine Schaltfläche hinzu und schreiben Sie dann den folgenden Code in sein OnClick-Ereignis: //CodeSite ist das globale TCodeSite-Objekt CodeSite.SendMsg('CodeSite's first message'); (3) Kompilieren Sie dieses einfache Programm und führen Sie es aus. Klicken Sie nach dem Ausführen auf die Schaltfläche, und CodeSite Dispatcher und CodeSite Viewer werden ausgeführt. Gleichzeitig sehen Sie die vom Programm gesendeten Nachrichten in der Nachrichtenliste von CodeSite Viewer (Hinweis: Wir müssen CodeSite Dispatcher und CodeSite Viewer nicht starten, bevor wir das Programm ausführen, da das TCodeSite-Objekt sie automatisch startet, wenn es ausgeführt wird muss Nachrichten senden). Die Laufergebnisse sind in Abbildung 4.38 unten dargestellt:
(4) Stoppen Sie als Nächstes das Programm und fügen Sie den folgenden Code in den OnClick-Ereignisverarbeitungsprozess ein: CodeSite.SendObject('Form1', Form1); (5) Kompilieren Sie das Programm erneut und führen Sie es aus. Klicken Sie erneut auf die Schaltfläche. Diesmal ist dies der Fall Im CodeSite Viewer habe ich zwei Meldungen gesehen. Die Form1 entsprechende Nachricht enthält die Objektinformationen von Form1. (6) Um die zugehörigen Objektinformationen von Form1 anzuzeigen, wählen Sie den CodeSite Viewer-Menübefehl „Ansicht|Inspektor“, um auf der rechten Seite der Nachrichtenliste ein neues Panel anzuzeigen, in dem die veröffentlichten Attribute von Form1 angezeigt werden, wie in gezeigt Abbildung 4.39 unten:
(7) Stoppen Sie das Programm erneut und ändern Sie dann den Code im OnClick-Prozess wie folgt: CodeSite.EnterMethod('Button1Click'); CodeSite.SendObject('Form1', Form1 ) ; CodeSite .ExitMethod('Button1Click' ); (8) Wenn wir dieses Mal das Programm ausführen und auf die Schaltfläche klicken, werden wir sehen, dass die Meldungen „Erste Nachricht von CodeSite“ und „Form1“ zwischen den Meldungen „Button1Click“ eingerückt sind, wie in Abbildung 4.40 unten dargestellt:
Durch das Hinzufügen von Aufrufen zu den Methoden EnterMethod und ExitMethod können wir ein Protokoll generieren, das aufzeichnet, wann die Methoden aufgerufen werden. Nachdem wir uns die Beispiele angesehen haben, werden wir feststellen, dass die Funktion von CodeSite sehr leistungsfähig ist. Durch einfaches Hinzufügen einiger Anweisungen zum Programm können wir sehr detaillierte Informationen generieren und diese über den CodeSite Viewer in anschaulichen Diagrammen anzeigen. Lassen Sie uns als Nächstes über die fortschrittliche Anwendungstechnologie von CodeSite sprechen. Senden von Nachrichten an Protokolldateien Jedes Programm weist mehr oder weniger Fehler auf. Wenn dies zu diesem Zeitpunkt nicht der Fall ist, kann dies nach einiger Zeit der Fall sein erscheint immer wieder, und manchmal passiert es, dass es sehr zufällig entdeckt wurde. Wenn Ihnen jemand sagt, dass die von ihm geschriebenen Programme jederzeit problemlos laufen, lügt er. Gerade wegen der zufälligen und versteckten Natur von Fehlern ist es für uns oft schwierig, von Benutzern gemeldete Fehler zu wiederholen, was für uns ein großes Hindernis beim Debuggen des Programms und beim Finden der Ursache des Problems darstellt, und CodeSite kann Nachrichten senden zum Protokollieren von Dateien Dies erleichtert Benutzern das Melden von Fehlern, da sie nur die zur Laufzeit generierte Informationsdatei übermitteln müssen. Dementsprechend wird unsere Arbeit beim Debuggen des Programms einfacher. Mit CodeSite Viewer können wir die Ursache und den Ort des Fehlers intuitiv analysieren. Um das Ziel des Nachrichtenversands zu ändern, können wir dies tun, indem wir die DestinationDetails-Eigenschaft des TCodeSite-Objekts festlegen. Für diese Funktion muss CodeSite Dispatcher auf dem Computer des Kunden installiert sein, der ein frei verteilbarer Teil von CodeSite ist. Der folgende spezifische Prozess basiert immer noch auf dem zuvor erwähnten Beispiel: (1) Fügen Sie den folgenden Code im OnCreate-Ereignis des Formulars hinzu: CodeSite.DestinationDetails := 'File[Path=C:/FirstLog.csl]' (2 ) Nachdem wir auf die Schaltfläche geklickt haben, wird die Nachricht dieses Mal nicht mehr an den CodeSite Viewer, sondern an die Datei FirstLog.csl auf dem Laufwerk C gesendet. (3) Verwenden Sie den CodeSite Viewer, um die Datei FirstLog.csl zu laden. Diesmal sehen wir uns die gespeicherten CodeSite-Nachrichten wie zuvor an. (4) Wenn wir gleichzeitig Nachrichten an CodeSite Viewer und Protokolldateien senden möchten, ändern Sie einfach den vorherigen Code wie folgt: CodeSite.DestinationDetails := 'Viewer,File[Path=C:/FirstLog.csl]'; -benutzerdefinierte Daten Obwohl die TCodeSite-Klasse eine große Anzahl von Methoden zur Verarbeitung verschiedener Datentypen bereitstellt, müssen wir manchmal Dateninformationen in einem bestimmten benutzerdefinierten Format senden. Zu diesem Zweck definiert die Klasse TCodeSite die Methode SendCustomData, die das Senden beliebiger Datentypen unterstützt und die Daten gemäß einem benutzerdefinierten Formatierer formatiert, damit der CodeSite Viewer die Daten korrekt anzeigen kann. Zuerst müssen wir eine Unterklasse des TCSFormatter-Objekts erstellen und dann die FormatData-, InspectorType- und TypeName-Methoden des Objekts überladen. Rufen Sie dann das CodeSite-Objektmanagerobjekt CSObjectManager auf, um die neue TCSFormatter-Unterklasse zu registrieren. Darüber hinaus müssen wir auch die Methode RegisterCustomFormat aufrufen, um einen neuen Nachrichtentyp zu registrieren. Das Folgende ist ein Beispiel für eine praktische Anwendung des TCSEmployeeRecord-Datensatztyps: Unit CSEmployee; const csmEmployeeDetails = csmUser + 2 , fügt im Abschnitt „Verwendungen“ einen Verweis auf die CSIntf-Einheit hinzu. Der zweite Schritt besteht darin, für jeden Formatierer neue CodeSite-Nachrichtentypkonstanten zu definieren. Beachten Sie, dass die Konstanten größer als csmUser sein sollten, jedoch nicht größer als 32.000. type TCSEmploye = record LastName: string; City: string; HireDate: String; SickDays: Integer; Boolean; end; Der obige Datensatz ist der benutzerdefinierte Datentyp, den wir senden möchten. TCSEmployeFormatter = class( TCSFormatter ) public function InspectorType; procedure FormatData( var Data ); override; Oben sind die Definitionen von zwei benutzerdefinierten Formatierungsklassen aufgeführt. Der erste Formatierer formatiert den TCSEmployee-Datensatz in ein Textformat und der zweite Formatierer formatiert den TCSEmployee-Datensatz in einen Rasterstil. Implementierung verwendet SysUtils; {=====================================} {= = TCSEmployeeSummaryFormatter-Methoden ==} {=========================================} function TCSEmployeeSummaryFormatter .InspectorType: TCSInspectorType; begin Result := itStockStringList; Der erste Schritt bei der Implementierung eines benutzerdefinierten Formatierers besteht darin, zu bestimmen, welcher Typ des integrierten Viewers zum Anzeigen der formatierten Daten verwendet wird. In diesem Fall wird ein String-Listen-Viewer verwendet. Der Viewer-Typ wird von der FormatData-Methode verwendet. procedure TCSEmployeeSummaryFormatter.FormatData( var Data ); begin EmpRec := TCSEmployee( Data ); AddLine( EmpRec.City + ', ' + EmpRec.State + ' ' + EmpRec.ZipCode ); AddLine( 'Phone: ' + EmpRec.PhoneNumber ); m', [ EmpRec.Salary ] ) ); AddLine( '' ); ' + IntToStr( EmpRec.VacationDays ) ); AddLine( 'Krankheitstage: ' + IntToStr( EmpRec.SickDays ) ); ; Die FormatData-Methode ist der Kernteil. Der an die FormatData-Methode übergebene Data-Parameter ist ein untypisierter Variablenparameter. Dies bedeutet, dass dieser Parameter einen beliebigen Datentyp haben kann. Durch den Formatregistrierungsprozess können wir sicherstellen, dass der erzwungene Typ einem benutzerdefinierten Datensatz ohne Konvertierungsfehler zugeordnet wird. Nach der Konvertierung des Datentyps können wir die Daten formatieren. Hier verwenden wir die AddLine-Methode der TCSFormatter-Basisklasse, um Trennlinien zwischen Zeichenfolgen zur Formatierung hinzuzufügen. function TCSEmployeeSummaryFormatter.TypeName: string; begin Result := 'TCSEmployee'; Die Überladung der TypeName-Methode ist optional, aber normalerweise können wir sie verwenden, um die Zeichenfolge zurückzugeben, die in der Nachrichtenliste angezeigt wird. {=======================================} {== TCSEmployeeDetailsFormatter-Methoden == } {=======================================} Funktion TCSEmployeeDetailsFormatter.InspectorType: TCSInspectorType ; begin Ergebnis := itStockGrid; Für den Formatierer „employeesdetails“ wird der benannte Grid-Viewer zum Anzeigen der Daten verwendet: procedure TCSEmployeeDetailsFormatter.FormatData( var Data ); var EmpRec: TCSEmployee( Data ); AddNameValuePair( 'LastName', EmpRec .LastName ) ; AddNameValuePair( 'FirstName', EmpRec.FirstName ); AddNameValuePair( 'Address', EmpRec.Address ); AddNameValuePair( 'State', EmpRec.State ); AddNameValuePair( 'PhoneNumber', EmpRec.PhoneNumber ); AddNameValuePair( 'HireDate', EmpRec.HireDate ); AddNameValuePair( 'Salary', Format( '%m', [ EmpRec.Salary ] ) ); AddNameValuePair( 'SickDays', EmpRec.SickDays ); AddNameValuePair( 'Manager', EmpRec.Manager ); end; Um die Daten im Grid Viewer zu formatieren, verwenden wir die Methode AddNameValuePair. function TCSEmployeeDetailsFormatter.TypeName: string; begin Result := 'TCSEmployee'; Die folgenden zwei Prozeduren werden verwendet, um Aufrufe der SendCustomData-Methode zu kapseln: {===== =============} {== Support-Methoden ==} {=====================} procedure CSSendEmployeeSummary ( const Nachricht: string; EmpRec: TCSEmployee ); begin CodeSite.SendCustomData( csmEmployeeSummary, Msg, EmpRec ); end; Vergessen Sie nicht, die Methode CSObjectManager.RegisterCustomFormatter aufzurufen, um den Formatierer beim CodeSite Object Manager zu registrieren. Initialisierung CSObjectManager.RegisterCustomFormatter( csmEmployeeSummary, TCSEmployeeSummaryFormatter ); CSObjectManager.RegisterCustomFormatter( csmEmployeeDetails, TCSEmployeeDetailsFormatter );