Komponentenentwickulung Eigenschaft mit Untereigenschaft erstellen
-
Ich hoffe AndreasW schaut mal wieder rein.
Ichhabe nämlich ein weiteres Problem bei der Komponentenentwicklung aufgetan, diesmal mit den Ereignisbehandlungsmethoden.
Im Code unten ist mal das meiste unwichtige ausgeblendet. Man sieht eine Ereignisbehandlungsmethode OnBeforeConnect() die ausgelösst werden soll befor hatl die Connection zum Comport wirklich aufgebaut wird.
Meine Frage ist die Implementierung dieser. Ich habe sie einfach in die Methode connect() (mit der stellt man die Verbindung her) als erstes reingeschrieben.
In deinem Builder Tutorial arbeitest du aber mit Messages. Soll ich nun für alle meine EreignisbehandlungsMethoden ne eigene Message erstellen und Abfragen?
Insbesondere bei dieser stell ich mir das nämlich schwierig vor, den wenn dann statt der Methode direkt erst der Aufruf der Mesage verschickt wird abeitet der doch danach weiter ab und wartet nicht, bis die Message erfolgreich verarbeitet wurde. Oder täusche ich mich da?typedef void __fastcall (__closure *MyDataRead) (String Daten, bool &doDelete); typedef void __fastcall (__closure *MyBeforeOpen)(DCB &dcb); //--------------------------------------------------------------------------- class PACKAGE TComm : public TComponent { __published: __property MyBeforeOpen OnBeforeOpen = {read=F_MyBeforeOpen, write=F_MyBeforeOpen}; private: MyBeforeOpen F_MyBeforeOpen; public: __fastcall TComm(TComponent* Owner); __fastcall ~TComm(); bool __fastcall Connect(); protected: bool __fastcall OpenCommP(); bool __fastcall CloseCommP(); void __fastcall DataInBuffer(DWORD *InQueue, DWORD *OutQueue); }; //--------------------------------------------------------------------------- #endif bool __fastcall TComm::Connect() { //Ereignisbehandlung OnBeforeOpen(...) aufrufen if(F_MyBeforeOpen)F_MyBeforeOpen(FDCB->FDCB); //wenn Verbindung zum Comport bereits besteht, dann trennen //und eine neue Verbindung mit den angegebenen Daten erstelln if (F_Connected) CloseCommP(); DatenBuffer = ""; if (!OpenCommP()) return false; //Je nach Modus die entsprechene Bearbeitung zum Daten lesen starten switch(F_Modus) { case PollingMode: PollingModeTimer->Interval = F_PollingTimeout; PollingModeTimer->Enabled = true; break; case EventMode: //Code folgt break; default: return false; }; return true; } //---------------------------------------------------------------------------
-------------------------------------------------------
Ich habe gerade noch das hier in deinem Tutorial gelesen:
if (!ComponentState.Contains(csDesigning))TLabel::Paint();
Hier wird die virtuelle Methode Paint redefiniert. Wenn dies leer ist, wird auch nichts gezeichnet. in der if-Anweisung wird die alte Methode nur aufgerufen, wenn die Komponente sich zur Laufzeit erstellt wird. Zur Entwurfzeit wird nichts gezeichnet.
Habs aber nicht ganz verstanden. unterscheidet der hier richtig zwischen Laufzeit und Entwurfszeit oder liegt die Betonung auf zur Laufzeit erstellt. Also muss das Teil mit new erzeugen?
-
Hi,
ich bin zwar nicht AndreasW aber ich sag trotzdem mal was!zu 1) Ich mache das immer so wie du! Messages sind wahrscheinlich nur wichtig wenn man sie auch außerhalb der Komponente abfrage können soll, oder?
Bigwill schrieb:
Habs aber nicht ganz verstanden. unterscheidet der hier richtig zwischen Laufzeit und Entwurfszeit oder liegt die Betonung auf zur Laufzeit erstellt. Also muss das Teil mit new erzeugen?
Hierbei unterscheidet er richtig zuwischen Entwurf- und Laufzeit! Beim TImage wird der gestrichelte Rand im Entwurf so gezeichnet:
if (ComponentState.Contains(csDesigning))
Zeichne_gestrichelten_Rand();Dadurch wird der Rand nur im Formulardesigner gezeichnet!
MFG
Alexander Sulfrian
-
Nun, das sind ja dann gleich 2 positive Antworten auf einmal, das mag ich.
-
Biwill schrieb:
Ich hoffe AndreasW schaut mal wieder rein.
Da bin ich wieder
War auf Wochenend- Tour...
Biwill schrieb:
In deinem Builder Tutorial arbeitest du aber mit Messages.
ähm, keine Ahnung was du meinst. Gib mir doch noch ein Hinweis bezüglich des Themas und Abschnittes. Vielleicht muss ich da ja noch was verbessern, wenn das Thema vomn mir nicht klar genug oder misverständlich ausgeführt wurde
Deine Implementation des Ereignisses sieht aber richtig aus. So muss es sein..
Biwill schrieb:
Insbesondere bei dieser stell ich mir das nämlich schwierig vor, den wenn dann statt der Methode direkt erst der Aufruf der Mesage verschickt wird abeitet der doch danach weiter ab und wartet nicht, bis die Message erfolgreich verarbeitet wurde. Oder täusche ich mich da?
wo liegt der Unterschied zwischen SendMessage (Perform/Broadcast) und PostMessage ?
Alexander Sulfrian schrieb:
Ich mache das immer so wie du! Messages sind wahrscheinlich nur wichtig wenn man sie auch außerhalb der Komponente abfrage können soll, oder?
naja, vom Prinzip her schon.
Etwas weiter gedacht, macht es aber schon Sinn. Nimm mal an, jemand möchte deine Komponente als SubKomponente verwenden. Er möchte aber auch auf Ereignisse der SubKomponente reagieren. Wenn er nun aber die Ereignisse (Methodenpointer) der SubKomponente benutzt kann der Anwendungsentwickler dieses aber nicht mehr )*. Somit sich Messages, die zum Parent und zum Owner geschickt werden durchaus sinnvoll. Vielleicht hab ich diese Aspekte im Tutorial noch nicht ganz rund angesprochen...
Ist ja auch erst mal eine Grundlage, ich werd da noch dran arbeiten und ausbauen.)* Das weiterreichen von Methodenpointern innerhalb eine Komponente zu SubComponenten erscheint nur auf den ersten Bilck sicher. Wenn Komponeten zur Laufzeit dynamisch erzeugt und wieder zerstört werden, kann es durchaus passieren, dass Methodenpointer ins "Nichts" führen und Zugriffsverletztungen verursachen.
Man sollte einfach hinnehmen, das ein Pointer halt nur eine Adresse aufnehmen kann. Jede weitere hin und her zwitscherrei kostet Sicherheit und ist nicht Vertretbar.Simples (ähnliches) Beispiel:
erzeuge eine Kompo. die auf das Ereignis Rezize des ParentForm reagiert.
macht dabei eine zwitscherrei wie (nur Pseudocode):
im Konstruktor:
OldFormResize= GetParentForm()->OnResize;
GetParentForm()->OnResize=FromResize;in der Methdoe FormResize sowas wie:
ShowMessage("FormResize");
if(OldFormResize)OldFormResize(GetParentForm());im Destruktor
GetParentForm()->OnResize=OldFormResize;soweit die Testkomponente.
nun zieh 4 dieser Komponeten in dein Formular.
Du wirst feststellen, dass es funktioniert.
nun lösche die zweite Komponente zur Laufzeit ....
Joh, und das Übel nimmt seine Lauf...