Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi FormKeyDown erkennt vk_Left... nicht (https://www.delphipraxis.net/114639-formkeydown-erkennt-vk_left-nicht.html)

taaktaak 28. Mai 2008 17:06


FormKeyDown erkennt vk_Left... nicht
 
Moin, Moin.

Das OnKeyDown-Event eines Forms erkennt die Pfeiltasten (vk_Left, vk_Right, vk_Up, vk_Down) nur, wenn sie gemeinsam mit Alt gedrückt werden. Werden die Tasten allein, oder zusammen mit Shift oder Ctrl betätigt, werden sie nicht erkannt. In einigen Beiträgen hier im Forum wird dieses Verhalten auch mehr oder weniger deutlich benannt. Eine Erklärung/Begründung, warum diese Tasten nur erkannt werden, wenn gleichzeitig Alt gedrückt wird, habe ich nicht gefunden.

Eine Möglichkeit, die Tasten trotzdem zu erkennen, ist GetAsyncKeyState() in einem Timer aufzurufen. Das funktioniert. Allerdings führt das in meinem Fall zu einer schlecht kontrollierbaren Verschiebung eines vergrößerten Bitmaps in einem Image (z.B. Nachlaufeffekt). Nutze ich OnKeyDown (und drücke zusätzlich die Alt-Taste) ist die Verschiebung kontrollierter (d.h. direkter) und wie erwartet zu steuern.

Fragen :
  • Warum werden die vorgenannten Tasten nur erkannt, wenn gleichzeitig Alt gedrückt wird?
  • Gibt es eine weitere Alternative zu GetAsyncKeyState und dem Timer?

DeddyH 28. Mai 2008 17:15

Re: FormKeyDown erkennt vk_Left... nicht
 
Moin taaktaak, ich habe dieses Problem nicht (unter D 2007). Hast Du evtl. einfach nur KeyPreview vergessen (klingt blöd, kann aber passieren)?

Christian Seehase 28. Mai 2008 17:36

Re: FormKeyDown erkennt vk_Left... nicht
 
Moin Ralph,

die Tasten selber sind eigentlich für die Navigation reserviert.
Mit ALT funkioniert es dann, weil sie in Kombination mit ALT standardmässig nicht reserviert sind.

Such' hier mal nach Hier im Forum suchenWM_GETDLGCODE. Da müsstest Du einige Fundstellen bekommen.

taaktaak 28. Mai 2008 19:48

Re: FormKeyDown erkennt vk_Left... nicht
 
Hallo Zusammen!
Also, KeyPreview ist schon aktiviert, daran liegt es nicht. Hm, ich bin immer wieder erstaunt, was ich hier in der DP nicht finde: Werde mich mal in die Suchergebnisse einlesen, vielen Dank vorerst für die Unterstützung :hi:

bluesbear 28. Mai 2008 20:59

Re: FormKeyDown erkennt vk_Left... nicht
 
moin taaktaak,

was mich heute geärgert hat - "ATI Catalyst Control Center". Nach der Installation von SP3 für XP ging hier nix mehr, die Bildschirme blieben schwarz, und wie soll man da konfigurieren, wenn man nix sieht?

Ok, das war OT, aber nachdem alles wieder funktionierte, hat dieses Ding hat mir so einige Shortcuts weggegeklaut. Da kann man programmieren wie ein Weltmeister, und ...

Könnte es sowas sein?

taaktaak 28. Mai 2008 21:05

Re: FormKeyDown erkennt vk_Left... nicht
 
So, kurze Rückmeldung:

Die aufgezeigten Lösungen funktionieren mit den verschiedensten Controls, es ist mr aber nicht gelungen das für das Form selbst umzusetzen. Nach kurzer Grübelei, bin ich zu dem Schluss gekommen, dass ich eigentlich ein ungewöhnliches Verhalten implementieren möchte, welches möglicherweise den Anwender irritiert. Daher ist es wohl doch sinnvoller die Bewegung des Bitmaps mit ALT+Pfeiltasten zu steuern. Hat dann auch den Vorteil, das die Grafik nicht unbeabsichtigt bewegt wird, wenn der Anwender unbeabsichtigt auf diese Tasten drückt.

per aspera ad astra - habe in dieser Frage "zum Licht" gefunden - hihi
Vielen Dank für die Antworten!

// PS : Sehe gerade den roten Kasten! Hab' auch 'ne ATI. Werde ich noch mal prüfen, danke für den Hinweis...

SirThornberry 28. Mai 2008 21:47

Re: FormKeyDown erkennt vk_Left... nicht
 
Zitat:

Die aufgezeigten Lösungen funktionieren mit den verschiedensten Controls
Welche Lösungen hast du probiert? WM_GETDLGCODE hätte eigentlich die Lösung sein müssen.

Delphi-Quellcode:
private
    procedure FWMGETDLGCODE(var Msg : TWMGetDlgCode); message WM_GETDLGCODE;
[...]
procedure TYourForm.FWMGETDLGCODE(var Msg : TWMGetDlgCode);
begin
  inherited;
  Msg.Result := Msg.Result or DLGC_WANTARROWS;
end;
Bei mir funktioniert folgendes übrigens (Delphi7):
Delphi-Quellcode:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if (Key = VK_LEFT) then
    caption := 'links'
  else if (Key = VK_RIGHT) then
    caption := 'rechts';
end;
Allerdings nur wenn kein Control den Focus hat (ansonsten gehen die Tasten an das Control (selbst mit KeyPreview := True))

mit
Delphi-Quellcode:
ActiveControl := nil;
kannst du den Focus von den Controls nehmen.

taaktaak 29. Mai 2008 07:58

Re: FormKeyDown erkennt vk_Left... nicht
 
Guten Morgen Zusammen!

@bluesbear: Danke für den Hinweis, ATI ist in meinem Fall unschuldig. Es stimmt mich allerdings nachdenklich, dass Programme in der Lage sind, das Verhalten eines anderen Programmes so grundlegend zu beeinflussen. Hat sicherlich in bestimmten Fällen seine Vorteile, aber wenn das praktisch unbemerkt geschieht, dann kann man ja auf der Suche nach der Ursache für ein absonderliches Verhalten ja geradezu Verzeifeln.

@SirThornberry: Besonderen Dank für dein Posting, obwohl ich die Angelegenheit schon ad acta gelegt hatte. Hatte es ergebnislos mit GetDlgCode() und einer eigenen WinProc versucht. Der Hinweis

Zitat:

Allerdings nur, wenn kein Control den Focus hat (ansonsten gehen die Tasten an das Control (selbst mit KeyPreview := True))
löst nun auch auf, warum es nicht funktioniert hat: Auf meinen ansonsten leeren Test-Forms ist standardmäßig immer ein Close-Button placiert. Und der hat nach Aufruf natürlich den Focus.

Mit ActiveControl:=nil funktioniert's - nun stellt sich allerdings die Frage, wo man den Befehl sinnvoll anordnet. OnFormActivate() wäre eine Möglichkeit: Dann werden die Tasten erkannt, bis irgendein anderes Control den Focus bekommen hat. Danach ist Schluss, da ActiveControl aktualisiert wird und nicht mehr nil ist. Die Reaktion, nun in allen focussierbaren Controls in deren OnEnter() das ActiveControl auf nil zu setzen, ist nicht praktikabel, da dann z.B. Buttons "ihren" Click nicht mehr empfangen. Also müssten, um dies auch dem Anwender deutlich zu machen, die "störenden" Controls deaktiviert (und auch wieder aktiviert) werden.

Dazu fällt mir im Augenblick keine vollständig automatisierte Lösung ein. Hmm, oder so: Man wertet das OnClick() des Image aus, in dem das Bitmap verschoben werden soll. Zur Kennzeichnung, dass nun das Image "den Focus" hat, zeichnet man einen farbigen Rahmen um das Image. Im OnClick() werden alle "gefährlichen" Controls disabled und ActiveControl auf nil gesetzt. Schön und gut, aber dieser Verschiebemodus muss auch wieder ausgeschaltet werden können. Also bei erneutem OnClick() vice versa!?

Hm, da ist es wohl deutlicher, wenn es einen separaten Button gibt, der dieses An/Aus steuert.

Tja, es gibt verschiedene Lösungsansätze, schauen wir mal...
:hi:

taaktaak 11. Jun 2008 15:03

Re: FormKeyDown erkennt vk_Left... nicht
 
Moin, Moin.

Habe das Thema notgedrungen heute noch einmal anfassen müssen - und konnte feststellen, dass folgende Lösung möglich ist: Der Lösungsansatz wie er von SirThornberry in #7 beschrieben wurde, hat funktioniert - leider konnte ich aber keinen passenden Ort für den Ausdruck ActiveControl:=nil finden. Nun meinte ich ihn gefunden zu haben:

Als erste Zeile im OnKeyPressed eingesetzt funktioniert es wie erwartet! Leider mit einem negativen Nebeneffekt: Damit verliert natürlich das vorher aktive Control den Focus. Nun, dachte ich, dann speichere/restauriere es. Das führte zu folgendem Konstrukt:

Delphi-Quellcode:
procedure Tfo~.FormKeyDown(Sender:TObject;var Key:Word;Shift:TShiftState);
var TmpActiveControl : TWinControl;
begin
  TmpActiveControl:=ActiveControl;
     ActiveControl:=nil;

  case Key of
    vk_Left : showmessage('left');
    //..
    end;

  ActiveControl:=TmpActiveControl; // damit geht's nicht?!
end;
Das Ergebnis ist nun leider wieder so, dass es nicht mehr funktioniert. Und das irritiert mich gewaltig. Obwohl die case()-Auswertung ja vor dem Restaurieren erfolgt, hat das ActiveControl:=nil nun keinen Effekt mehr. Wird die letzte Zeile auskommentiert, werden die Pfeiltasten wieder erkannt. Komisch ....


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:49 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