Registrieren Sie ein benutzerdefiniertes Formular, damit ich es von mehreren Projekten übernehmen kann, ohne das Formular in den Object Repository-Ordner zu kopieren

8

Ich habe einen benutzerdefinierten Frame, von dem ich in mehreren Projekten erben muss. Dieser Frame enthält Code und einige Komponenten und befindet sich irgendwo auf der Festplatte in seinem eigenen Projektverzeichnis. Ich möchte nicht COPY in den Object Repository-Ordner kopieren, das scheint mir nicht richtig zu sein: Ich würde am Ende zwei Kopien des Formulars haben, eins in meinem Mercurial-Backed-Repository, eine in Delphi's Object Repository. Absolut keine gute Idee.

Ich möchte meinen Frame in einem Package haben und das Package dazu veranlassen, den Frame der IDE bekannt zu machen und es der IDE zu ermöglichen, neue Geschwister des gegebenen Frames zu erstellen, ohne den Frame wirklich jedem hinzuzufügen Einzelprojekt.

Was ich bisher gemacht habe, Probleme, denen ich begegnet bin, Lösungen, die ich versucht habe:

  1. Ich habe meinen Frame zu einem Paket hinzugefügt, meinen Frame mit RegisterClass und RegisterNoIcon. registriert. Problem: Wenn ich in ein anderes Projekt gehe und versuche, einen abgeleiteten Frame zur Bearbeitung zu öffnen, heißt es es kann meinen ursprünglichen Rahmen nicht finden.
  2. Um das Problem "1" zu beheben, musste ich meinen Frame als Custom Module registrieren. Also habe ich RegisterCustomModule(TMyFrameName, TCustomModule) aufgerufen. Problem: Vom "anderen" Projekt aus öffne ich einen abgeleiteten Frame, die IDE erstellt nicht die Komponenten in meinem ursprünglichen Frame und die IDE beschwert sich über eine der "ererbten" Komponenten, die fehlen.
  3. Um "2" zu beheben, dachte ich, ich würde der IDE helfen, indem ich InitInheritedComponent(Self, TFrame) aufruft. Dies half mir, als ich versuchte, den Rahmen im "anderen" Projekt zu öffnen, alles wurde neu erstellt und ich konnte den Rahmen sehen, wie ich es erwartet hatte. Problem: Wenn ich den Rahmen speichere, vergisst er alles über die geerbten Komponenten und behandelt jede einzelne Komponente als eine neue Komponente, die diesem bestimmten Rahmen hinzugefügt wird. Wenn ich in den gespeicherten DFM schaue, beginnt alles mit "Objekt", nichts beginnt mit "geerbt", wie ich es erwarten würde.

Leider bin ich beim Problem "3" hängen geblieben. Ich habe versucht, in Classes.pas, ToolsAPI, DesignIntf ​​und DesignEditors zu graben, fand aber nichts hilfreiches. Offenbar wurde das "geerbte" Attribut, das ich im DFM sehen wollte, von TWriter erzeugt, wenn die "TWriter.Ancestor" -Eigenschaft vor dem Streaming einer TComponent zugewiesen wird, aber es gibt keine Möglichkeit für mich, sie einzurichten, die IDE muss sie setzen oben. Und ich kann die IDE nicht davon überzeugen, es für mich zu tun.

Hier sind die kumulierten relevanten Teile des Codes:

%Vor%

Irgendwelche Ideen, beybded "geben Sie auf und legen Sie Ihre Sachen in Object Repository" ? Danke!

Bearbeiten

Warum muss ich das tun und warum Lösungen, die von tatsächlichen Pfadnamen abhängig sind, die in die Dateien meines Projekts geschrieben werden, nicht funktionieren: Ich möchte Branching unterstützen: Wenn man verzweigt, ist es vernünftig, mehrere Versionen desselben Projekts zu erwarten. lebendig "in verschiedenen Verzeichnissen auf der gleichen Maschine. Die Folge davon ist, dass ich nicht mehrere Versionen desselben Projekts gleichzeitig am selben Ort haben kann.

Damit das funktioniert, habe ich beschlossen, meine Projekte nicht davon abhängig zu machen, wo das Live ist, und um dies durchzusetzen, habe ich in unserem Team Clone (Mercurial Terminologie) oder Check Out (SVN Terminologie) unsere Projekte in verschiedenen Verzeichnissen. Ein fest codierter Pfad auf meinem System ist für das System meines Kollegen nicht gut: Wenn einer von uns den Fehler macht, irgendeine Art von Pfad in die Anwendung zu programmieren, wird es nicht lange dauern, bis er einen von uns bremst Der Fehler wird behoben.

Dies ist natürlich ein Problem mit Formularen und Rahmen, die Teil einer Bibliothek sind (also nicht in unserem Projektverzeichnis), von der wir erben müssen! Um IDE-Unterstützung zu bekommen, wenn wir mit diesen Dateien arbeiten, müssen wir sie temporär zum Projekt hinzufügen und wir müssen nicht vergessen, sie zu entfernen, nachdem wir fertig sind. Wenn wir Änderungen vergessen und einschieben / einchecken, bremsen die Änderungen den Build für unsere Kollegen (weil sie die Bibliotheken an verschiedenen Orten ausgecheckt haben).

Um dies zu lösen, habe ich versucht, diese Frames und Formulare zu einem Design-Zeitpaket hinzuzufügen (Pakete werden mit dem vollständigen Pfad in die IDE geladen, aber der Pfad ist nicht Teil der Projektdateien, also ist es in Ordnung). Leider ist das gescheitert, und das ist der Grund, warum ich diese Frage gestellt habe.

    
Cosmin Prund 17.09.2010, 06:49
quelle

3 Antworten

3

Es gibt ein paar Aspekte zu diesem Problem:

  • Verwenden von Frames aus einem Paket zur Entwurfszeit, um sie in Formulare einzufügen.
  • Erstellen eines neuen Rahmens in einem Projekt, das von einem Rahmen in einem Paket erbt.
  • Ermöglichen, dass verschiedene Projektverzweigungen unterschiedliche Versionen des Pakets und damit die Rahmen verwenden, ohne mit fest codierten Pfaden in dpr oder dproj konfrontiert zu werden.

Aktivieren Sie verschiedene Projektzweige, um verschiedene Versionen Ihrer eigenen Pakete zu verwenden

  • Erstellen Sie eine Umgebungsvariable in der Delphi-IDE mit Tools | Optionen | Umgebungsvariablen und verweisen Sie auf den Ordner, in dem sich die Frames für Ihren aktuellen Zweig befinden. Für diese Diskussion nennen wir diese Umgebungsvariable "MyLib" und verweisen sie auf einen Ordner "D: \ Whatever \ Version1".
  • Gehen Sie in den Registrierungseditor und exportieren Sie diesen Eintrag in eine Datei "MyLibEnvironmentVariable.reg". Fügen Sie diese Datei der Quellcodeverwaltung hinzu und bearbeiten Sie sie, um alle anderen Umgebungsvariablen zu entfernen, die sich auch unter demselben Registrierungsschlüssel befinden.
  • Exportieren Sie den Inhalt des Known Packages-Schlüssels Ihrer Delphi-Installation.
  • Bearbeiten Sie die exportierte Datei - Entfernen Sie alle Werte, die nicht Ihre eigenen Pakete sind. - Ändern Sie die Werte Ihrer eigenen Pakete von zum Beispiel D:\Whatever\Version1\xxx.bpl in $(MyLib)\xxx.bpl .
  • Entfernen Sie alle Schlüssel, die auf Ihre eigenen Pakete verweisen, aus dem Schlüssel "Bekannte Pakete" und importieren Sie die gerade bearbeitete Datei. Dies ändert effektiv Ihre Paketregistrierungen, um die MyLib var zu verwenden und stellt sicher, dass die IDE jetzt auch die MyLib var verwendet, um Ihre Pakete zu finden.

Frames aus einem Paket zur Entwurfszeit verwenden

  • Erstellen Sie ein Paket "LibraryPackage" und speichern Sie es im Ordner D: \ Whatever \ Version1.
  • Fügen Sie einen Rahmen "LibraryFrame" hinzu und speichern Sie ihn im Ordner D: \ Whatever \ Version1.
  • Setzen Sie einige Steuerelemente auf den Rahmen oder geben Sie ihm eine hässliche Farbe, damit Sie ihn visuell erkennen können.
  • Fügen Sie der LibraryFrame-Einheit eine Register; -Prozedur hinzu und fügen Sie in ihrer Implementierung RegisterComponents('MyFrames', [TLibraryFrame]); hinzu.
  • Erstellen Sie das Paket und installieren Sie es in der IDE.
  • Entfernen Sie den verschlüsselten Pfad zu diesem Paket aus dem Bibliothekspfad der Umgebungsoption und / oder ändern Sie ihn zur Verwendung der $ (MyLib) -Umgebungsvariablen.
  • Ändern Sie den Registrierungseintrag für dieses Paket so, dass die Umgebungsvariable MyLib verwendet wird.
  • Der Rahmen ist immer noch nicht unter Tool Palette | verfügbar Frames, aber es wird von seiner eigenen MyFrames Tool Palette-Seite verfügbar sein, und Sie können es in beliebigem Formular einschließen. Die IDE fügt den Einheitennamen des Rahmens zur uses-Klausel des Formulars hinzu. Es sollte nichts zu dem dpr hinzufügen, aber es kann immer noch einen vollständig fest codierten Pfad zu Ihrem dproj hinzufügen. Um dies zu vermeiden, müssen Sie den bpl-Pfad exportieren und ändern, um $ (MyLib) / Doppelklicktrick für dieses Paket zu verwenden.

Vererbt von einem Rahmen in einem Paket

Nun, da alle oben genannten Einstellungen vorgenommen wurden, ist der Frame aus dem Paket immer noch nicht verfügbar, um von einem anderen Projekt als der Bibliothek, in der er erstellt wurde, übernommen zu werden. Es ist jedoch jetzt ziemlich einfach, sie für die Vererbung verfügbar zu machen. Fügen Sie einfach LibraryFrame_fr in 'LibraryFrame_fr.pas' {LibraryFrame}, zu Ihrem Projekt dpr hinzu und der Rahmen wird nun in der Liste "vererbbare Objekte" angezeigt, wenn Sie "Hinzufügen Neu | Andere" verwenden, um etwas zu Ihrem Projekt hinzuzufügen.

Leider, wenn Sie es auswählen, wird sich die IDE beschweren: Cannot open file "D:\Whatever\SecondFormReusingFrame\LibraryFrame_fr.pas". The system cannot find the file specified.

Offensichtlich erwartet es jetzt den LibraryFrame im Projektordner, anstatt zu versuchen, ihn im MyLib-Ordner zu finden. Die IDE redigiert auch den TLibraryFrame-Typ im Formular, obwohl Strg-Klick die richtige Datei anzeigt ...

Ändern von LibraryFrame_fr in 'LibraryFrame_fr.pas' {LibraryFrame}, zu %Code% hilft insofern, als die IDE sich nun nicht mehr darüber beschwert, das LibraryFrame_fr.pas nicht zu finden. Es hat aber den Effekt, dass die IDE "freundlicherweise" den relativen Pfad ändert, wenn Sie alles speichern. In meinem Fall $(MyLib)\LibraryFrame_fr in 'LibraryFrame_fr.pas' {LibraryFrame}, , das das gesamte Objekt der Übung besiegt, da es die Abhängigkeit von Pfadnamen wieder einführt, wenn auch nur teilweise.

Allerdings bleibt ..\FrameToBeReusedSecond\LibraryFrame_fr in 'LibraryFrame_fr.pas' {LibraryFrame}, im dpr nicht wirklich eine Option. Wenn Sie das Projekt erneut laden, beklagt sich die IDE darüber, den Rahmen nicht gefunden zu haben, obwohl er im Suchpfad gefunden wurde.

Auch wenn es so bleibt und die IDE-Beschwerde ignoriert wird, wenn man von diesem Rahmen ableitet, ist das nicht wirklich eine Option. Die IDE fügt kein entsprechendes dfm hinzu ... Und während Sie die Verwendungen im dpr von LibraryFrame_fr in 'LibraryFrame_fr.pas' {LibraryFrame}, bis MyOwnFrame_fr in 'MyOwnFrame_fr.pas' bearbeiten und einen dfm-Stubb manuell hinzufügen können, wird die IDE immer noch verwirrt, weil sie LibraryFrame_fr.pas nicht finden kann ...

Alles in allem Cosmin, es scheint, die IDE ist nur ein bisschen zu viel drin, was sie will und erwartet. Ich denke, was Sie wollen, ist erreichbar, aber nur, wenn Sie bereit und in der Lage sind, Ihre Bibliotheksordner immer an demselben relativen Ort wie Ihre Projekte zu haben.

    
Marjan Venema 18.09.2010 13:43
quelle
1

Uh, was ist falsch daran, einfach den Frame, den Sie wiederverwenden möchten, zu dem Projekt hinzuzufügen, in dem Sie ihn wiederverwenden wollen?

z.B.

  • Project1.dpr verwendet Form1 und Frame1, Sie möchten Frame1 wiederverwenden.
  • Starten Sie das neue VCL-Formularprojekt in einem anderen Ordner.
  • Wenn Sie auf Frames auf der Seite "Standard" der Tool-Palette klicken, wird angezeigt, dass keine vorhanden sind.
  • Fügen Sie diesem Projekt Frame1-Einheit über den Projektmanager hinzu (damit es zur Verwendungsliste im dpr hinzugefügt wird).
  • Wenn Sie nun auf Frames auf der Seite "Standard" der Werkzeugpalette klicken, wird Frame1 zur Auswahl angezeigt.
  • Und klicken Sie mit der rechten Maustaste auf das Projekt im Projektmanager und wählen Sie dann Hinzufügen | andere und gehen zu "vererbbaren Elementen", zeigt auch Frame1 als ein vererbbares Element.

Bearbeiten

Wenn Sie den fest codierten Pfad nicht in dpr in den Frame einschließen möchten, müssen Sie immer die Umgebungsvariablen der IDE verwenden.

  • Gehe zu Extras | Optionen | Umgebungsvariablen.
  • Fügen Sie eine var MYLIB hinzu und zeigen Sie sie auf den Ordner an, der für die Zweigstelle gilt, in der Sie sich gerade befinden.
  • Fügen Sie Ihren Quellen eine Datei hinzu, die den Ordnerpfad enthält, und fügen Sie sie der Quellcodeverwaltung hinzu. Dies könnte ein Export des Registrierungsschlüssels sein, der jetzt den Wert von MYLIB enthält.
  • Fügen Sie dem Bibliothekspfad Ihres Projekts $ (MYLIB) hinzu.
  • Fügen Sie die Frames zu Ihrem Projekt hinzu. Sie sollten nun ohne den Pfad in den dpr eingefügt werden (weil sie im Bibliothekspfad gefunden werden können).
  • Bei der Integration von Verzweigungen: Stellen Sie sicher, dass die Quelldatei mit dem Wert für MYLIB entsprechend geändert wird.
  • Beim Wechseln von Verzweigungen: Aktivieren Sie den richtigen Wert für MYLIB. Wenn Sie der Quellcodeverwaltung eine REG-Datei hinzugefügt haben, doppelklicken Sie einfach darauf, um den Schlüsselwert der MYLIB-Registrierung zu ändern.
Marjan Venema 17.09.2010 07:31
quelle
0

Als wir den Build-Prozess aus der letzten Firma, für die ich gearbeitet habe, erstellt haben, wollten wir genau dasselbe machen. Wir verwenden Subversion und hatten ein Projekt für unsere freigegebenen Komponenten, die ein (Finalbuilder-) Projekt enthielten, um all unsere geteilten Pakete zu erstellen.

Ich habe dann eine ähnliche Technik wie Marjan (MyLib) verwendet. Und starten Sie Delphi aus einer Batch-Datei mit den neuesten Komponenten.

Am Ende fanden wir, dass es nicht notwendig war. Die veröffentlichten Eigenschaften unserer Hauptrahmen haben sich so selten geändert, dass wir nur einen installierten Satz von Paketen verwendet haben, sagen wir in

c: \ BDS \ Komponenten \ D12 \ Bpl (Dies kann von Entwickler zu Entwickler anders sein)

Aber der Code, der in

saß

c: \ BDS \ MeinProjekt \ Freigegeben war beim Kompilieren immer mit verlinkt, da dies beim Erstellen des Projekts auf dem relativen Suchpfad lag

c: \ BDS \ MeinProjektExperimental würde beim Aufbau auch den korrekt verzweigten Code verwenden.

Wir haben das Problem mit dem Repository gelöst, indem wir CodeSmith (einen Code-Generator) zum Generieren der Frames verwendet haben, mit dem zusätzlichen Vorteil, dass sie in den richtigen Ordner mit korrekten Namenskonventionen (und allen branchenspezifischen Änderungen) eingefügt werden. Wir haben dies als Zeiteinsparung für uns getan, aber wir (durch Zufall) vermieden dieses Problem alle zusammen.

Die CodeSmith-Vorlagen haben ein wenig Zeit in Anspruch genommen, um das erste Bild zu erstellen, aber dann haben wir es leicht angepasst, um andere Unterklassen ohne zu viele Gehirnzyklen zu erstellen (für Dinge wie dataModules).

cfEditFrame.dfm.cst

%Vor%

cfEditFrame.cst - Das eine Skript, das wir aufrufen mussten, um einen neuen Unterklassenrahmen zu erzeugen

%Vor%

Es kann andere Quellcode-Generatoren geben, die das genauso gut machen, wenn nicht sogar besser. Wir hatten CodeSmith und verwendeten es daher. Hoffentlich sind die obigen Dateien korrekt formatiert. Ich bin ein SO-Neuling und die hoffentlich Wiedergabe von HTML-Code ist korrekt.

Wenn Sie sowohl Eigenschaften als auch Komponenten für diese Frames haben, die Sie erben möchten, müssen Sie etwas Seltsames tun. Sie müssen es in zwei Schritten tun. Zuerst müssen Sie die Rahmeneigenschaften in der ersten Klasse hinzufügen und DANN fügen Sie die Komponenten in einer Unterklasse hinzu.

Zum Beispiel fügen wir die benutzerdefinierten Eigenschaften in cfBaseEditFrames.TcfBaseEditFrame hinzu.

Wir untergliedern das dann in cfEditFrames.TcfEditFrame = class (TcfBaseEditFrame). Hier fügen wir unsere Komponenten hinzu (in unserem Beispiel eine TActionList und TImageList)

Bei der Registrierung in einem Paket haben wir

hinzugefügt

RegisterCustomModule (TcfBaseEditFrame, TWinControlCustomModule);

Wir stellen dann sicher, dass dieses Paket in unserer Projektgruppe ist und es kein Problem gibt, neu unterklassierte Frames zu öffnen.

Eine letzte Anmerkung, aus dem Speicher war es wichtig, dass der Nachfahrerrahmen (TcfEditFrame) derjenige war, der Komponenten hinzufügte. Sie konnten keine Komponenten in TcfBaseEditFrame und Eigenschaften in TcfEditFrame hinzufügen.

BaseEditFrames.pas

%Vor%

BaseEditFrames.dfm

%Vor%

EditFrames.pas

%Vor%

EditFrames.dfm

%Vor%

FramePackage.dpk

%Vor% %Vor%

Sie müssen dieses Entwurfszeitpaket installieren. Sie könnten dann einen Rahmen in einem anderen Projekt wie dem folgenden haben

EditFrameDescendants.pas

%Vor%

EditFrameDescendants.dfm

%Vor%

Sie sollten in der Lage sein EditFrameDescendant zu öffnen, seine erstaunliche "NewFormProperty" zu bearbeiten und Aktionen zu seiner Aktionsliste hinzuzufügen. Funktioniert für mich .... Viel Glück

    
Clint Good 21.09.2010 07:17
quelle