![]() |
RuntimePackage laden/verwenden
Hallo Leute,
ich möchte hier für mein Problem ein neues Thema aufmachen. Begonnen hatte ich mit einer Antwort (eher weiteren Frage) in BaBuSE's Thread ![]() Für den benannten Thread und deren Titel ist die Frage beantwortet. Mein Problem aber leider nicht. Somit möchte ich hier einen neuen Thread als offene Frage aufmachen. Hier noch mal das, was ich machen will: Ich habe folgende Module: - BasePackage (enthält die Basisformulare und Komponenten; erstellt für Runtime und Designtime) - SpezialPackage (enthält spezielle Formulare als Nachfahren der Basisformulare aus BasePackage; erstellt für Runtime) - MyApp (enthält Nachfahren aus BasePackage und soll spezielle Formulare mittels LoadPackage aus SpezialPackage verwenden) Dabei muß ich in MyApp mittels GetClass sowohl für die Formulare und Komponenten in BasePackage und in SpecialPackage arbeiten. Alle benötigten Klassen sind mittels RegisterClass im initialization-Teil der Units registriert. Mein aktuelles Problem stellt sich wie folgt das (letzer Beitrag von mir in MaBuSE's Thread): Zitat:
Wenn jemand helfen oder einfach Licht ins Dunkel bringen kann ... Jedwede Hilfe wird dankbar angenommen. Gruß oki |
Re: RuntimePackage laden/verwenden
Zwischenzeitlich hat sich herausgestellt, dass mit der Anwahl "Laufzeit-Packages verwenden" eindeutig nur Laufzeitpackages von der Exe verwendet werden. Damit ist mein Verdacht hier im "Mischbetrieb" zu fahren widerlegt.
Gut so! Mein Problem ist damit aber noch nicht behoben, Schlecht so! Beim Debuggen habe ich festgestellt, dass in der IDE die "blauen Punkte" an der linken Seite (also die compilierten Codezeilen) einen Zeilenversatz haben. Das passiert an der Stelle, wenn ich das Package geladen habe und bei zeilenweiser Abarbeitung mit dem Debugger dieser in eine Unit des Packages springt. Das heisst, der Debugger markiert in den Units beim debuggen die falschen Zeile. Breakpoints sind somit für die Katz! Im Ablauf ist das so, ich setze in meiner Exe einen Breakpoint vor dem Code zum Laden des Modules (LoadPackage). Steppe dann per Einzelschritt weiter bis ein Aufruf im Code einer Unit meines Packages aufgerufen wird. Der Debugger springt in das richtige Fenster, aber dort ist alles versetzt. Der code wird auch nicht richtig ausgeführt. Ich hab es getestet, indem ich die Unit in die Anwendung eingebunden habe und das ganze ohne Package laden ausprobierte. Da war alles korrekt. Nur wenn ich das Package zur Laufzeit nachlade entsteht der Käse. Kennt jemand diese Erscheinung? Gruß oki |
Re: RuntimePackage laden/verwenden
Musst du unbedingt Formulare vererben oder könntest du dir vorstellen auch andere objektorientierte Techniken zu verwenden?
Mein Erfahrung mit abgeleiteten Formularen ist, dass man dies besser vermeiden sollte. Gründe: * Änderungen im Basisformular können den Code in den abgeleiteten Formularen brechen * unbeabsichtigte Änderungen (z.B. Verschieben eines Controls um wenige Pixel) auf dem abgel. Formular machen Probleme * Zur Entwicklungszeit blockieren sich die versch. Instanzen der Formulare gegenseitig. Projekt schliesen und neu öffnen muss immer wieder durchexerziert werden |
Re: RuntimePackage laden/verwenden
Hi schmia,
der Weg der Vererbung der Formulare ist erst mal der, den ich eingeschlagen habe. In der Regel liegen kaum weitere Komponenten auf den Basisformularen. Sie dienen eigentlich als spezialisierte Vorlagen, um das Erstellen von Anwendungen einfacher zu gestalten und ein durchgängiges Grunddesign sicher zu stellen. Natürlich neben weiteren Grundfunktionalitäten. Für andere Techniken bin ich immer offen. Ich fand halt keine passenden für die gewünschten Anforderungen. Für den Bereich der Vererbung von Formularen gebe ich dir vollkommen recht. Damit muss ich leben. Das aktuelle Problem kommt eigentlich aus einer anderen Ecke. Ich will für den internen Gebrauch ein Tool erstellen, in das man die spezialisierten Packages laden kann. Das Basispackage soll eigentlich nicht mehr verändert werden. Damit ich das Tool nicht jedesmal neu kompilieren muss wenn ein neues Package vorliegt will ich diese nachladen können. Dabei muss ich aber über die Klasseninformationen gehen. Beispiel. Ein neues Formular liegt im neuen Spezialpackage vor, das ein Nachfahre vom BaseForm in Basepackage ist. Wenn ich dieses in meinem Tool creieren und anzeigen will mache ich folgendes:
Delphi-Quellcode:
Entladen wird das Package an anderer Stelle.
procedure TSettingsMainForm.TATBPLFormsLoad;
var AFormClass: TPersistentClass; // hier könnte man auch TFormClass nehmen, spaart man weiter unten das Casten AForm : TForm; FormList: TStringList; Counter: Integer; begin if FBPLModule <> 0 then TATBPLFormsUnload; if not FileExists(FSettingsProject.TATBPLName) then Exit; FBPLModule := LoadPackage(FSettingsProject.TATBPLName); if FBPLModule <> 0 then begin @GetBPLFormClasses := GetProcAddress(FBPLModule, 'GetBPLFormClasses'); if @GetBPLFormClasses = nil then Exit; try FormList := TStringList.Create; GetBPLFormClasses(FormList); // Liste aller Formularklassen aus dem Package holen for Counter := 0 to FormList.Count - 1 do begin AFormClass := GetClass(FormList.Strings[Counter]); if Assigned(AFormClass) then begin Application.CreateForm(TComponentClass(AFormClass), AForm); AForm.Show; end; end; finally FreeAndNil(FormList); end; end; end; Also, wenn du andere Ideen hast, gerne her damit. Sollte mein Anwendungsfall nicht verständlich genug sein, liefer ich mehr. Da das mit dem den Laufzeitpackages jetzt aber wohl klar ist und die Sache prinzipiell klappen müßte, würde ich das auf diesem Weg schon gerne hin bekommen. Gruß oki |
Re: RuntimePackage laden/verwenden
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Eine Möglichkeit wäre Frames zu verwenden. Ich habe z.B. einen "NavigatorFrame" auf vielen meinen Formularen. Es ist eine Zusammenfassung von DBNavigator und einem Suchen- ,OK- und Abbrechen-Button. Dann gibt es bei mir z.B. einen LoggingFrame: Eine Memo für Textmeldungen + Combobox für das Datumsuhrzeitformat + Combobox für einen Filter Info, Warnungen oder Fehler. Man sollte die Frames aber nicht überfrachten. Auch das Ableiten von Frames kann ich nicht empfehlen; das macht nur Probleme. Eine andere Möglichkeit wäre eine Form-Factory. Anstatt überall folgenden Code zu verwenden:
Delphi-Quellcode:
lässt man die Formulare indirekt erzeugen:
Form42 := TForm42.Create(nil);
Delphi-Quellcode:
Die Methode CreateForm() kann z.B. so aussehen:
Form42 := TFormFactory.CreateForm(TForm42, nil) as TForm42;
Delphi-Quellcode:
Man kann mehrere Factory-Methoden verwenden.
class function TFormFactory.CreateForm(AClass: TComponentClass;Owner: TComponent): TComponent;
begin Result := AClass.Create(Owner); With(TForm(Result) do begin // Formulare sollen nicht an festen Positionen erscheinen; das soll Windows machen if Position = poDesigned then Position := poDefaultPosOnly; // jedes Formulare wird um ein SystemMenu erweitert, // damit alle Formulare zusätzlich den Eintrag "Screenshot" und "Drucken" bekommen AddSpecialSystemMenue(Handle); end; end;
Delphi-Quellcode:
Die Möglichkeiten sind vielfältig.
class function TFormFactory.CreateModalDialogForm(AClass: TComponentClass;Owner: TComponent): TComponent;
begin Result := CreateForm(AClass, Owner); With(TForm(Result) do begin // alle Formulare, die für einen modalen Dialog gedacht sind // sollen ROT sein Color := clRed; // ausserdem sollen diese Dialoge ein besonderes Icon bekommen Icon := MyWarningIcon; end; end; Man kann z.B. mit einer Funktion über alle TLabels des gerade erzeugten Formulars gehen und Font.Name auf einen bestimmten Wert setzen. Und schon haben alle Labels einen bestimmten Font auch wenn sie zur Entwicklungszeit auf "MS Sans Serif" waren. |
Re: RuntimePackage laden/verwenden
Hi shmia,
sorry, dass ich noch nicht geantwortet habe, aber mein Rechner ist diese Woche abgeka... Da hatte ich etwas Stress. Das Thema Frames ist mir leider etwas unsympathisch geworden. Ich habe eigentlich fast nie mit Frames gearbeitet, außer in einem Projekt vor ca. einem Jahr. Das hat mir die Laune an Frames echt verhagelt. Das was du vorstellst ist nicht schlecht, aber für eine Umstellung ist der Code etwas zu weit bei mir. Da ich im Moment denke, dass ich mit den Packages nun erst mal nichts mehr falsch mache (hoffe ich zumindest) möchte ich schon raus bekommen, was da beim laden schief läuft. Ich teste mal weiter. Dank für deine Mühe, Gruß oki |
Re: RuntimePackage laden/verwenden
Hi Leute,
das war ein Kampf. Hab den Fehler gefunden! :hello: Mit den Packages und deren Umgang ist alles korrekt. Der Fehler war an einer anderen Stelle. In meinen Units waren die Zeilenumbrüche nicht korrekt. Mann will es kaum glauben. Nachdem ich den Fehler auf drei anderen Rechnern mit unterschiedlicher Delphi-Installation nachvollziehen konnte hab ich mir die Mühe gemacht und mir meine Units mit einem HEX-Editor angeschaut. Mein Verdacht waren versteckte "Steuerzeichen". Dabei habe ich ein $0D$0D sowie ein einzelnes $0D anstatt eines $0D$0A als Zeilenumbruch gefunden. Nachdem ich dies geändert hatte (im Hexeditor) war alles Bestens. Der Versatz war weg, die Programme und Runtimepackages laufen zur vollsten Zufriedenheit. Debuggen: bestens. Wie dieser Fehler da rein kam ist mir aber immer noch ein Rätzel. Ich habe die Units ausschließlich mit Delphi geöffnet. Auch CodeGear hat darauf noch keine Antwort gegeben. Ich glaube zu wissen, dass bei HTML und Linux $0D als Zeilenumbruch verwendet wird. Habe den verwendeten Code aber definitiv selber geschrieben und nicht irgendwo her kopiert. Das einzige, was ich zwischendurch gemacht habe waren mehrere Refactorings. Ich hoffe nicht, dass da der Fehler steckt. Wer diesen Fehler hat und zu faul ist das mit einem Hex-Editor zu machen, der kann die Unit auch in einem einfachen Texteditor laden und wieder speichern. Das sollte diese Fehler automatisch korrigieren. Ich hatte mir erst ein kleines eigenes Tool geschrieben in dem ich meine Units in ein Memo lade. Dort wollte ich dann entsprechende Such- und Korrigiermethoden implementieren. Dabei habe ich festgestellt, dass das Memo die benannten Fehler automatisch korrigiert. Ich brauchte die Unit dann nur noch unter dem gleichen Namen speichern und alles war paletti. Dann schönen Gruß, oki |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:45 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