![]() |
Feststellen ob Anwendung die VCL verwendet
Hallo,
ich habe ein kleines Problemchen: Abhängig davon, ob eine Delphi Anwendung die VCL verwendet oder nicht, möchte ich entweder TThread.Synchronize verwenden oder eine eigene Non-VCL Methode. Um festzustellen, ob die VCL initialisiert ist oder nicht, müsste ich aber die Unit "Forms" einbinden, was bekanntermaßen die VCL automatisch initialisiert und die Größe der ausführbaren Datei aufbläht. Momentan verwende ich folgenden Code, ich habe jedoch berechtigte Zweifel (TComponent wird erst mit der Registration von "TMenuItem" registriert), ob dieser Code mit allen Delphi-Versionen funktioniert:
Delphi-Quellcode:
Gibt es eine (zuverlässige) Möglichkeit festzustellen (entweder zur Compile- oder zur Laufzeit) ob die Anwendung die VCL (ich meine damit das vorhanden sein von TApplication) verwendet? Die Units "SysUtils" und "Classes" dürfen dabei verwendet werden.
function AcVCLActive: Boolean;
begin //The VCL can only be active, if the TComponent class is registered result := GetClass('TComponent') <> nil; end; Schonmal vielen Dank, Andreas |
Re: Feststellen ob Anwendung die VCL verwendet
Zur Laufzeit:
Delphi-Quellcode:
function IsVclApplication:Boolean;
begin Result := Assigned(Classes.FindGlobalComponent); end; |
Re: Feststellen ob Anwendung die VCL verwendet
Danke für die schnelle Antwort.
Leider scheinen neuere Delphi-Versionen mehrere "FindGlobalComponentProcs" zu unterstützen und die FindGlobalComponent-Funktion ist nun statisch in der Classes-Unit vorhanden:
Delphi-Quellcode:
Ich hatte auch schon vorher mit dieser Funktion herumgespielt, doch leider ist dabei nichts brauchbares entstanden...
function FindGlobalComponent(const Name: string): TComponent;
var I: Integer; begin Result := nil; if FindGlobalComponentProcs <> nil then begin for I := FindGlobalComponentProcs.Count - 1 downto 0 do begin Result := TFindGlobalComponent(FindGlobalComponentProcs[I])(Name); if Result <> nil then Exit; end; end; end; Die "FindGlobalComponentProcs"-Liste ist leider nur privat für die Classes unit. Edit: Kann ich vielleicht irgendwie über die RTTI an alle vorhanden Klassen kommen, die von TPersistent abgeleitet sind? |
Re: Feststellen ob Anwendung die VCL verwendet
Vielleicht geht das ja.
Allerdings weiss ich nicht, ab wann dieses Compiler-Konstrukt funktioniert, hab nur D2010 zur Hand.
Delphi-Quellcode:
function AcVCLActive: Boolean;
begin {$IF Defined(TApplication)} Result := True; {$ELSE} Result := False; {$IFEND} end; |
Re: Feststellen ob Anwendung die VCL verwendet
Zitat:
Dieses Konstrukt wird unter D7 Pro kompiliert, aber es wird false rückgemeldet |
Re: Feststellen ob Anwendung die VCL verwendet
@H4ndy: Dieses prüft nur ob TApplication an der Codestelle verfügbar wäre.
Wobei ihm auch noch TApplication egal ist. Mit Definied(TComponent) würde auch sowas geprüft und am Ende ist dieses Ergebnis vollkommen irrelevant, da dieses nicht aussagt, ob diese Klasse auch verwendet wird, abgesehn davon, daß man dafür auch noch die böse Forms-Unit einbinden muß, mit dem Ergebnis, daß man gleich TRUE zurückgeben kann. :roll: |
Re: Feststellen ob Anwendung die VCL verwendet
@himitsu Ach stimmt, das sagt ja dann leider nix ueber die gesammte Anwendung aus :/
Forms muss man nicht dafuer einbinden, da das Defined() und Declared() eine reine ![]() Andere Frage: Kann man nicht einfach immer die NonVCL-Routine nutzen? |
Re: Feststellen ob Anwendung die VCL verwendet
Zitat:
aber um auf diese Weise z.B. TComponent prüfen zu können, muß man die entsprechende Unit einbinden. @Lösung: Du könntest eventuell nachsehn, ob irgendwelche von der VCL verwendete/benötigte Resourcen vorhanden sind. |
Re: Feststellen ob Anwendung die VCL verwendet
Vielen Dank schonmal für die ganzen Antworten.
Zitat:
In meiner alten Version des Codes, habe ich entsprechend einen Compilerswitch eingefügt, der explizit aktiviert werden muss, sobald man die VCL nicht verwendet. Da ich das Ganze nun neu geschrieben habe, möchte ich es so einfach verwendbar wie möglich haben. Und bevor jemand auf die Idee kommt das Vorzuschlagen: Die Synchronisation kann auch recht einfach vom Anwender selbst geschehen, er muss dann nur eine Funktion in einem Timer/Schleife/Was auch immer aufrufen. Zitat:
Nochmal Danke, vielleicht hat jemand noch eine Zündende Idee, Andreas |
Re: Feststellen ob Anwendung die VCL verwendet
Eine zündene Idee, wie der Anwender doch mithilft.
PS: Nur weil die VCL eingebunden ist, muß sie bei den Events dennoch keine Rolle spielen. Bau doch einfach ein Feld/Property in deiner Komponente ein, wo man den SyncMode wählen kann. (per Standard auf VCL-Synchronize ... sicher ist sicher, falls man das Setzen vergist) |
Re: Feststellen ob Anwendung die VCL verwendet
Zitat:
Delphi-Quellcode:
...beim Programmstart einen eigenen Prozessor für die Events festlegen oder auf den oben beschriebenen manuellen Modus umschalten. Macht man gar nichts wird bei der ersten Verwendung der Notify-Funktionalität der Standard ausgewählt. Entweder der TAcVCLNotifyProzessor oder eben der TAcNonVCLNotifyProcessor.
{Allows you to set an own instance of a notification processor. This method has to be called before any other notification system procedure has been used.
@seealso(TAcNotifyProcessor)} procedure AcNotifyManualSetProcessor(ANotifyProcessor: TAcNotifyProcessor); {If you've initialized the notification queue system using the AcNotifyManualInit function, you must use this function to synchronize the notifications with the thread calling AcNotifyManualProcessQueue. @seealso(AcNotifyManualInit)} procedure AcNotifyManualProcessQueue; {Initializes the notification system with TAcManualNotifyProcessor, allowing you to use the AcNotifyManualProcessQueue function. @seealso(AcNotifyManualProcessQueue)} procedure AcNotifyManualInit; Ich möchte eben nur irgendwie automatisch den Standardprozessor setzen... |
Re: Feststellen ob Anwendung die VCL verwendet
Also letztlich geht es ja um die Synchronize-Methode, oder? Wäre es da nicht u.U. einfacher zu prüfen, ob die "Maschinerie", die den internen Synchronize-Queue abarbeitet, existiert, als zu prüfen, ob die VCL eingebunden wurde? Ich habe da beim Überfliegen der Synchronisations-methoden in der Unit Classes den globalen Funktionszeiger "WakeMainThread" gefunden. Auf den ersten Blick scheint er ein ganz gutes Indiz zu sein:
Delphi-Quellcode:
Ich habe es nur kurz anhand einer neu erstellten VCL-Applikation bzw. einer leeren Konsolenapplikation getestet, dort lieferte der Test aber jedenfalls das korrekte Ergebnis.
if Assigned(WakeMainThread) then
// VCL else // NonVCL |
Re: Feststellen ob Anwendung die VCL verwendet
Hallo,
dein Code funktioniert - auch mit Lazarus wird korrekt auf das vorhandensein der LCL (bzw. eines Handlers für Synchronize, was in der Tat das ist, was ich eigentlich möchte) hingewiesen. :thumb: Vielen Dank, Andreas |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:24 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