Neues Fenster zur Laufzeit erstellen
-
Könntest Du nicht statt dessen mit Screen->FormCount und Screen->Forms arbeiten?
Gruß,
Alexander
-
Spitze Alex ! Super
for (int i = 0;i < Screen->FormCount;i++) { if (Screen->Forms[i]->Caption == "TestWindow ") ShowMessage(""); }Was muss ich deleten wenn ich ein neu erzeugtes Fenster schliesse da er momentan auch reagiert wenn ich das Fenster geschlossen habe ? Da kann man doch bestimmt was über OnClose biegen
-
Ahhhhhhhhh, habs rausgefunden:
void __fastcall TForm4::FormClose(TObject *Sender, TCloseAction &Action) { delete this; }
-
Wenn ich folgendes mache:
for (int i = 0;i < Screen->FormCount;i++) { if (Screen->Forms[i]->Caption == "Searched_Window ") ... ......Wie kann ich den jetzt in die Memo1 Komponente der gesuchten Form zugreifen um dort einen String ein zu tragen

-
Zero01 schrieb:
Wie kann ich den jetzt in die Memo1 Komponente der gesuchten Form zugreifen um dort einen String ein zu tragen

Es ist klar, dass in Screen::Forms keinerlei Informationen über Deine selbstgebastelten Formulare direkt zugänglich sind.
Um das zu realisieren musst Du halt einen cast machen. Wenn Du mal verrätst, was Du eigentlich erreichen will, könnte
man sich aber mal Gedanken darüber machen, ob es einen anderen Weg gibt.Gruß,
Alexander
-
Ich denke hier wäre dann wohl ein Array dieser Forms besser (dann braucht man keinen cast).
-
Hallo
Wenn Du mal verrätst, was Du eigentlich erreichen will, könnte
man sich aber mal Gedanken darüber machen, ob es einen anderen Weg gibt.Deshalb eigenen Container (std::map), dann wird auch die Suche für dich übernommen.
Für Infos über map siehe z.B.
http://www.cppreference.com/bis bald
akari
-
@akari
Für die std::map sollte man aber #include<map> machen.
Bei deinen Post ist es #include<Map>
-
akari schrieb:
Deshalb eigenen Container (std::map), dann wird auch die Suche für dich übernommen.
Eigentlich dachte ich "eine Ebene höher". Es führen bekanntlich viele Wege zum Ziel und vielleicht gibt
es einen Weg das Speichern von Formularen oder Durchgehen der Formulare, Verwendung von maps o.ä. komplett
zu vermeiden.
Nebenbei, wenn Du Formulare verschiedenen Typs in eine map wirfst, musst Du doch wohl auch casten, oder?Gruß,
Alexander
-
Hallo
Eigentlich dachte ich "eine Ebene höher".
Und an was genau dachtest du da?
Ich selber würde jedem User in ein struct/class aufnehmen, der neben den Namen und Verbindungsdaten u.a. auch einen Pointer auf das eventuell vorhandene Chat-Fenster enthält. Aber auch das würde ich in einen Standard-Container packen.bis bald
akari
-
akari schrieb:
Und an was genau dachtest du da?
Da habe ich mich vielleicht nicht ganz klar ausgedrückt. Ich meinte, dass man vielleicht genauer beschreiben sollte,
was eigentlich das Ziel ist.
Aber die Idee mit einem eigenen Struct geht schon in die Richtung, die ich wahrscheinlich auch einschlagen würde.
So wie ich mich kenne, würde ich vermutlich irgendeinen MVC-ähnlichen Ansatz mit Klassen und Observer-Pattern etc.
wählen. Die Daten in Formularen zu speichern und direkt über Memos, Edits u.ä. zu ändern würde ich wahrscheinlich
vermeiden.Gruß,
Alexander
-
Beispiel:
Im Header der Form1:
TForm4 *ChatWindow;Erzeugt wird dies mit:
void __fastcall TForm1::ChatUDP1DataReceived(TComponent *Sender, int NumberBytes, AnsiString FromIP, int Port) { if (NumberBytes>-1 && NumberBytes<1024) { char Buff[1024]; int j,i,Size,lenght; String received_buff,from_user,message; ChatUDP1->ReadBuffer(Buff, 1024, j); Buff[j]=0; received_buff = String(Buff); bool istrue = false; if(received_buff.SubString(1,2) == "M:") { received_buff = received_buff.SubString(3,received_buff.Length()); //M: ausschneiden int a = received_buff.LastDelimiter(":") + 1; from_user = received_buff.SubString(a,received_buff.Length()); // Von User message = received_buff.SubString(1,a - 2); // Nachricht int screenform; for (int i = 0;i < Screen->FormCount;i++) { if (Screen->Forms[i]->Caption == from_user) { screenform = i; istrue = true; } } if (istrue == false) { ChatWindow = new TForm4(Form1); if(ChatWindow) { ChatWindow->Memo3->Lines->AddStrings(userlist); //unsichtbare Form ChatWindow->Caption = from_user; ChatWindow->Label1->Caption = nickname +" "; ChatWindow->Label2->Caption = from_user; ChatWindow->Memo1->Lines->Add(from_user + ": " + message); ChatWindow->Show(); } } else { } } } }Wie ihr seht ist der else Zweig noch leer. Ich möchte sobald ein Fenster eines Users offen steht, das seine ankommende Nachricht darin (Memo1) Eingetragen wird. Wenn ein Fenster von einem gewissen User nicht offen ist wird es erzeugt wie man oben schön sieht.
Das ganze Problem ist nur das jede ankommende Message in ein eindeutiges User Fenster geschrieben wird und wenn dies nicht existiert wird es erzeugt. Es funzt alles bestens bis auf die Zuweißung in eine spezielles Fenster. Das bestes Beispiel für den Mechanismus ist ICQ, IRC privat chat, Trillian.Wie kann ich das am besten lösen

-
Hallo
das einfachste wäre (was auch schon mal genannt wurde) ein cast
ChatWindow = dynamic_cast<TChatForm *> (Screen->Forms[screenform]); if (ChatForm != NULL) { // Text in ChatForm anzeigen }allerdings ist das nicht sehr sauber und effizient.
Wenn du besser arbeiten willst, must du dich mit den Vorschlägen oben beschäftigen.bis bald
akari
-
Vielen Dank !
Aber was ist an dem Cast so verwerflich ? bei mir funzt es super. Hab mal einige Situationen durchgespielt
-
Verwerflich ist er nicht unbedingt. Es müssen nur zwei Dinge beachtet werden.
1. RTTI muss eingeschaltet sein
2. Sehr häufige Nutzung, insbesondere in Schleifen, senkt die Performance. Dieser Cast ist nämlich relativ langsam.Ciao
-
Als built-in RTTI Operator wird ja dynamic_cast verwendet. Die Geschwindigkeit ist
ist hier relativ egal da es max 30 User werden die Miteinander chatten können und in einer Schleife wird es bei mir ohnehin nicht verwendet.ChatWindow = dynamic_cast<TForm4 *> (Screen->Forms[screenform]); if (ChatWindow != NULL) { ChatWindow->Memo1->Lines->Add(from_user + ": " + message); }Das Projekt ist ein serverloser Subnet Chat im ICQ Design mit File Transfer und Webcam Support.
Da ich momentan in einer intensiven Lernphase bin danke ich euch vielmals für diesen Top Support
! Es wird sicher einige geben die gleiche Probleme haben, wie wäre es diesen Thread in die FAQ aufzunehmen ?David
-
Ich finde das schreit geradezu nach Verwaltung in einer struct.
Grüße Joe_M.
-
Hallo
Ein Problem ist, wenn ein User als Namen die Caption des Hauptfensters nimmt, dann wird irgendwo etwas verschluckt. Oder eines anderen Fensters, das kein ChatForm ist.
Denn in Screen->Forms[i] sind alle Fenster der Anwendung drinnen, nicht nur die ChatForms.bis bald
akari
-
Hi,
jeder Username wird mit einem Leerzeichen ergänzt was nicht nur vom "Delete" Steuerbyte meines Protokolls abweicht sondern auch einen Doppelten Fensertitel vermeiden sollte da ich diese ohne Leerzeichen am Ende definiert habe. Der User kann eingeben was er will. Wird jedoch bei einem Username change oder connect der neue Name via Broadcast gesendet und eine Station "nee, so heise ich schon !" Antortet ist der User gezwungen einen eindeutigen Name für sich zu definieren. Alle Fliegen mit einer Klappe

-
@akari
In diesem Fall müsste aber auch der cast daneben gehe (0 zurückgeben), da diese Form ja einen anderen Typ haben dürfte.