Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wie Entertaste bei Button abfangen? (https://www.delphipraxis.net/66106-wie-entertaste-bei-button-abfangen.html)

Armageddon 24. Mär 2006 19:41


Wie Entertaste bei Button abfangen?
 
Hallöchen,

kurze Frage. Möchte durch drücken der Entertaste automatisch zum nächsten Editfeld weiterspringen. Soweit funktionert das auch ganz wie ich es möchte. Nur wenn ich auf einen Button komme welcher nunmal innerhalb der Editfelder auf meinem Form in der TabOrder kommt und ich die Entertaste drücke um zum nächsten Editfeld zu kommen wird der Button gedrückt/ausgelöst. Arrrgs. :wall:

Habe es schon im OnKeyDown versucht mit:

Delphi-Quellcode:
If Key = VK_RETURN then Key := 0;
aber irgendwie wills nicht so wie ich will. Wie löse ich das am besten?
Mir reicht es schon wenn ich die Leertaste drücke damit der Button gedrückt/ausgelöst wird und das tuts ja schon von Haus aus.

Danke schonmal,
Markus

Christian Seehase 24. Mär 2006 20:10

Re: Wie Entertaste bei Button abfangen?
 
Moin Markus,

nur mal so als Idee:
Wenn Du mit der Entertaste von einem Feld zum nächsten springst, wirst Du Dir ja auch eine Reihenfolge überlegt haben, in der die Felder angesprungen werden sollen.
Also könnstest Du einfach bei Enter den Fokus direkt setzen (Editxxx.SetFocus).

Armageddon 24. Mär 2006 20:15

Re: Wie Entertaste bei Button abfangen?
 
Die Reihenfolge hab ich mir wie Du sagst überlegt. Und wird auch nach und nach richtig abgearbeitet und auch die beiden Button sind in der TabOrder drin weil ich auch dort hin muß. Nur hab ich eben das Problem sobald ich auf nem Button angekommen bin und ich Enter für das nächste DLGCtrl (hoffe ich schreib das jetzt richtig) drücke es so interpretiert wird wie wenn ich mit der Maus auf den Button klicke. Da muß es doch was geben wo dies unterbindet und der Button nur gedrückt wird wenn ich die Leertaste drücke. Brauch das weil es noch einige PC's gibt welche keine Maus haben wo das drauf laufen soll.

SirThornberry 24. Mär 2006 20:19

Re: Wie Entertaste bei Button abfangen?
 
Anwender die mit PC's ohne Maus arbeiten arbeiten in aller Regel mit der Tabtaste. Nicht umsonst heißt das Property auch TabStop, weil es eben mit der Tabtaste angesprungen werden kann. Man sollte also die Bedienführung windowsmäßig lassen. So das Enter auführen des Buttons ist und Tab zum springen von einem Control zum nächsten. Du könntest noch vesuchen ob es beim Button ein OnKeyPress oder ähnliches gibt.

Armageddon 24. Mär 2006 20:23

Re: Wie Entertaste bei Button abfangen?
 
Ist mir schon klar das dies von der Standart Windowsdingsbums weit weg ist. Aber die Anwendergruppe auf welche es abzeilt gibt ein paar Zahlen über den Zehnerblock ein und drückt halt nunmal gern die Entertaste auf dem Zehnerblock um zum nächsten Eingabefeld zu kommen. Die Tab-Taste kennen die da zum Großteil nicht weil die das auch von anderer Software so gewöhnt sind. :-( Leider. Im KeyPress passiert genau das gleiche.

Hansa 24. Mär 2006 20:34

Re: Wie Entertaste bei Button abfangen?
 
Zitat:

Zitat von SirThornberry
...Man sollte also die Bedienführung windowsmäßig lassen. So das Enter auführen des Buttons ist und Tab zum springen von einem...

...und somit eventuell ein Programm schreiben, was keiner DIN genügt und somit nicht nach ISO??? zertifiziert werden wird ! Das ist jetzt allgemein gemeint wegen Tab zum nächsten Control. Wird eine Tastatureingabe erwartet, z.B. bei Edits, so sollte das auf jeden Fall mit Enter abzuschließen sein, ähnlich wie bei Schreibmaschine oder Taschenrechner. Um allerdings auch dem von M$ gesetzten NICHT Industriestandard zu genügen, hindert einen aber keinen daran, WM_NEXTDLGCTRL nicht nur bei Tab, sondern auch bei Enter auszulösen.

Armageddon 24. Mär 2006 20:40

Re: Wie Entertaste bei Button abfangen?
 
*grins* Genau so seh ich das auch aber wie stell ich das an? Der Button wehrt sich. *lol*

SirThornberry 24. Mär 2006 20:41

Re: Wie Entertaste bei Button abfangen?
 
Ich würde dann einfach vorschlagen keinen Button zu verwenden sondern selbst eine Komponente zu schreiben. Oder im OnClick des Buttons zu prüfen ob die Entertaste gerade gedrückt ist.

Armageddon 24. Mär 2006 20:42

Re: Wie Entertaste bei Button abfangen?
 
Zitat:

OnClick
Ah das ne gute Idee. Soweit hab ich noch gar nicht gedacht. Werd ich Morgen gleich mal ausprobieren. Danke

engine 24. Mär 2006 20:59

Re: Wie Entertaste bei Button abfangen?
 
Zitat:

Zitat von SirThornberry
Anwender die mit PC's ohne Maus arbeiten arbeiten in aller Regel mit der Tabtaste. Nicht umsonst heißt das Property auch TabStop, weil es eben mit der Tabtaste angesprungen werden kann. Man sollte also die Bedienführung windowsmäßig lassen. So das Enter auführen des Buttons ist und Tab zum springen von einem Control zum nächsten. Du könntest noch vesuchen ob es beim Button ein OnKeyPress oder ähnliches gibt.

Das kommt ganz auf die Anwendung an. Sicher sollte man sich immer an eine Windowseinheitliche Richtlinie halten, es gibt aber durchaus auch Anwendungsfälle bei denen es effektiver ist einen anderen Weg zu gehen. Als Beispiel möchte ich Berechnungsprogramme für den Maschinenbau heranziehen. Hierbei ist die Reihenfolge der Eingabe meistens vorgegeben. Aus meiner eigenen Erfahrung kann ich sagen, das der Wechsel zwischen den Controls nach einer Eingabe mit einem Return wesentlich angenehmer ist (jedenfalls für Rechtshänder).

Du kannst es im OnKeyPress so lösen.
Delphi-Quellcode:
procedure TForm1.LabeledEdit2KeyPress(Sender: TObject; var Key: Char);
begin
  case Ord(Key) of
    13 : begin     //Wenn RETURN [13] gedrückt wurde
           LabeledEdit3.SetFocus; //Den Fokus an das nächste Steuerelement
           key := #0;
         end;
  end;
end;
engine

Hansa 24. Mär 2006 21:07

Re: Wie Entertaste bei Button abfangen?
 
@Armageddon : genau so ist das.

Nimm einen SpeedButton und fertig. Dann taucht das Problem erst gar nicht auf, weil kein Focus. Dann würde ich für Edits usw. Form-global (wie bereits gesagt) das OnkeyPress bei Enter auch auf WM_NEXTDLGCTRL auswerten. Suche mal nach EnterTab.

@Engine : dto. Tipse würde irgendwann Krankenschein machen müssen wegen Handverrenkung, um bei einzugebenden Zahlenkollonnen mit dem kleinen rechten Finger die Tab-Taste links oben zu erreichen. :lol: Solche Sachen stehen in den DINs drin, die M$ anscheinend aber nicht interessieren.

Daniel Schuhmann 24. Mär 2006 23:19

Re: Wie Entertaste bei Button abfangen?
 
Zitat:

Zitat von Hansa
Solche Sachen stehen in den DINs drin, die M$ anscheinend aber nicht interessieren.

MS ist aber ne amerikanische Firma, die werden sich da kaum für Forderungen eines deutschen Instituts interessieren. Zudem ist die ganze Bedienung "historisch gewachsen" (ich glaub bei ~15 Jahren kann man das im IT-Bereich schon sagen) und eben nicht von heut' auf morgen zu ändern.

Hansa 25. Mär 2006 00:31

Re: Wie Entertaste bei Button abfangen?
 
Zitat:

Zitat von Daniel Schuhmann
... Zudem ist die ganze Bedienung "historisch gewachsen" (ich glaub bei ~15 Jahren kann man das im IT-Bereich schon sagen) und eben nicht von heut' auf morgen zu ändern.

Was soll wo geändert werden ? RETURN kommt von "Carriage Return" und das bedeutet "Wagenrücklauf". Diese Taste war immer schon ganz rechts, relativ groß und zwar seit Anfang des 20. Jahrhunderts. Selbst 15 Jahre reichen deshalb nicht aus, einen eigenen "Standard" zu setzen und diese Arbeitsweise zu ersetzen. Was konkret zu tun ist, das steht im Thread. 8)

Armageddon 31. Mär 2006 15:25

Re: Wie Entertaste bei Button abfangen?
 
So hab mich jetzt nochmal dran versucht. Das ich mit Enter vom einen Edit zum nächsten springen kann ist mir bekannt und verwende ich auch so. Nur leider haut das bei dem Button nicht hin. Und ich kann den Button nicht aus der TabOrder nehmen!!! Wie kann ich im OnKlick des Buttons abfragen ob es durch das drücken der Enter-Taste ausgelöst wurde? Das ist immer noch mein Problem. Das kann doch nicht so schwer sein. :wall:

Hawkeye219 31. Mär 2006 20:19

Re: Wie Entertaste bei Button abfangen?
 
Hallo Armageddon,

Du könntest die WindowProc des Buttons ersetzen:

Delphi-Quellcode:
type
  TForm1 = class (TForm)
    Button1: TButton;
    procedure FormCreate (Sender: TObject);
    procedure FormDestroy (Sender: TObject);
  private
    svWndProc : TWndMethod;
    procedure NewWndProc (var aMessage: TMessage);
  end;

procedure TForm1.FormCreate (Sender: TObject);
begin
  svWndProc := Button1.WindowProc;
  Button1.WindowProc := NewWndProc;
end;

procedure TForm1.FormDestroy (Sender: TObject);
begin
  Button1.WindowProc := svWndProc;
end;

procedure TForm1.NewWndProc (var aMessage: TMessage);
begin
  if ((aMessage.Msg = CN_KEYDOWN) and (aMessage.WParam = 13)) then
    aMessage.WParam := 9;
  svWndProc (aMessage);
end;
In der neuen WindowProc wird die CN_KEYDOWN-Nachricht für den Button abgefangen und die Taste RETURN (Code 13) durch TAB (Code 9) ersetzt. Ein Drücken von RETURN führt beim Button nun zum Fokussieren des nächsten Dialogelements.

Gruß Hawkeye

gfjs 1. Apr 2006 06:52

Re: Wie Entertaste bei Button abfangen?
 
Guten Morgen, allerseits.

Kann man nicht mit KeyPreview erreichen, dass die Eingabe zuerst vom Formular bearabeitet wird? Dann könnte man doch an dieser Stelle den Focus auf das nächste Steuerelement setzen, wenn >Enter< gedrückt wurde?!

Bin noch Anfänger und hoffe, dass ich da nicht allzu falsch liege.

mfg gfjs

Armageddon 1. Apr 2006 09:38

Re: Wie Entertaste bei Button abfangen?
 
Danke für den Code Hawkeye219,

nur leider läßt es sich nicht kompilieren. Delphi ist mit der Zeile irgenwie nicht ganz zufrieden:

Delphi-Quellcode:
  private
    svWndProc : TWndMethod;

Hawkeye219 1. Apr 2006 10:01

Re: Wie Entertaste bei Button abfangen?
 
Merkwürdig, der Code läuft bei mir unter Delphi 6 und Delphi 2006 einwandfrei. :gruebel:
TWndMethod ist in den Units Classes und Controls definiert, und die sollten eigentlich in deiner Uses-Liste enthalten sein.

Wie sieht denn die Fehlermeldung aus?

Armageddon 1. Apr 2006 10:38

Re: Wie Entertaste bei Button abfangen?
 
Zitat:

Wie sieht denn die Fehlermeldung aus?
Felddefinition nicht erlaubt nach Methoden oder Eigenschaften. Hab das wohl irgendwie am falschen Fleck so wie es aussieht. Ich häng mal die Unit an. Bzw. den Brocken Code vielleicht siehst Du ja meinen Fehler:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Menus, XPMan, ComCtrls, StdCtrls, Buttons, jpeg, IniFiles,
  LMDOneInstance, LMDUtils, LMDCustomControl,
  LMDCustomPanel, LMDCustomBevelPanel, LMDCustomParentPanel,
  LMDCustomGroupBox, LMDGroupBox, LMDIniCtrl, LMDApplicationCtrl,
  LMDControl, LMDBaseControl, LMDBaseGraphicControl, LMDGraphicControl,
  LMDBaseImage, LMDCustomLImage, LMDLImage, LMDBaseController,
  LMDCustomContainer, LMDCustomImageList, LMDImageListConnector, ImgList,
  LMDClock, LMDImageList, LMDCustomButton, LMDButton, LMDClass,
  RichEdit, Clipbrd, LMDCustomStatusBar, LMDStatusBar, LMDWndProcComponent,
  LMDFormStyler, LMDCustomComponent;

type
  TForm1 = class(TForm)
    PopupMenu1: TPopupMenu;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    Panel1: TPanel;
    Image1: TImage;
    Label1: TLabel;
    GroupBox1: TGroupBox;
    GroupBox2: TGroupBox;
    RichEdit1: TRichEdit;
    RichEdit2: TRichEdit;
    GroupBox4: TGroupBox;
    GroupBox3: TGroupBox;
    TL_V_DREHZAHL: TLabel;
    TL_V_VC: TLabel;
    TL_V_VORSCHUB: TLabel;
    TL_V_REFPUNKT: TLabel;
    TL_V_VERSATZ: TLabel;
    TL_V_BREITE: TLabel;
    TL_V_AUFMASS: TLabel;
    TL_V_TEILE: TLabel;
    TL_V_UEBERWACHUNG: TLabel;
    TL_V_MATERIAL: TLabel;
    TL_VS: TLabel;
    TL_VQ: TLabel;
    TE_V_DREHZAHL: TEdit;
    TE_V_VC: TEdit;
    TE_V_VORSCHUB: TEdit;
    TE_V_REFPUNKT: TEdit;
    TE_V_VERSATZ: TEdit;
    TE_V_BREITE: TEdit;
    TE_V_AUFMASS: TEdit;
    TE_V_TEILE: TEdit;
    TE_V_UEBERWACHUNG: TEdit;
    TE_V_MATERIAL: TEdit;
    TE_VS: TEdit;
    TE_VQ: TEdit;
    Panel3: TPanel;
    LMDOneInstance1: TLMDOneInstance;
    Panel4: TPanel;
    TL_V_AUSSPANN: TLabel;
    TL_VE: TLabel;
    TL_VZ: TLabel;
    TE_V_AUSSPANN: TEdit;
    TE_VE: TEdit;
    TE_VZ: TEdit;
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    XPManifest1: TXPManifest;
    TL_VA: TLabel;
    TE_VA: TEdit;
    BB_V_REFPUNKT: TBitBtn;
    TE_V_ANSCHLAG: TEdit;
    TL_V_ANSCHLAG: TLabel;
    TL_VX: TLabel;
    TE_VX: TEdit;
    BB_M27: TBitBtn;
    LMDImageList1: TLMDImageList;
    BB_V_MATERIAL: TBitBtn;
    Timer1: TTimer;
    StatusBar1: TStatusBar;
    procedure FormDestroy(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure Vorschau(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure LMDOneInstance1Custom(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
    procedure EditKommaExit(Sender: TObject);
    procedure EditNumerischKeyPress(Sender: TObject; var Key: Char);
    procedure EditEnter(Sender: TObject);
    procedure BB_V_REFPUNKTClick(Sender: TObject);
    procedure TE_V_TEILEExit(Sender: TObject);
    procedure BB_V_REFPUNKTEnter(Sender: TObject);
    procedure BB_V_REFPUNKTExit(Sender: TObject);
    procedure BB_M27Click(Sender: TObject);
    procedure BB_M27Enter(Sender: TObject);
    procedure BB_M27Exit(Sender: TObject);
    procedure BitBtn1Enter(Sender: TObject);
    procedure BitBtn2Enter(Sender: TObject);
    procedure PageControl1Enter(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure BB_V_MATERIALClick(Sender: TObject);
    procedure BB_V_MATERIALEnter(Sender: TObject);
    procedure TE_V_DREHZAHLExit(Sender: TObject);
    procedure PageControl1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private-Deklarationen }
    procedure WMEXITSIZEMOVE(var Msg : TWMSIZE); message WM_EXITSIZEMOVE;
    svWndProc : TWndMethod;
    procedure NewWndProc (var aMessage: TMessage);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  M27, Maschinenauswahl: Boolean;
  R: Integer;
  V_ANSCHLAG, V_DREHZAHL, V_VC, V_VORSCHUB, V_REFPUNKT, V_VERSATZ, V_BREITE: String;
  V_AUFMASS, V_TEILE, V_UEBERWACHUNG, V_MATERIAL, VS, VQ: String;
  V_AUSSPANN, VE, VZ, VA, VX, HUB, Ini_Name: String;
  V_WKSTLAENGE, V_HUBZUGABE, Maschtyp: String;
  K1, K2: String;
  aktControl: String;

implementation

uses Unit2, Unit3, Unit4, MTRMethoden;

{$R *.dfm}

procedure TForm1.WMEXITSIZEMOVE(var Msg: TWMSIZE);
var
  minhoehe: Integer;
begin
  BitBtn1.Top := ClientHeight - BitBtn1.Height - StatusBar1.Height - R * 2;
  BitBtn2.Top := BitBtn1.Top;
  PageControl1.Height := BitBtn1.Top - PageControl1.Top - R;
  Label1.Top := TabSheet1.Height - R - Label1.Height;
  Image1.Height := Label1.Top - R - Image1.Top;
  Image1.Width := Image1.Height;
  GroupBox3.Left := Image1.Left + Image1.Width + R;
  GroupBox4.Left := GroupBox3.Left;
  PageControl1.Width := GroupBox3.Left + GroupBox3.Width + Image1.Left
    + ( PageControl1.Width - TabSheet1.Width );
  minhoehe := GroupBox4.Top + GroupBox4.Height + Label1.Height * 5
    + BitBtn1.Height;
  if ClientHeight < minhoehe then
  begin
    ClientHeight := minhoehe;
    SendMessage(self.Handle, WM_EXITSIZEMOVE, 0, 0);
  end;
  if ClientHeight > Screen.WorkAreaHeight then
  begin
    ClientHeight := minhoehe;
    SendMessage(self.Handle, WM_EXITSIZEMOVE, 0, 0);
  end;
  ClientWidth := PageControl1.Left + PageControl1.Width + PageControl1.Left;
  BitBtn1.Left := ClientWidth div 4 - BitBtn1.Width div 2;
  BitBtn2.Left := ClientWidth div 4 * 3 - BitBtn2.Width div 2;
//Vorschaubereich
  GroupBox1.Left := R; GroupBox1.Top := R;
  GroupBox1.Height := TabSheet2.Height - GroupBox1.Top - R;
  GroupBox2.Top := GroupBox1.Top;
  GroupBox2.Height := GroupBox1.Height;
  GroupBox1.Width := TabSheet2.Width div 2 - 2 * GroupBox1.Left;
  GroupBox2.Width := GroupBox1.Width;
  GroupBox2.Left := TabSheet2.Width div 2 + GroupBox1.Left;
  Left := Screen.WorkAreaWidth div 2 - Width div 2;
  Top := Screen.WorkAreaHeight div 2 - Height div 2;
end;

procedure TForm1.NewWndProc (var aMessage: TMessage);
begin
  if ((aMessage.Msg = CN_KEYDOWN) and (aMessage.WParam = 13)) then aMessage.WParam := 9;
  svWndProc (aMessage);
end;

Hawkeye219 1. Apr 2006 10:48

Re: Wie Entertaste bei Button abfangen?
 
Die Online-Hilfe kann das viel besser erklären als ich. :zwinker:
Einfach mit der Maus die Fehlermeldung anklicken und F1 drücken...

Gruß Hawkeye

Armageddon 1. Apr 2006 11:23

Re: Wie Entertaste bei Button abfangen?
 
Bin wohl heute Morgen noch nicht ganz auf der Höhe. Klappt aber wunderbar. Isses eigentlich schlimm wenn ich das weg lasse?
Delphi-Quellcode:
procedure TForm1.FormDestroy (Sender: TObject);
begin
  Button1.WindowProc := svWndProc;
end;
Lasse ich es drin und ich schliesse mein Progrämmchen mit Close so kommt ein Fehler wegen einem ungültigen Fensterhandle-1400. Mach ich es weg gehts wunderbar. Oder hab ich dann etwas was übrig bleibt?

Hawkeye219 1. Apr 2006 11:35

Re: Wie Entertaste bei Button abfangen?
 
In dieser Zeile erhält der Button lediglich seine "alte" WindowProc zurück.
Weil das Formular aber sowieso zerstört wird, sollte das nicht mehr notwendig sein.
Beim meinem Test kommt auch mit dieser Zeile keine Fehlermeldung.

Gruß Hawkeye

Armageddon 1. Apr 2006 12:30

Re: Wie Entertaste bei Button abfangen?
 
Ich glaub ich geh wieder ins Bett.
Hab den Fehler gefunden. Wenn bei mir der BitButton BB_V_REFPUNKT heist, dann sollte ich das da auch richtig ändern. Das kommt davon wenn man fäufig nur Copy und Paste benutzt. :wall:


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz