Form.Keypreview vs. Memo

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Form.Keypreview vs. Memo

Beitrag von mulcheo »

Hallo, in einigen meiner Forms nutze ich keypreview, um Tasteneingaben (für Textscrollen und sonstige Hotkeys) abzufangen. Wenn nun das Form zusätzlich noch ein Memo enthält und ich Form.KeyPreview=true setze, werden die Tasten zwar wie gewünscht abgefangen, doch landen sie anschließend auch im Memo (was dann quasi ungewünscht alle Tasten 'mitprotokolliert'). Ich hätte es nun gerne so, dass das Memo Eingaben nur dann aufnimmt, wenn es auch im Fokus liegt (weil es angeklickt wurde o.ä.). Wie mache ich das?

Vielen Dank schonmal

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Form.Keypreview vs. Memo

Beitrag von m.fuchs »

Mal davon ausgehend, dass du TForm.OnKeyDown benutzt: Der Parameter Key ist ein var-Parameter. Das heißt, du kannst ihn im Inneren deiner Methode verändern.
Wenn du nun also eine Taste erwischt hast, die nicht ans Memo gehen soll, führst du in der OnKeyDown-Methode einfach folgendes aus:

Code: Alles auswählen

Key := #0;
Damit wird der ursprüngliche Inhalt der Key-Variable mit dem NUL-Zeichen überschreiben und darauf reagiert das Memo nicht.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Re: Form.Keypreview vs. Memo

Beitrag von mulcheo »

das bewirkt leider nicht, was ich möchte, denn jetzt gehen die Tasten überhaupt nicht mehr ans Memo.

mein Ausgangsproblem hat auch zwei Seiten (zur Erklärung: ich habe auf meiner Form eine Paintbox, die ich mit keys scrolle, und zusätzlich eine paar Memos);
a) wenn ich eine der Steuertasten (wasd und co.) drücke, gehen die gleich ins Memo, obwohl ich in dem Moment wirklich nur die Paintbox steuern möchte, spricht das Memo nicht angeklickt oder dort den cursor gesetzt habe...
b) wenn ich im Memo einen Text eingebe und dabei eine der Steuertasten fällt, werden sie dank keypreview auch vom Form verarbeitet, obwohl in diesem Moment wirklich nur eine Texteingabe erfolgen soll

ich möchte aber a) und b) ausschließen. Ich bin mir auch recht sicher, dass das gut geht. Denn bei mehr als einem Memo pro Form landet die eingabe ja auch nicht in jedem Memo, sondern nur in dem, das aktuell im Fokus liegt...

[edit]: ich habe noch etwas rumprobiert; ein Teil des Problems ist anscheinend, dass mein Memo beim Erstellen der Form automatisch den Fokus hat, obwohl ich es noch nicht angeklickt habe, das erklärt zumindest Punkt a) ... mein Problem könnte daher auch so geschildert werden, dass ich es nicht schaffe, den Fokus zur Laufzeit wieder auf die Paintbox zu legen - ich kann ihn nur an Buttons oder andere Eingabefelder und Memos 'abgeben', was zu Problem b) führt ...

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

Re: Form.Keypreview vs. Memo

Beitrag von theo »

Nur kurz dazu: Eine Paintbox kann keinen Fokus erhalten, da sie von TGraphicControl abgeleitet ist.
Du könntest dir eine Komponente von TCustomControl ableiten.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Form.Keypreview vs. Memo

Beitrag von Michl »

mulcheo hat geschrieben:wenn ich eine der Steuertasten (wasd und co.) drücke
Evtl. hilft Dir ja auch die Überlegung wirklich die Steuerungstaste zu verwenden, sprich <Ctrl> + <Taste> für ein Steuern der PaintBox?!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Re: Form.Keypreview vs. Memo

Beitrag von mulcheo »

Michl hat geschrieben:
mulcheo hat geschrieben:wenn ich eine der Steuertasten (wasd und co.) drücke
Evtl. hilft Dir ja auch die Überlegung wirklich die Steuerungstaste zu verwenden, sprich <Ctrl> + <Taste> für ein Steuern der PaintBox?!
leider nicht wirklich - es sind ja nicht nur die Tasten für 'auf' und 'ab', sondern auch noch Tasten für das Einblenden von Masken, Listenwechsel usw. ... ich kann mein Programm jetzt zwar so ändern, dass das Memo nur dann den Fokus erhält, wenn ich auch wirklich etwas eingeben möchte, aber dann muss ich den Fokus auf ein anderes Objekt schieben. Irgendwie verhagelt's mir damit gesamte Steuerung; hat niemand eine Idee, wie ich das lösen könnte? Bzw. gibt es eine Möglichkeit, präzise festzulegen, wann welche Komponente die Eingabe aufnimmt (ich würde dann versuchen, eine Variable setzen, die das zur Laufzeit regelt und die Tasten wahlweise zur Paintbox, zum Edit, zum Memo oder zur Combobox etc. sendet)

höchst ärgerlich das ganze :(

[edit]: :D es gibt doch noch lichte Momente! mir ist gerade eingefallen, dass für die Zeit, während der ich Eingaben im Memo tätige, der Keypreview des Forms deaktiviert werden kann:

Code: Alles auswählen

 
procedure TForm2.Memo1Enter(Sender: TObject);
begin
  Form2.KeyPreview:=false;
end;
 
procedure TForm2.Memo1Exit(Sender: TObject);
begin
  Form2.Keypreview:=true;
end;
damit wäre zumindest der eine Teil des Problems behoben. Bleibt noch zu klären, wie ich den Fokus vom Memo nehmen kann, indem ich beispielsweise auf einen anderen Punkt irgendwo in Form2 klicke (am besten ohne den Fokus dabei auf ein Element zu legen, das seinerseits durch die Tasten, die für die Paintbox bestimmt sind, verändert wird). Ideen?

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Form.Keypreview vs. Memo

Beitrag von Michl »

mulcheo hat geschrieben:Bleibt noch zu klären, wie ich den Fokus vom Memo nehmen kann, indem ich beispielsweise auf einen anderen Punkt irgendwo in Form2 klicke
Du könntest einem unverfänglichen Button den Focus geben:

Code: Alles auswählen

procedure TForm1.FormClick(Sender: TObject);
begin
  Button1.SetFocus;
end;
Ich kenne allerdings Dein Programm nicht, auch kommt mir das Vorgehen irgendwie seltsam vor.

Du könntest auch die PaintBox (mit den Scrollbars) in ein TFrame (oder in eine separate Form) stecken und diesem den Focus geben?!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Antworten