Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - opt. (Tastatur-)Steuerung eines Formulars (KeyAbf., Fokus)


berlingo - Mi 17.07.02 23:40
Titel: opt. (Tastatur-)Steuerung eines Formulars (KeyAbf., Fokus)
Hallo ersteinmal dem Forum´s Mitgliedern,

ich bin ein totaler -Newbee- was Delphi angeht, (Pascal ist mir bekannt) ich möchte gerne eine Anwendung entwickeln die 100% über die Tastatur zu bedienen ist. Ich bin schon über so manches gestolpert, zB. die zwei Arten der Tastaturabfrage. Was mir aber fehlt ist, wie stelle komfortabel fest welches meiner vielen Eingabeflächen (TEdit..) den Focus besitzt ?? Wenn möglich lesbar, sprich "den Namen" der Schaltfläche und nicht eine Nummer wie über -Controls[i]-.

Hat jemand ein heißen Tipp... :roll:


DaSurv - Do 18.07.02 03:19

Versuch´s mal so.

Mach eine Schleife, die jedes Edit abfragt, ob es .focused is.

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var i: integer;
begin
  for i := 1 to 3 do
  begin
    if assigned (findcomponent('Edit' + IntToStr(i))) then
    begin
      if TEdit(findcomponent ('Edit' + IntToStr(i))).focused = True
      then label1.Caption := 'Edit' + IntToStr(i);
    end;
  end;
end;


Code-Tags hinzugefügt. Tino

Diese Prozedur packts du jetzt noch in irgendein Ereignis und dann klappts. (Aber nicht in einen Button oder so, denn dann ändert sich der Focus und der Button ist focused!!!)

DaSurv


Klabautermann - Do 18.07.02 09:06

Hallo,
das geht auch einfacher mit

Quelltext
1:
2:
IF Assigned(MyForm.ActiveControl) THEN
  ShowMessage(MyForm.ActiveControl.Name);


Gruß
Klabautermann


berlingo - Do 18.07.02 12:52

Super, vielen Dank.

Vor lauter Objekten, Methoden und Eigenschaften findet man zu Anfang nicht das was man sucht.. :?

Letzteres kommt den sehr nahe, was ich suche. Vieleicht trifft es auch den Punkt :D

Also müsste ich mit ...
- if MyForm.ActiveControl.Name := "e_vorname" (Name des TEdit) ...
prüfen können, in welchem Feld ein Anwender steht und könnte entsprechend gezielt auf ein Tastendruck "Coursor hoch/runter" reagieren (abhängig von dem Eingabefeld..), mit SetFocus sollte könnte ich dann ein anderes Eingabefeld aktivieren ... richtig ?
...


RockBärbel - Di 23.07.02 00:12
Titel: anderer Vorschlag
Hallo, Klabautermann !

Also, wenn ich dich richtig verstehe, möchtest Du eigentlich eher sowas richtung "old-fashioned", also wie's früher in DOS war: Daß man nämlich lauter Eingabefelder übereinander hat, z.B.:

Blah1: [_______________]
Blah2: [_______________]
Blah3: [_______________]
etc.

...und mit den Pfeiltasten hoch und runter wechseln kann. Also, WENN DU *DAS* WILLST: sowas ähnliches hab ich auch mal gebastelt. Am einfachsten machst Du es Dir, wenn Du's machst wie ich. Dazu tue aber zuerst folgendes:
Jetzt kannst Du meine Version einbauen. Bitte tu Dir einen Gefallen und speichere zwischendurch immer wieder.
HINWEIS: Ich nehme für dieses Beispiel an, daß Du 4 Edit-Fenster hast.
Viel Spass beim Programmieren!

Manfred Wagner


Klabautermann - Di 23.07.02 00:49
Titel: Re: anderer Vorschlag
RockBärbel hat folgendes geschrieben:
Hallo, Klabautermann !
Also, wenn ich dich richtig verstehe, möchtest Du eigentlich [...]


Ich will hier nur helfen, ich glaube du meinst berlingo.

Gruß
Klabautermann


berlingo - Di 30.07.02 23:15

Hallo Klabautermann, hallo RockBärbel...

erstmal zum Stand der Dinge, also ich kann jetzt wunderbar mit den Coursor-Tasten duch meine Felder -rocken-. Mein Lösung kommt der von RockBärbel sehr nahe :lol:

Ok, jetzt aber zu mein weiteren Problem: mein Formular sieht ähnlich wie folgt aus ...

_____________________________
ComboBox. [_______________]
_____________________________
TEdit.Blah1: [_______________]
TEdit.Blah2: [_______________]
TEdit.Blah3: [_______________]
etc.

Wie gesgagt über VK_UP und DOWN rock ich durch die Felder, nur ...die Combobox hat damit leider ein kleineres Problem :( drück ich VK_DOWN/UP wird ein entsprechender Eintrag aus der TSringListe angezeigt, da ich desweiteren auch auf die Eingabe/Wechsel der ComboBox reagiere kommen unschöne Ergebnisse!

Zum Beispiel es soll bei einer leeren ComboBox (aktuelles Item) die Felder unter für eine neue -leer- Eingabe bereitstehen, ist aber leider nicht der Fall da wie gesagt autom. auch der nächste TListEintrag verwendet wird und entsprechende meine DB angewiesen wird eine entsprechenden Datensatz anzuzeigen...grummel..gleiches gilt natürlich für das Editieren eines bestehenden Datensatzes, denn ich dann voher über die ComboBox ausgewählt habe. Auch hier wird der nachfolgende verwendet...(Coursor up)...

Kann man das irgendwie -umtricksen- ?


MathiasH - Mi 31.07.02 13:28

Wie genau soll das bei der Kombobox jetzt funktionieren?

soll er bei rauf-runter ins nächste(Edit) wechseln oder nicht?
wie soll der User dann aber die Items durchblättern können?
willst du die Items vielleicht mit VKLeft/Right durchblättern?
oder sollen die Items per 1. buchstaben angesprochen werden?

oder doch ganz anders?

MathiasH


berlingo - Mi 31.07.02 18:07

Hallo MatthiasH,

ich habe mir heut in der Pause überlegt, das ich ledigtlich die -standard- Möglichkeit der Tab-Taste nutzen werde, um von der KomboBox in den Maskenbereichreich zu gelangen. Ich denke eine entsprechende Abfrage/Verarbeitung kann ich über TForm.FromKeyDown realsieren, ist nihct viel in diesem Fall, setzen von ein paar Hilfsvariablen, je nach Inhalt der KomboBox.

Die restlich Steuerung über VK_DOWN/UP wird schon etwas schwieriger, Trage ich eine entsprechenden ProcedureNamen über den Objektinspector, bei einem ausgwählten Edit-Feld, setzt Delphi dieses in die Beziehung von dem Fomular(!), also betrifft es auch die ComboBox.

Irgenwie habe ich etwas gesehen, gelesen das "FormKeyDown" auch als Methode der untergeordneten Objekte verwendet werden kann. Z.B. MeinEdit.FormKeyDown. Das wäre eine Lösung (mit x-mal so vielen Proceduren wie Edit-Feldern..)....

Aber wer weiß vielicht geht es auch anderes...
(Die KomboBox möchte mit ihren grundlegenden Funktioen nutzen, wie gesagt wechsel ich dann halt mit Tab)


berlingo - Mi 31.07.02 22:14

So jetzt (m)einer kurzen Lösung ... :idea:



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:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
...
    procedure Fokus_setzen;
    begin
        case m_feld of
            1: e_vorname.SetFocus;
            2: e_nachname.SetFocus;
            .....
            8: e_nochwas.SetFocus;
 //         9: combobox.SetFocus
        end;
    ....
    end;
...
begin
  if (Key=VK_DOWN) and (ActiveControl.Name <> 'ComboBox_name') then
  begin
    if m_feld <= 7
    then m_feld := m_feld + 1  // auf das nächste Eingabe-Feld
    else begin
           m_feld := 1;               // auf das erste Eingabe-Feld
           ...
           ... 
        end;
    Fokus_setzen;
  end;

  if (Key=VK_UP) and (ActiveControl.Name <> 'ComboBox_name') then
  begin
    if m_feld >= 2
    then m_feld := m_feld - 1   // auf das voherige Eingabe-Feld
    else m_feld := 8;               // auf das letzte Eingabe-Feld
    Fokus_setzen;
   end;
...
...


Wie gesagt wechsel ich von der ComboBox über Tab in Eingabe-Felder der Maske, ggf. kann man auch über VK_UP/DOWN in die ComboBox zurückspringen (oben angedeutet als Case-Punkt 9).

Ein kleiner Nachteil entsteht, wurde aber in diesem Forum schon in andere Hinsicht angefragt, wenn ich mit TAB aus der ComboBox in das erste TEdit Feld wechsel, muss ich -zweimal- :!: die Pfeil-Taste nach unten drücken, um in das nächste TEdit Feld zu gelangen. Aber dieses ist ersteinmal OK, ich kann damit leben... :D

RockBärbel: Deine Kurzversion mit IntToStr und den einheitlichen Feldnamen ist -quicky-, nur ich liebe sprechende Bezeichner von dieser Seite aus lobt es so..., großes thx, wir hatten die selben Gedanken..