Autor Beitrag
hRb
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 287
Erhaltene Danke: 12



BeitragVerfasst: So 09.02.25 21:24 
Hallo zusammen,
ich habe in mein Programm neu einen TFindDialog und einen TReplaceDialog eingebaut, also Routinen zum Finden und Tauschen von Text. In meinem Programm sind mehrere Richedit- und TEdit-Objekte. Problemlos kann ich in diesen Felder mit Strg+C, Strg+V, Str+X, etc. korrekt arbeiten.
In den Edit-Feldern von FindDialog und ReplaceDialog funktionieren diese Shortcut-Befehle nicht.
Ich frage in die Runde: Warum nur in diesen Feldern?. Was ist falsch an meinem Pascalcode oder fehlt irgenwo in den Optiona ein Häkchen?
Zu erwähnen:
1. Über die Tastatur kann ich in diesen Textfelder manuell Veränderungen vornehmen. Die Such-Tauschfunktion selbst, arbeitet korrekt – vorwärts wie rückwärts.
2. Beim Befehl Strg+V wird der in der Zwischenablage stehende Text nicht ins Edit-Feld eingefügt in dem der Cursor steht, sondern in meine Richedit-Vorlage, in dem später gesucht/getauscht werden soll.

Meine Befehle
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
procedure TForm1.EditCopy(Sender: TObject);
{ Bearbeiten|Kopieren  = Strg C }
begin
  If Self.ActiveControl is TCustomEdit then
    TCustomEdit(Self.ActiveControl).CopyToClipboard;
end;

procedure TForm1.EditPaste(Sender: TObject);
{ Bearbeiten|Einfügen  = Strg V }
{ nur unformatierten Text übernehmen: Send... statt Paste }
begin
  If Self.ActiveControl is TCustomEdit then
    TCustomEdit(Self.ActiveControl).PasteFromClipboard
end;

procedure TForm1.EditCut(Sender: TObject);
{ Bearbeiten|Ausschneiden = Strg X }
begin
  If Self.ActiveControl is TCustomEdit then
    TCustomEdit(Self.ActiveControl).CutToClipboard;
end;

Aufgerufen wird der ReplaceDialog mit:
procedure TForm1.ReplaceDialog1Show(Sender: TObject);
begin
  SetFocus;
end;

procedure TForm1.FindDialog1Show(Sender: TObject);
begin
  SetFocus;
end;
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19310
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 09.02.25 22:06 
Moment, das verstehe ich nicht. Wenn der Dialog angezeigt wird, versuchst du dir den Fokus wieder mit SetFocus auf dein Formular zu klauen? Dann ist doch aber klar, dass der angezeigte Dialog nicht mehr den Eingabefokus hat und die Tastaturbefehle dort nicht mehr ankommen.

Was möchtest du denn mit dem SetFocus erreichen?
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 287
Erhaltene Danke: 12



BeitragVerfasst: Di 11.02.25 23:19 
Hallo jaenicke,
den Einwand verstehe ich nicht. Mit ...DialogShow wird m.E. ja "nur" das Dialogfeld angezeigt. Hat es dann den Focus automatisch? Dann wäre SetFocus redundant.
Ist aber nicht mein Problem, denn wenn ich mit den Cursor in eines der Felder Findtext bzw. Replacetext klicke, dann ist der Focus in jedem Fall im entsprechenden Feld. Dann sollten die Funktionen Strg + C, V, X doch funktionieren. Nochmals der Hinweis: die eigentliche Such-Ersetzenfunktion arbeitet korrekt, es geht nur ums Ändern der Felder im Dialogfeld.
Anders gefragt: Wie wäre es denn richtig?
PS: habe mal den Befehl SetFocus weggenommen, also
ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.ReplaceDialog1Show(Sender: TObject);
begin
//  SetFocus;   2025
end;

Es hat überhaupt nichts verändert.
hRb
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19310
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 12.02.25 08:01 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Mit ...DialogShow wird m.E. ja "nur" das Dialogfeld angezeigt. Hat es dann den Focus automatisch? Dann wäre SetFocus redundant.
Du hast SetFocus auf das Formular aufgerufen, nicht auf den Dialog. Deshalb machte das für mich keinen Sinn und deine Antwort zeigt, dass du das auch gar nicht beabsichtigt hattest.

Vielleicht noch zur Erklärung:
Nur weil du innerhalb eines Events einer Komponente bist, beziehen sich Befehle darin nicht auf diese Komponente. So etwas musst du immer auch explizit hinschreiben, z.B. Memo1.SetFocus statt nur SetFocus. SetFocus alleine wird dann auf die Klasse bezogen, in der du dich befindest, und das ist das Formular.

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Ist aber nicht mein Problem, denn wenn ich mit den Cursor in eines der Felder Findtext bzw. Replacetext klicke, dann ist der Focus in jedem Fall im entsprechenden Feld. Dann sollten die Funktionen Strg + C, V, X doch funktionieren.
Da hast du Recht, dann ist der Fokus kein Problem. Ich rate mal basierend auf deinem Quelltext, dass du diese Shortcuts in deinem TMainMenu den Menüeinträgen zum Kopieren usw. zugewiesen hast?

Nimm das mal raus, dann sollte es funktionieren.
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 287
Erhaltene Danke: 12



BeitragVerfasst: Do 13.02.25 00:55 
Danke, das mit SetFocus in einer Komponente war mir so nicht klar.
Zitat:
Ich rate mal basierend auf deinem Quelltext, dass du diese Shortcuts in deinem TMainMenu den Menüeinträgen zum Kopieren usw. zugewiesen hast?

Sorry, den Satz verstehe ich nicht. Ein Tipp mit einem Fragezeichen abschließen!. Fehlen da noch ein paar Worte dazwischen?
In meinem MainMenü habe ich, wie in jedem Programm, ein PulldownMenü "Bearbeiten". Dort stehen die MenüItems (s. Image3), mit den in der Eingangsfrage erwähnten Befehle. Ihnen sind die Shortcuts Strg+C,V,X,A zugewiesen
Zitat:
Nimm das mal raus, dann sollte es funktionieren.

Bitte, wo soll ich was rausnehmen? Ich füge mal weitere Image bei (4..5), vielleicht sieht man, ob Parameter falsch sind. Und nochmals: In allen anderen Edit- bzw. Richedit-Objekten funktionieren die Kurzbefele, nur beim Dialogfeld nicht?

Danke für Geduld. hRb
Einloggen, um Attachments anzusehen!
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 287
Erhaltene Danke: 12



BeitragVerfasst: Do 13.02.25 17:56 
Guten Tag
Ich habe mal mit dem Debugger getestet und sehe, dass tatsächlich die Dialogfelder nicht aktive werden, obwohl ich in die Textfelder hineinklicke. Wie werden die Dialogfelder aktiv? Mit z.B. Form1.ReplaceDialog1.SetFocus gibt*s Compilerfehler.
Beigefügt ein rudimentäres Testprogramm an dem das sichtbar/testbar wird. Vielleicht ist mein Fehler damit leichter zu erkennen. Das Programm besteht nur aus 2 Editfelder, Richedit und den Such- Dialogfeldern. Keine weiterer Code zum Suchen, weil es ja nur darum geht etwas in die Dialogfelder etwas hineinzukopieren.
Anlage : zip-Datei, damit auch Parameter sichtbar.
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.StdCtrls, Vcl.ComCtrls, System.Types;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    Edit1: TEdit;
    datei1: TMenuItem;
    Bearbeiten1: TMenuItem;
    Kopieren1: TMenuItem;
    Einfuegen1: TMenuItem;
    MarkiereAlles1: TMenuItem;
    Ausschneiden1: TMenuItem;
    Suchen1: TMenuItem;
    ShowFindDialog1: TMenuItem;
    ShowReplaceDialog1: TMenuItem;
    RichEdit1: TRichEdit;
    Beenden1: TMenuItem;
    FindDialog1: TFindDialog;
    ReplaceDialog1: TReplaceDialog;
    EditCommand: TEdit;
    procedure Kopieren1Click(Sender: TObject);
    procedure Einfuegen1Click(Sender: TObject);
    procedure MarkiereAlles1Click(Sender: TObject);
    procedure Ausschneiden1Click(Sender: TObject);
    procedure Beenden1Click(Sender: TObject);
    procedure ShowFindDialog1Click(Sender: TObject);
    procedure ShowReplaceDialog1Click(Sender: TObject);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Beenden1Click(Sender: TObject);
begin
 Form1.Close
end;

procedure TForm1.MarkiereAlles1Click(Sender: TObject);
begin   // Bearbeiten|Alle auswählen = Strg A 
  If Self.ActiveControl is TCustomEdit then
    TCustomEdit(Self.ActiveControl).SelectAll;
end;

procedure TForm1.Kopieren1Click(Sender: TObject);
begin  // Bearbeiten|Kopieren  = Strg+C 
  If Self.ActiveControl is TCustomEdit then
    TCustomEdit(Self.ActiveControl).CopyToClipboard;
end;

procedure TForm1.Einfuegen1Click(Sender: TObject);
begin  //   Bearbeiten|Einfügen = Strg+V
  If Self.ActiveControl is TCustomEdit then
    TCustomEdit(Self.ActiveControl).PasteFromClipboard
end;

procedure TForm1.Ausschneiden1Click(Sender: TObject);
begin   // Bearbeiten|Ausschneiden = Strg+X 
  If Self.ActiveControl is TCustomEdit then
    TCustomEdit(Self.ActiveControl).CutToClipboard;
end;

procedure TForm1.ShowFindDialog1Click(Sender: TObject);
begin  // Dialogfenster zeigen
  FindDialog1.Position :=  Point(Form1.Left + 3 { + Fi.Width } , Form1.Top + 3);
  FindDialog1.Execute;
end;

procedure TForm1.ShowReplaceDialog1Click(Sender: TObject);
begin  // Dialogfenster zeigen
  ReplaceDialog1.Position := Point(Form1.Left +3 { + Fi.Width } , Form1.Top +3);
  ReplaceDialog1.Execute;
end;

end.
Einloggen, um Attachments anzusehen!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19310
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 14.02.25 01:20 
user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Ich rate mal basierend auf deinem Quelltext, dass du diese Shortcuts in deinem TMainMenu den Menüeinträgen zum Kopieren usw. zugewiesen hast?

Sorry, den Satz verstehe ich nicht. Ein Tipp mit einem Fragezeichen abschließen!. Fehlen da noch ein paar Worte dazwischen?
Nicht "ich rate dir", sondern "ich rate" im Sinne von "ich errate etwas". ;-)

user profile iconhRb hat folgendes geschrieben Zum zitierten Posting springen:
In meinem MainMenü habe ich, wie in jedem Programm, ein PulldownMenü "Bearbeiten". Dort stehen die MenüItems (s. Image3), mit den in der Eingangsfrage erwähnten Befehle. Ihnen sind die Shortcuts Strg+C,V,X,A zugewiesen
Zitat:
Nimm das mal raus, dann sollte es funktionieren.
Genau diese Shortcuts sollst du entfernen. Die sorgen dafür, dass die Shortcuts im Hauptfenster behandelt werden und nicht bei den anderen Eingabefeldern ankommen.
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 287
Erhaltene Danke: 12



BeitragVerfasst: So 16.02.25 20:39 
Hallo Jänicke,
danke für Deine Geduld. Habe endlich Deinen Hinweis verstanden und alle Shortcut entfernt.
Ich gebe mal meine neuen Test-Erkenntnisse wieder:
1. Die Standardfunktionen Strg+C,V,A,X funktionieren nun tatsächlich in allen Objekten, auch in den Dialogfeldern - also ohne eigenen PascalCode. Strg+C, V, etc. sind wohl Funktionen, die offenbar selbst gar nicht ausprogrammiert werden müssen (lässt sich am Testprogramm prüfen). Damit zunächst eitel Freude!
2. Allerdings besteht mein Problem insoweit weiter, dass ich in meine eigen definierte Copy- und Paste-Routinen weiteren Code eingebaut habe. So erscheint es wünschenswert, die Shortcuts zu belassen.
Wie Jänicke schreibt, geht mit FindDialog1.Execute der Focus nicht aufs Dialogformular über (was ich glaubte, denn beim Filedialog funktioniert es ja auch).
3. Ich rufe das Dialogfeld wie folgt auf:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm1.FindTxtMenuClick(Sender: TObject);
begin
  FindDialog1.Position := Point(Form1.Left + 30 { + Fi.Width } , Form1.Top + 30);
  FindDialog1.FindText := SelectWort;
  FindDialog1.Execute;
// zum Test eingebaut
MessageDlg(Screen.FocusedForm.ActiveControl.Name, mtInformation, [mbOk], 0); 
end;

Die obige MessageMeldung liefert den Objektname, aus dem der Dialog aufgerufen wurde.
Aufrufe, um dem Dialogfeld zwangsweise den Focus zuzuweisen, wie
FindDialog1.SetFocus oder FindDialog1.Findtext.SetFocus funktionieren nicht.
Wie kann ich den Focus erzwingen? bzw. gibt keine andere Lösung, als die eigenen Shortcut zu entfernen?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19310
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 16.02.25 22:00 
Der Fokus wird schon auf den Dialog gesetzt, ganz ohne extra Code. Sonst könntest du ja auch nicht in dem Feld schreiben, ohne extra hineinzuklicken.

Das Problem liegt aber woanders. Die Shortcuts werden im Hauptfenster behandelt, egal wo der Fokus liegt. Du solltest ein wenig mehr mit dem Debugger arbeiten. Wenn du einen Haltepunkt in deiner Kopieren-Methode setzt, siehst du auch, wie die Behandlung intern abläuft:
Screenshot_2025-02-16_213455

Bedeutet:
Zusammengefasst kommt der Shortcut in der Anwendung (TApplication) an und dort wird dann das Hauptformular gefragt, ob es diesen Shortcut kennt. Deshalb ist es völlig egal, wo der Fokus liegt.

Du siehst beim Debuggen daher auch, wo du eingreifen kannst: Bei der Prüfung, ob es ein Shortcut ist oder nicht. Du musst ja nur dafür sorgen, dass der Shortcut nur beachtet wird, wenn das Hauptformular den Fokus hat. Also überschreibst du die entsprechende Methode:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  public
    function IsShortCut(var Message: TWMKey): Boolean; override;

...

function TForm1.IsShortCut(var Message: TWMKey): Boolean;
begin
  if Focused then
    Result := inherited
  else
    Result := False;
end;
Einloggen, um Attachments anzusehen!
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 287
Erhaltene Danke: 12



BeitragVerfasst: Mi 19.02.25 16:41 
Hallo Jänicke
Vielen Dank, das hat mir jetzt sehr geholfen.
Dich könnte ich als Nachbarn gebrauchen.
LG hRb