Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Namen der virtuellen Tastencodes (https://www.delphipraxis.net/74525-namen-der-virtuellen-tastencodes.html)

Mazel 4. Aug 2006 14:53


Namen der virtuellen Tastencodes
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich möchte die Namen der virtuellen Tastencodes ermitteln, also wenn ich die Bild nach oben Taste drücke, soll in einem Editfeld BILD-NACH-OBEN stehen.

Mir ist in Winamp aufgefallen, dass es trotz seiner englischen Sprache, die deutschen Namen der Tasten anzeigt. Das heißt für mich, dass es da eine Funktion geben muss um diese Namen zu ermitteln. Wie kann ich dies unter Delphi erreichen?

Im Anhang mal ein Bild von Winamp (Hotkeys).

Gruß
Mazel

cruiser 4. Aug 2006 15:02

Re: Namen der virtuellen Tastencodes
 
MSDN-Library durchsuchenGetKeyNameText sieht doch gut aus, oder?

Mazel 4. Aug 2006 15:11

Re: Namen der virtuellen Tastencodes
 
Danke,

aber wie wende ich dei Funktion nun an?

himitsu 4. Aug 2006 15:14

Re: Namen der virtuellen Tastencodes
 
na so wie jede aus der WinAPI?

erstma gucken, ob sie bei dir definiert is (eventuell in der Windows.pas), wenn ncith dann woanders gucken, oder halt selber definieren ... steht ja alles wichtige da
und dann entsprechend den angaben aus'm MSDN/PSDK aufrufen.

Mazel 4. Aug 2006 15:21

Re: Namen der virtuellen Tastencodes
 
Definiert ist sie, nur kommt bei mir kein Name am Ende heraus: (habe ich beim suchen gefunden)
Delphi-Quellcode:
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  var p: PChar;
begin
  p:=StrAlloc(150);
  If GetKeyNameText(16, p, SizeOf(p)) > 0 then Edit1.Text:=StrPas(p);
end;

Mazel 4. Aug 2006 21:10

Re: Namen der virtuellen Tastencodes
 
Liste der Anhänge anzeigen (Anzahl: 1)
HI,

ich habe jetzt eine andere Lösung, nur gibt es dabei noch ein Problem, siehe Anhang:
Delphi-Quellcode:
procedure TForm1.EditHotkeyKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  TempShortCut: TShortCut;

begin
  TempShortCut:=ShortCut(Key, shift);
  EditHotkey.Text:=ShortCutToText(TempShortCut);
end;
Warum stehe bei einem Druck auf die STRG-Taste STRG 2 mal da und einmal davon klein?

Gruß
Mazel

SirThornberry 4. Aug 2006 22:16

Re: Namen der virtuellen Tastencodes
 
Zitat:

Zitat von Mazel
Definiert ist sie, nur kommt bei mir kein Name am Ende heraus: (habe ich beim suchen gefunden)
Delphi-Quellcode:
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  var p: PChar;
begin
  p:=StrAlloc(150);
  If GetKeyNameText(16, p, SizeOf(p)) > 0 then Edit1.Text:=StrPas(p);
end;

Als Dritter Parameter wird die verfügbare Länge erwartet. Du übergibst aber die Größe von PChar. Und PChar ist nur ein Pointer womit die Größe bei dir nur 4 wäre. Wenn du mit StrAlloc, 150 zeischen reservierst schreib die 150 doch statich rein.

Robert Marquardt 5. Aug 2006 05:55

Re: Namen der virtuellen Tastencodes
 
Besser gleich einen Puffer verwenden, denn sonst gibt es ein Speicherleck.
Delphi-Quellcode:
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  var
    Buffer: array [0..255] of Char;
begin
  if GetKeyNameText(16, @Buffer[0], SizeOf(Buffer)) > 0 then
    Edit1.Text := Buffer;
end;
Wenn man sich allerdings ernsthaft mit den Tastencodes beschaeftigen will, dann ist WM_KEYDOWN bzw WM_SYSKEYDOWN abzufangen der bessere Ansatz.

Mazel 5. Aug 2006 08:21

Re: Namen der virtuellen Tastencodes
 
Hi,

ich habe jetzt die letzen beiden Version probiert, leider ohne Erfolg. Es kommt kein Zeichen (ALT, STRG, etc.) in das Editfeld.
Delphi-Quellcode:
//Version 1
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  Buffer: array [0..255] of Char;
 
begin
  If GetKeyNameText(16, @Buffer[0], SizeOf(Buffer)) > 0 then Edit1.Text:=Buffer;
end;

//Version 2
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  p: PChar;
 
begin
  p:=StrAlloc(150);
  If GetKeyNameText(16, p, 150)) > 0 then Edit1.Text:=StrPas(p);
end;
Nur bei folgender Version bekomme ich die Namen in das Editfeld mit dem Problem das es doppelt hinein geschrieben wird:
Delphi-Quellcode:
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  TempShortCut: TShortCut;

begin
  TempShortCut:=ShortCut(Key, Shift);
  EditHotkey.Text:=ShortCutToText(TempShortCut);
end;
Weis jemand wo die Fehler liegen?

Gruß
Mazel

xaromz 5. Aug 2006 08:43

Re: Namen der virtuellen Tastencodes
 
Hallo,

hast Du schon mal den ErrorCode der Funktion ausgelesen? Der ist nämlich genau dazu da, um Fehler einzugrenzen :zwinker: .

[Edit]
Ich habe gerade bemerkt, LastError ist einfach Null. Das Problem ist, das KeyDown-Event liefert keinen gültigen KeyCode für diese Funktion. So funktioniert's:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Label1: TLabel;
  protected
    procedure DoKeyDown(var Msg: TWMKeyDown); message WM_KEYDOWN;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.DoKeyDown(var Msg: TWMKeyDown);
var
  Buffer: array [0..50] of Char;
begin
  if GetKeyNameText(Msg.KeyData, @Buffer[0], 50) > 0 then
    Label1.Caption := Buffer;
end;
Blöderweise mag mich allerdings die Alt-Taste nicht. Die Methode wird gar nicht ausgeführt. Das liegt daran, dass Alt das System-Menü aktiviert (drück danach mal "Nach Unten").
[/Edit]

Gruß
xaromz

Flocke 5. Aug 2006 09:53

Re: Namen der virtuellen Tastencodes
 
Zitat:

Zitat von xaromz
Blöderweise mag mich allerdings die Alt-Taste nicht.

Dafür musst du die Meldung WM_SYSKEYDOWN nehmen (hat dieselben Parameter).

Mazel 5. Aug 2006 09:59

Re: Namen der virtuellen Tastencodes
 
Hi,

das funktioniert leider nur, wenn ich keine weiteren Objekte auf meiner Form habe, sonst bekomme ich keinen Key zurück. Leider wird dann auch nicht die Kombination wie STRG+ALT+F angezeigt, sondern nur STRG.
Immer wenn ich eine Kombination drücke soll diese auch angezeigt werden, sonst würden Hotkeys keinen sinn machen, denn man sollte schon sehen welchen Hotkey man benutzt.
Zitat:

Zitat von Mazel
Nur bei folgender Version bekomme ich die Namen in das Editfeld mit dem Problem das es doppelt hinein geschrieben wird:
Delphi-Quellcode:
procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  TempShortCut: TShortCut;

begin
  TempShortCut:=ShortCut(Key, Shift);
  EditHotkey.Text:=ShortCutToText(TempShortCut);
end;
Weis jemand wo die Fehler liegen?

Wenn das nicht mehr doppelt hineingeschrieben werden würde, wär das die optimale Lösung für mein Problem.

Gruß
Mazel

Hawkeye219 5. Aug 2006 10:51

Re: Namen der virtuellen Tastencodes
 
Hallo Mazel,

vielleicht läßt sich dein Problem mit einem kleinen Kniff lösen:

Delphi-Quellcode:
function ShiftKeyToStr (aShift: TShiftState; aKey: Word): string;
var
  SC : TShortCut;
begin
  if (aKey in [VK_SHIFT, VK_CONTROL, VK_MENU]) then
    begin
      SC := ShortCut(Ord('A'), aShift);
      Result := ShortCutToText(SC);
      SetLength (Result, Length(Result) - 2);
    end
  else
    begin
      SC := ShortCut(aKey, aShift);
      Result := ShortCutToText(SC);
    end;
end;
Gruß Hawkeye

Mazel 5. Aug 2006 12:22

Re: Namen der virtuellen Tastencodes
 
Hi,

danke, das funktioniert super :thumb: . Genau das was ich gebraucht habe. Nun habe ich aber eine Frage: Warum muss ich den Buchstaben A hier in dieser funktion verwenden? Ich hatte eine einfachere aber ähnliche Ansatzweise, nur hatte ich als Key den Integer-Wert NULL (0) genommen, da ist nichts passiert, soll das der Grund gewesen sein?

Gruß
Mazel

Hawkeye219 5. Aug 2006 13:27

Re: Namen der virtuellen Tastencodes
 
Man hätte auch jede andere Taste verwenden können. Wichtig ist nur, daß eine gültige Tastenkombination entsteht, damit die Umschalttasten in der richtigen Schreibweise zurückgeliefert werden. Mit einem Buchstaben ist es besonders einfach und zudem unabhängig von der Sprache.

Gruß Hawkeye

Mazel 5. Aug 2006 17:56

Re: Namen der virtuellen Tastencodes
 
Danke für die Infos.

Es müsste doch nun auch möglich sein, das ganze rückwärts aufzuschlüsseln. Ich habe folgendes vor, hier ein Beispiel:

Wenn ich in einem Editfeld die Tasten STRG, ALT und UMSCHALT drücke und keine weitere Taste, dann soll das Editfeld wieder frei werden. Momentan ist es so das bei dem gleichzeitigen drücken dieser Tasten sie dank Hawkeye219 in dem Editfeld eingetragen werden, beim loslassen allerdings sollen alle Tastenkombinanten die nur aus STRG, ALT oder UMSCHALT bestehen wieder gelsöcht werden. Folgendes habe ich probiert aber das geht nicht richtig (in OnKeyUp):
Delphi-Quellcode:
If (ssAlt in Shift) and (ssShift in Shift) and (ssCtrl in Shift) then EditHotkey.Text:=''
Ich hatte auch dies ausprobiert aber da kommt eine Fehlermeldung "[Fehler] Form_7.pas(297): Inkompatible Typen: 'TShiftState' und 'Enumeration'":
Delphi-Quellcode:
If (Shift in [ssShift, ssCtrl, ssAlt]) then EditHotkey.Text:=''
Wie kann ich das nun lösen?

Gruß
Mazel

Mazel 5. Aug 2006 18:38

Re: Namen der virtuellen Tastencodes
 
:wall: :wall: :wall: :wall:

Ich habe so eben mitbekommen, dass es eine Komponente names Hotkey auf dem Reiter Win32 (Delphi 6) gibt, die all das macht was ich brauche. Warum habe ich das nicht früher bemerkt, dann hätten wir uns die ganze Arbeit sparen können :wink: .

Dadurch hat sich nun fast alles erledigt. Nun habe ich noch ein kleines Problem: Ich habe in einer ListView die Hotkeys stehen, die sollen nun durch diese Komponente geändert werden, was ich über TextToShortCut und ShortCutToText mache. Wenn ich auf einen Eintrag in der ListView klicke, soll der Hotkey in die Hotkey Komponente eingetragen werden, das Problem ist aber, dass er mit den falschen Hotky zurück liefert:
Delphi-Quellcode:
// beim Klick auf den Eintrag
procedure TForm7.ListViewClick(Sender: TObject);
begin
 EditAction.Text:=ListView.Selected.Caption;
 EditHotkey.HotKey:=TextToShortCut(ListView.Selected.SubItems[0]);
end;
Wenn STRG + ALT + EINFG im Eintrag steht, wird mir STRG + ALT + 0 (ZEHNERTASTATUR) zurück geliefert, wo ist mein Fehler?

Gruß
Mazel

Hawkeye219 5. Aug 2006 19:42

Re: Namen der virtuellen Tastencodes
 
Zitat:

Zitat von Mazel
Ich habe so eben mitbekommen, dass es eine Komponente names Hotkey auf dem Reiter Win32 (Delphi 6) gibt, die all das macht was ich brauche.

Nach deinem vorletzten Beitrag wollte ich dir genau diese Komponente vorschlagen, aber mit deinem letzten Beitrag bist du mir zuvorgekommen.

Zu deinem Problem: die Tastenkombinationen 'Strg+Alt+Einfg' und 'Strg+Alt+0(Zehnertastatur)' unterscheiden sich (mit NUMLOCK off) nur durch die Modifier. Du wirst diese Eigenschaft von THotkey also mit abspeichern und beim Auswählen eines Listeneintrags wieder setzen müssen. Leider werden die Modifier dadurch für nachfolgende Eingaben in THotkey erzwungen. Mit einem Löschbutton gibst du dem Anwender die Möglichkeit, das Eingabefeld komplett (inklusive Modifier) zu löschen.

Im folgenden Beispielcode wird die Eingabe in einer globalen Variablen gespeichert. Sehr wichtig ist die Reihenfolge der Anweisungen in den Routinen btnLoadHotkey und btnClearHotkey.

Delphi-Quellcode:
var
  ShortCut : TShortCut;
  Modifier : THKModifiers;

procedure TForm1.btnSaveHotkey (Sender: TObject);
begin
  ShortCut := HotKey1.HotKey;
  Modifier := HotKey1.Modifiers;
end;

procedure TForm1.btnLoadHotkey (Sender: TObject);
begin
  HotKey1.HotKey := ShortCut;
  HotKey1.Modifiers := Modifier;
end;

procedure TForm1.btnClearHotkey (Sender: TObject);
begin
  HotKey1.Modifiers := [];
  HotKey1.HotKey := 0;
end;
Gruß Hawkeye

Mazel 5. Aug 2006 19:50

Re: Namen der virtuellen Tastencodes
 
Hi,

ich weis nicht wieso ich das nicht früher bemerkt habe mit der Komponente aber nun zum Thema:

Wann muss ich nun die einzelnen Prozeduren ausführen?

Zitat:

Zitat von Hawkeye219
Mit einem Löschbutton gibst du dem Anwender die Möglichkeit, das Eingabefeld komplett (inklusive Modifier) zu löschen.

Wie meinst du das? Löschen wollte ich keinen Hotkey.

Gruß
Mazel

Hawkeye219 5. Aug 2006 20:10

Re: Namen der virtuellen Tastencodes
 
Wenn du einen vom Anwender eingegebenen Hotkey speichern möchtest, mußt du die Eigenschaften Hotkey und Modifiers von THotkey sichern. Nur durch die Kombination beider Werte wird ein Hotkey eindeutig beschrieben. Im Beispielcode passiert das in der Methode btnSaveHotkey.

Nach der Auswahl eines Eintrags in der ListView müssen die mit dem Eintrag gespeicherten Werte in das THotkey-Control zurückgeschrieben werden (Routine btnLoadHotkey). Wichtig ist hier die Reihenfolge der beiden Anweisungen.

Wenn du eine Tastenkombination wie 'Strg+Alt+Einfg' in das THotkey-Control überträgst, wirst du feststellen, daß bei allen folgenden Eingaben die Modifier 'Strg' und 'Alt' auch dann ergänzt werden, wenn der Anwender sie nicht benutzt. Damit der Anwender diese Modifier wieder löschen kann, habe ich den Löschbutton vorgeschlagen (Routine btnClearKey). Mir ist kein anderer Weg bekannt, die Eigenschaft Modifiers zurückzusetzen, um "normale" Eingabe wie "F1" wieder zu ermöglichen. Auch hier ist die Reihenfolge der beiden Anweisungen wichtig; sie unterscheidet sich von der beim Setzen eines Hotkeys.

Gruß Hawkeye

Mazel 6. Aug 2006 09:18

Re: Namen der virtuellen Tastencodes
 
Hi,

ich habe jetzt mal versucht das ganze umzusetzen, leider habe ich kein großen Erfolg:
Delphi-Quellcode:
procedure TForm7.ListViewClick(Sender: TObject);
// Klick auf das ListView
begin
  EditHotkey.HotKey:=ShortCut;
  EditHotkey.Modifiers:=Modifier;
  Edit1Action.Text:=ListView.Selected.Caption;
  EditHotkey.HotKey:=TextToShortCut(ListView.Selected.SubItems[0]);
end;

procedure TForm7.BtnOKHotkeyClick(Sender: TObject);
// das zurückschreiben in die ListView
begin
  ListView.Items[ListView.Selected.Index].SubItems[0]:=UpperCase(ShortCutToText(EditHotkey.HotKey));
  ShortCut:=EditHotkey.HotKey;
  Modifier:=EditHotkey.Modifiers;
  EditHotkey.Modifiers:=[];
  EditHotkey.HotKey:=0;
end;

procedure TForm7.FormCreate(Sender: TObject);
// beim Erzeugen der Form
begin
 ShortCut:=EditHotkey.HotKey;
 Modifier:=EditHotkey.Modifiers;
 EditHotkey.Modifiers:=[];
 EditHotkey.HotKey:=0;
end;
Ist das so wie du es gemeint hast?

Gruß
Mazel

Hawkeye219 6. Aug 2006 10:40

Re: Namen der virtuellen Tastencodes
 
Hallo Mazel,

die Variablen ShortCut und Modifier in meinem Beispielcode waren lediglich der Ersatz für deine ListView. Du wirst diese Variablen in deinem Programm nicht benötigen.

Bei der Übernahme eines Hotkeys (in der Routine BtnOKHotkeyClick) speicherst du den Text des Hotkeys in SubItems[0] ab. Die Werte von EditHotkey.HotKey und EditHotkey.Modifiers mußt du ebenfalls im Listeneintrag ablegen, damit du sie bei einem späteren Klick auf den Eintrag wieder in das THotkey-Control übertragen kannst. Den 16-Bit-Hotkey und den 8-Bit-Modifier kannst du dazu in einen 32-Bit-Wert packen und anschließend im Feld TListItem.Data ablegen:

Delphi-Quellcode:
// ListItem sei das markierte Element in der ListView
with EditHotkey do
  ListItem.Data := Pointer(MakeLong(Byte(Modifiers), Hotkey));
Nach dem Klick auf einen Listeneintrag müssen die Werte wieder extrahiert und in das THotkey-Control übertragen werden:

Delphi-Quellcode:
// ListItem sei das angeklickte Element in der ListView
with EditHotkey do
  begin
    Hotkey := HiWord(Cardinal(ListItem.Data));
    Modifiers := THKModifiers(LoByte(ListItem.Data));
  end;
Wichtig ist also, daß du für jeden Eintrag in der ListView die zugehörigen Werte für HotKey und Modifiers speicherst.

Gruß Hawkeye

Mazel 6. Aug 2006 12:58

Re: Namen der virtuellen Tastencodes
 
Hi,

danke, nun funktioniert es so wie es soll. Ich muss jetzt nur noch eine einfache Routine zum Speichern und Laden entwerfen aber wie gesagt es funktioniert. Echt super :thumb: .

Wenn ich schon früher mit der Komponente Hotkey gearbeitet hätte, würde ich jetzt hier nicht die Fragen stellen, ich bin dir sehr dankbar.

Gruß
Mazel


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