Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Form KeyDown wird nicht ausgelöst trotz keypreview=true


Logikmensch - So 18.11.12 19:22
Titel: Form KeyDown wird nicht ausgelöst trotz keypreview=true
Ich arbeite an einer Grafikanwendung, mit der man sowohl mit Tastatur als auch mit Maus grafische Objekte zeichnen kann (bzw. können soll). Maus ist kein Problem. Aber leider wird das FormKeyDown-Ereignis trotz KeyPreview:=true nicht ausgelöst. Auf der Form sitzt lediglich eine ScrollBox, darin eine PaintBox, in die ich zeichne.

Habe mir in den vergangenen Monaten mit Hilfe von Actions geholfen, denen ich die Shortcuts der Cursortasten zugewiesen hatte. Die haben hervorragend auf die Tastenanschläge reagiert. Hat soweit ja ganz gut gefunzt, bis ich rausfand, dass die Shortcuts auch von anderen Forms der Anwendung ausgeführt wurden, z.B. während man eine Listview mit den Pfeiltasten steuert. Habe die Shortcuts jetzt entfernt, aber nun kriege ich es nicht hin, dass meine Anwendung auch auf die Cursortasten reagiert. Es ist zum Mäusemelken.

Ich habe mich hier im Forum nochmal zu dem Thema belesen. Es heißt ganz allgemein, dass Tastenanschläge grundsätzlich an die Form gehen, wenn Keypreview des Forms auf True ist. Gibt es noch andere Gründe, die das Auslösen von FormKeyDown verhindern?

Stehe jetzt irgendwie total auf dem Schlauch.

Wäre dankbar für eure Hilfe...


Martok - So 18.11.12 20:32

Hallo,

user profile iconLogikmensch hat folgendes geschrieben Zum zitierten Posting springen:
Es heißt ganz allgemein, dass Tastenanschläge grundsätzlich an die Form gehen, wenn Keypreview des Forms auf True ist. Gibt es noch andere Gründe, die das Auslösen von FormKeyDown verhindern?
Manche Tasten tauchen nur in OnKeyPress auf, nicht einzeln in KeyDown/KeyUp.

Vielleicht hast du einen davon getroffen?

Grüße,
Martok


rushifell - Mo 19.11.12 19:09

Logikmensch hat folgendes geschrieben:
Gibt es noch andere Gründe, die das Auslösen von FormKeyDown verhindern?

Ja, wenn Deine ScrollBox den Fokus erhält (aus welchen Gründen auch immer).

Versuch mal folgendes im OnEnter-Ereignis der Scrollbox:


Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.ScrollBox1Enter(Sender: TObject);
begin
ScrollBox1.Enabled:=False;
ScrollBox1.Enabled:=True;
end;


Viele Grüße


Logikmensch - Mo 19.11.12 20:12

Jetzt bin ich echt platt! Der Tipp mit dem Scrollbox-disablen und enablen löst mein Problem... :-)

Das Problem scheint wirklich an der Scrollbox zu liegen. Aber auch an der Edit-Box, die in meiner eigentlichen Anwendung auch in einem Toolbar sitzt. Die Editbox lässt sich trotz allem mit Backspace und den Buchstaben und Zahlentasten editieren, aber die Cursortasten werden souverän abgefangen.

Die Cursortasten treten auch nicht im KeyPress-Ereignis auf, daher wollte ich es im KeyDown unterbringen.

Ich danke euch vielmals!!! Ihr seid klasse! :-) :-) :-)

Hier nochmal den Quelltext meines abgespeckten Versuchsprogramms:


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:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, ToolWin, ComCtrls;

type
  TForm1 = class(TForm)
    ToolBar1: TToolBar;
    Edit1: TEdit;
    ScrollBox1: TScrollBox;
    PaintBox1: TPaintBox;
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure ScrollBox1Enter(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormActivate(Sender: TObject);
begin
  if scrollbox1.canfocus then scrollbox1.SetFocus;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  relevantkey:boolean;
begin
  relevantkey:=true;
  case key of
    vk_right,vk_left,vk_up,vk_down:showmessage('Cursortaste!');
    else relevantkey:=false;
  end;
  if relevantkey then key:=0;
end;

procedure TForm1.ScrollBox1Enter(Sender: TObject);
begin
  ScrollBox1.Enabled:=true;
  ScrollBox1.Enabled:=false;
end;

end.


Hier zum einfachsten Einbinden auch der Formularquelltext:


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:
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 339
  ClientWidth = 445
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = False
  OnActivate = FormActivate
  OnKeyDown = FormKeyDown
  PixelsPerInch = 96
  TextHeight = 13
  object ToolBar1: TToolBar
    Left = 0
    Top = 0
    Width = 445
    Height = 29
    ButtonHeight = 21
    Caption = 'ToolBar1'
    TabOrder = 0
    object Edit1: TEdit
      Left = 0
      Top = 0
      Width = 121
      Height = 21
      TabOrder = 0
      Text = 'Edit1'
    end
  end
  object ScrollBox1: TScrollBox
    Left = 0
    Top = 29
    Width = 445
    Height = 310
    Align = alClient
    TabOrder = 1
    OnEnter = ScrollBox1Enter
    object PaintBox1: TPaintBox
      Left = 168
      Top = 104
      Width = 105
      Height = 105
    end
  end
end


rushifell - Mo 19.11.12 20:30


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.FormActivate(Sender: TObject);
begin
  if scrollbox1.canfocus then scrollbox1.SetFocus;
end;

Wenn Du diese Zeile rausnimmst, kannst Du Dir vermutlich auch meinen Lösungsvorschlag sparen ;-) Wofür brauchst Du die überhaupt?

Viele Grüße


Logikmensch - Di 20.11.12 13:21

user profile iconrushifell hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.FormActivate(Sender: TObject);
begin
  if scrollbox1.canfocus then scrollbox1.SetFocus;
end;

Wenn Du diese Zeile rausnimmst, kannst Du Dir vermutlich auch meinen Lösungsvorschlag sparen ;-) Wofür brauchst Du die überhaupt?

Viele Grüße


Hihi, ja, berechtigte Frage.

Ich habe auf meiner Form auch einige (wenige) Controls drauf, die Focus erhalten können. Z.B. die TEdit-Box. Darum mache ich beim Formularstart bzw. Aktivierung dieses Setfocus, um den Focus von den Steuerelementen wegzunehmen. Die Paintbox kann den Focus nicht erhalten, sonst hätte ich die genommen.
Ich setze den Focus woandershin, weil diese Kompos sonst gleich auf eventuelle Tasteneingaben reagieren, insbesondere diese, die ich beim Zeichnen einsetzen will, aber auch weil bei dem Edit-Feld dieser Cursor dann stets blinkt, was ich als störend empfand.

Aber ich kann Dich trösten, ohne Deinen Vorschlag würde auch dann mein Problem nicht gelöst sein - das habe ich als erstes ausprobiert.
Somit bleibt's dabei: Eine tolle Lösung, die noch dazu sehr einfach umzusetzen war.