Non GUI Application

Rund um die LCL und andere Komponenten
Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Ein package kann auch IDE Menüs ändern man kann damit ne ganze menge machen. Schau dir z.b. mal das IDE Printing package an das eine Druckfunktion zum Source Window kontext menü hinzufügt. Man kann eigentlich in alle IDE Menüs etwas einfügen.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Beitrag von mschnell »

Wo soll ich mir das angucken ? (Ich habe die Druckfunktion schon vermisst.) Muss ich vermutlich irgendwo downloaden ?!?!

-Michael

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Findet sich in der mailkinglist und ich hab sie jemandem der mal zu faul war sie runterzuladen hier an nem beitrag angehängt. Wenn dus net findest sag bescheid !
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6212
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Beitrag von af0815 »

@Christian
Als Programmier Beispiel OK zum arbeiten nein. Ich hätte einen Din A0 Plotter benötigt für die Ausdrucke. Das Skalieren ist noch nicht wirklich ausgreift, zumindesten nicht mit meinen Druckern.

@mschnell
Wenns Du sie auf der Mailingliste suchst, dann mit den richtigen Schlüsselworten.

@Christian
Blind ja, faul entschieden nein.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Nimm das net so ernst, und zu dem plotter du hast ja den source ... :)
Also für mich hats noch nie nen grund gegeben sourcen auszudrucken. Und so hoch wei die nachfrage nach solcher funktionalität ist bin ich da wohl nicht der einzige.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Beitrag von mschnell »

mschnell hat geschrieben:Wenn nicht ein entsprechender Vermerk von ihm das verhindert, schicke ich Dir den Text.


Michael hat mich gebeten, das Dokument nicht weiterzugeben, Du musst ihn also selber ansprechen.

-Michael

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Beitrag von mschnell »

Christian hat geschrieben:schau dir erstmal an wie das da gelöst ist n daemon mit widgetsetbindungen wäre ja schwachsinn die laufen ja meisst auf servern ohne gui


Leider verwendet der "daemon stuff" eine Application nur zur Kommunikation mit dem "Windows Service Manager". Der eigentliche Daemon Code läuft als TThread und nicht als "Mainthread". deshalb gehen Timer Events etc. da nicht.

Ich bin aber im Gespräch mit Michael vC und vielleicht machen wir zusammen eine Erweiterung zum "daemon stuff", der das ermöglicht.

-Michael

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Aber Threads im allgemeinen gehen doch oder ? Damit lassen sich doch sehr einfach Timer implementieren
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
theo
Beiträge: 10498
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Irgendwie verstehe ich immer noch nicht, weshalb du in einer Dienstanwendung diesen ganzen GUI Krempel (TTimer, Synchronize, Sendmessage) imitieren möchtest.
Das geht doch viel einfacher mit Threads, Criticalsection, etc.
Die "getimeten Threads" kannst du doch aus dem Main Loop starten.
Ausserdem: Welche Events erwartest du den überhaupt von "aussen"?
Ausser TCP/IP Requests (Wenn es denn ein Server ist) kann ich mir da gar nicht viel vorstellen.

Ist nicht böse gemeint, ich kapier's bloss nicht.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Beitrag von mschnell »

theo hat geschrieben:Irgendwie verstehe ich immer noch nicht, weshalb du in einer Dienstanwendung diesen ganzen GUI Krempel (TTimer, Synchronize, Sendmessage) imitieren möchtest.


Ich möchte nicht, ich muss. Eine Delphi-Applikation soll so portiert werden, dass der endgültige Code der Funktionalen Teile (die als Komponenten getrennt von den GUI Teilen vorliegen), sowohl mit Delphi (für Windows PC mit GUI, leicht zu debuggen) als auch mit FP (für Linux ARM System ohne GUI) übersetzbar ist. Die Umgeung muss also an die (vorhandene) Software angepasst werden und nicht neue Software für eine existierende Umgebung geschaffen werden.

Außerdem ist es bei größeren Anwendungen durchaus sinnvoll, nicht mit vielen Threads sondern mit Events zu arbeiten, weil dann die hochgradig kritische inter-Thread-Synchronisation bei gemeinsam verwendeten Ressourcen wegfällt.
theo hat geschrieben:Das geht doch viel einfacher mit Threads, Criticalsection, etc.
Die "getimeten Threads" kannst du doch aus dem Main Loop starten.

Klar kann ich das, aber die Delphi-Applikation existiert schon und soll nur so schonend wie möglich protiert werden.
theo hat geschrieben:Ausserdem: Welche Events erwartest du den überhaupt von "aussen"?
Ausser TCP/IP Requests (Wenn es denn ein Server ist) kann ich mir da gar nicht viel vorstellen.

Das Programm korrespondiert über eine ganze Menge TCP-IP-Sockets und COM-Schnittstellen mit diversen weiteren Geräten. Jedes ankommende Byte (bzw Block) ist ein Event. Außerdem muss es auf jede Menge Zeitbedingungen reagieren, die jederzeit auftreten können, (echte getimete Ereignisse, Kommunikations-Timouts, ...) Und alle diese Kommunikationen hängen über gemeinsame Datenstrukturen zusammen.

-Michael

Benutzeravatar
theo
Beiträge: 10498
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Na gut.
Dann hoffe ich nur, dass du den Rahmencode, der die alles ermöglich spater der Community zur Verfügung stellst.
Insbesondere eine elegante Lösung für eine Systemunabhängige allgemeine Inter-Thread-Communication à la Sendmessage aber ohne Winapi etc. würde mich schon interessieren.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Beitrag von mschnell »

theo hat geschrieben:Dann hoffe ich nur, dass du den Rahmencode, der die alles ermöglich spater der Community zur Verfügung stellst.

Na klar. (Wenn die Free-Pascal-Betreuer es denn wollen.)
Meine Idealvorstellung ist es, eine Methode ztu finden, mit der man nicht nur eine "NonGuiApplication" erzeugen kann, sondern auch in einer "normalen" (GUI-) Applikation jeden Thread (bei dem man das denn möchte) mit einer Message-Queue ausstatten kann, so dass man da Funktionalitäten wie Timer etc. verwenden kann (ein "TApplicationThread" ist oder beinhaltet einen Nachfolger von TCustomApplicartion). Ein Platform-unabhängiger Inter-Thread-Message-Mechanismus entsteht dabei natürlich automatisch (allein schon wegen TThread.Synchronize).

Schließlich könnte ich mir (u.U. sogar als Sprach-Erweiterung) eine Art "Thread-Event" vorstellen. Hier soll es dann möglich sein, ein Event syntaktisch so ähnlich wie ein normales Delphi-Event (Klassen-Property eines beliebigen prozeduralen Typs) zu definieren, der Code in diesem Event läuft aber später als anderer Thread als der, der das Event "fired" (z.B. als der, der die Property gesetzt hat). Parameter lassen sich übergeben und Funktionsergebnisse und var-Parameter in einem Synchronisationsvorgang zurückgeben. Ein alter Traum von mir aber noch lange nicht "gar".

Ob die NonGuiApplication und die DaemonApllication von Michael vC zusammengefasst werden können/sollen, müssen wir noch diskutieren.
theo hat geschrieben:Insbesondere eine elegante Lösung für eine Systemunabhängige allgemeine Inter-Thread-Communication à la Sendmessage aber ohne Winapi etc. würde mich schon interessieren.

Die Sende-Seite ist kein großes Problem. Das sollte in Lazarus Platform-übergreifend existieren (Ich schaue am Dienstag, wenn ich wieder im Büro bin, nach.) Die Empfangs-Seite ist der "Dispatch"-Mechanismus (procedure .... message). Das ist Plattform-übergreifender Sprachumfang, aber eben nur für den Mainthread realisiert. Hier soll jeder TAplicationThread eine eigene Message-Queue bekommen. Die Message-Sende-Prozedur muss dann natürlich einen Parameter für den Ziel-Thread bekommen.

Es ist für einen Thread nur dann richtig sinnvoll, Messages empfangen zu können, wenn er wíe ein "Application" Main-Thread Event-ortientiert programmiert werden kann, also auf mehrere Events (=Messages) gleichzeitig warten kann. Dafür braucht man genau das angesprochene "TApplicationThread" Verfahren, das die Delphi-Entwickler merkwürdigerweise "verschlafen" haben. "Normale" TThreads sind natürlich absolut sinnvoll, wenn sie auf immer nur auf genau ein Ereignis warten (man kann für mehrere Ereigniss-Arten ja auch mehrere Threads anwerfen), Aber bei komplexen Synchronisationsaufgben ist ein TApplicationThread, der auf viele Ereignis-Arten reagieren kann, von Vorteil.

-Michael
Zuletzt geändert von mschnell am Mo 19. Feb 2007, 00:39, insgesamt 9-mal geändert.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Also für mich hört sich das ganz verdächtig nach pfusch an hrhr :)
Wenn die Anwendung so komplex ist gehört die in ne klassenstruktur in der man auch einfach mal die basis thread klaee oder die basis timer klasse austauschen kann. So mach ich das jedenfalls in diesem komplexitätsgrad.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Beitrag von mschnell »

Christian hat geschrieben:Wenn die Anwendung so komplex ist gehört die in ne klassenstruktur in der man auch einfach mal die basis thread klaee oder die basis timer klasse austauschen kann. So mach ich das jedenfalls in diesem komplexitätsgrad.

Also en Einwand verstehe ich nun überhaupt nicht. Was hat die Objekt-Orientierte Code-und Daten- Organisation in Klassen-Kontexten mit der Ablauf-Organisation in Threads-Kontexten zu tun ?
In einem TThread läuft "Execute" im Thread Kontext und fast alles andere (meist) im Main-Thread-Kontext. Trotzdem ist das alles in einer Klasse zusammengefasst, weil es logisch zusammenghört. Wenn Du z.B. Indy, Async-Pro, oder die "alten" Delphi Socket-Komponenten anschaust, werden da Klassen zur Verfügung gestellt, die mehrere Threads verwalten. Oft ist noch nicht einmal dokumentiert, in welchem Thread-Kontext die Ereignisse geschmissen werden, die man anmeldet. Bei Async-Pro z.B. werden die Ereignisse im Kontext des Threads geschmissen, der "open" macht und nicht dessen, der das Objekt instanziert. Das ist sehr sinnvoll, da man so das Objekt grafisch platzieren kann (es wird dann natürlich vom Mainthread kreiert) und trotzdem einen Thread benutzen kann, um auf die Ereignisse zu reagieren. Das ist aber - glaube ich - nirgendwo dokumentiert. Die machen also intern eine spezifische Ereignis-Queue auf. Das Verfahren möchte ich nun verallgemeinern und für den Programmierer leicht nutzbar machen. Zunächt durch einen Basis-Typ TApplicationThread, also "normal" Objekt-Orientiert. Später vielleicht durch ein zusätzliches Sprach-Konstrukt, um es noch Benutzer-freundlicher zu machen (wie gesagt ist das noch unausgegoren).

Es ist jedenfalls "Delphi-Tradition", dass Der Thread-Kontext unabhängig von der Daten- und Code-"Verwaltung" organisiert wird. Ich finde jedenfalls die momentane Methodik mit TThread.Execute sehr wenig Benutzerfreundlich und extrem verwirrend, weil man den Mainthread ereignisorientiert programmieren muss und man alle anderen Threads nicht ereignisorientiert programmieren kann .

-Michael

Benutzeravatar
theo
Beiträge: 10498
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Ja, so langsam kann ich mir einen Nutzen vorstellen.
Ich wäre wahrscheinlich selber niemals so an ein Problem herangegangen, aber es dämmert mir schon, dass es was werden könnte.
Es könnte aber auch ziemlich in die Hose gehen. ;-)
Immer schon sauber arbeiten mit den Threads, damit's keine "lustigen" Effekte gibt!
Bin gespannt!

Antworten