Suchen Dialog über ActionList / FindDialog
-
Moin!
ich habe wohl mal wieder ein Problem, dass einfach ist aber für mich dennoch zu hoch...
Ich möchte in meinem Projekt einen Dialog zum suchen und ersetzen einfügen, der dies in einem RichEdit tuen soll.
IN BCB gibt es dafür ja die Möglichkeiten über den ActionList zu gehen oder mit dem FinDDialog zu arbeiten.Beides fruchtet nicht so recht.
Die wie ich fand sauberste Methode über die ActionList gibt mir Rätsel auf. Zwar springt der Suchdialog an, wenn ich ein RichEdit klicke und ihn über das Menü starte und er sucht auch, aber das gefundene Wort wird erst markiert, wenn ich das Dialogfeld zum suchen schließe oder in das RichEdit klicke. Allerdings wird nur das erste Vorkommen des Wortes ab der Cursorposition gesucht und gefunden, egal ob ich "nach oben" oder "nach unten" dann im Dialog anklicke.In die ActionList habe ich dafür ein SearchFind1 + SearchFindNext1 eingefügt. Letzteres habe ich über sein Ereignis SerachFind mit meinem SearchFind1 verbunden. In den Eigenschaftes des SerachFind1 unter Dialog/Options sind frDown und frNext auf true gesetzt.
In meinen Menü ist der Punkt Suchen dann über sein Ereignis Action mit dem SerachFind1 verbunden.Für den FindDialog habe ich aus der BCB Hilfe das Beispiel "Position, Execute, FindText, OnFind, SelStart, SelLength (Beispiel)" entnommen. Aus den Dialogen habe ich dafür den FindDialog gezogen. Mein Code sieht dann folgendermaßewn aus:
void __fastcall TFormMain::Suchen1Click(TObject *Sender) { FindDialog1->Position = Point(dynamic_cast<TRichEdit*>(PageControl1-> ActivePage->Components[6])->Left + dynamic_cast<TRichEdit*>(PageControl1-> ActivePage->Components[6])->Width, dynamic_cast<TRichEdit*>(PageControl1-> ActivePage->Components[6])->Top); FindDialog1->Execute(); } //--------------------------------------------------------------------------- void __fastcall TFormMain::FindDialog1Find(TObject *Sender) { int FoundAt, StartPos, ToEnd; // Suchbeginn nach der aktuellen Markierung // (falls vorhanden), // andernfalls am Textanfang starten if (dynamic_cast<TRichEdit*>(PageControl1->ActivePage->Components[6])->SelLength) StartPos = dynamic_cast<TRichEdit*>(PageControl1->ActivePage->Components[6]) ->SelStart + dynamic_cast<TRichEdit*>(PageControl1->ActivePage->Components[6])->SelLength; else StartPos = 0; // ToEnd ist die Länge von StartPos // bis zum Ende des Textes im RTF-Eingabefeld ToEnd = dynamic_cast<TRichEdit*>(PageControl1->ActivePage->Components[6])->Text.Length() - StartPos; FoundAt = dynamic_cast<TRichEdit*>(PageControl1->ActivePage->Components[6])-> FindText(FindDialog1->FindText, StartPos, ToEnd, TSearchTypes()<< stMatchCase); if (FoundAt != -1) { dynamic_cast<TRichEdit*>(PageControl1->ActivePage->Components[6])->SetFocus(); dynamic_cast<TRichEdit*>(PageControl1->ActivePage->Components[6])->SelStart = FoundAt; dynamic_cast<TRichEdit*>(PageControl1->ActivePage->Components[6])->SelLength = FindDialog1->FindText.Length(); } }Wie zu sehen ist, arbeite ich mit mehreren RichEdits auf die ich per dynamic cast zugreife wärend der Laufzeit. Mein spezielles RichEdit zum durchsuchen soll halt die Komponente 6 auf einem TabSheet einer PageControl sein.
Selbst wenn es funktionieren würde wäre es noch nicht anganz sauber, da ich eigentlich zwei RichEdits druchsuchen muss. Aber mir würde es schon reichen, wenn es überhaupt läuft...Danke für eure Hilfe im Voraus.
MfG Martin
-
macsmac schrieb:
das gefundene Wort wird erst markiert, wenn ich das Dialogfeld zum suchen schließe oder in das RichEdit klicke
HideSelection des RichEdit auf false setzen.
Allerdings wird nur das erste Vorkommen des Wortes ab der Cursorposition gesucht und gefunden, egal ob ich "nach oben" oder "nach unten" dann im Dialog anklicke.
Im OnFind des SearchFind1 den FindDialog-Beispielcode einfügen, dabei das FindDialog1 durch SearchFind1->Dialog ersetzen.
Tip am Rande: sieh zu, dass du die dynamic_cast-Häufungen los wirst. Erstell dir eine temporäre Instanz der Zielklasse und arbeite dann mit der weiter.
TRichEdit *RE = dynamic_cast<TRichEdit *>(PageControl1->ActivePage->Components[6]); if (RE) SearchFind1->Dialog->Position = Point(RE->Left + RE->Width, RE->Top); // usw.
-
Hallo
du hast das mit dem TReplaceDialog falsch verstanden...
statt dem OnFind-Event must du auch den OnReplace-Event nehmen.
Außerdem würde ich dir empfehlen, die casts auf einen zu reduzieren, so hier :void __fastcall TFormMain::Suchen1Click(TObject *Sender) { TRichEdit *CurrEdit = static_cast<TRichEdit*>(PageControl1-> ActivePage->Components[6]); // Ein fester Cast, das du ja genau weist, das ein RichEdit vorhanden ist FindDialog1->Position = Point(CurrEdit->Left + CurrEdit->Width, CurrEdit->Top); FindDialog1->Execute(); }/Edit : zu spät
bis bald
akari
-
akari schrieb:
TRichEdit *CurrEdit = static_cast<TRichEdit*>(PageControl1-> ActivePage->Components[6]); // Ein fester Cast, das du ja genau weist, das ein RichEdit vorhanden istAlso gerade beim Zugriff auf das Components-Array ist ein dynamic_cast IMO unverzichtbar. Wie schnell hat man im Formdesigner mal ein paar Komponenten entfernt und/oder (wieder) hinzugefügt, und schon geht der static_cast in's Auge.
-
Und noch ein Nachtrag zum eigentlichen Thema:
Im OnFind des SearchFind1 einfach SearchFindNext1->Execute aufrufen.
-
Danke, ihr habt mir sehr geholfen.
Jansen schrieb:
Und noch ein Nachtrag zum eigentlichen Thema:
Im OnFind des SearchFind1 einfach SearchFindNext1->Execute aufrufen.Genau damit läuft's wunderbar

Allerdings macht mir der Ersetzendialog noch Probleme, da er nur alles nach der Cursorposition ersetzt, aber nicht darüber. Ich habe dafür das SearchReplace in der ActionList eingesetzt.
Die Position zu setzen hilt auch nichtTRichEdit *RE = dynamic_cast<TRichEdit *>(PageControl1->ActivePage->Components[6]); if (RE) SearchReplace1->Dialog->Position = Point(RE->Left + RE->Width, RE->Top); SearchReplace1->Dialog->Execute();Den Aufruf habe ich unter dem Menüpunkt Ersetzen und dessem Ereignis OnClick vermacht.
Gruß M