Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - HotKey in selbst entwickelter Komponente verwenden?


galagher - Fr 04.11.11 21:47
Titel: HotKey in selbst entwickelter Komponente verwenden?
Hallo!

Ich habe eine Komponente TCheckBoxPlus und möchte da gerne Shortcut verwenden, klappt aber nicht. Habe ich in Prozedur KeyDown etwas vergessen?


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:
protected
//..
  procedure KeyDown(var Key: Word; Shift: TShiftState); override;
//..
published
//..
  property OnKeyDown;
//..

//Was fehlt denn hier in KeyDown?
procedure TCheckBoxPlus.KeyDown(var Key: Word; Shift: TShiftState);
begin
  if not fEnabled then exit;

  if fFocus then
    if Shift = [] then
      if Key = 32 then
        begin
          fMouseState := msMouseDown;
          if fState <> cbGrayed then
          begin
            SetFocus;
            fFocus := True;
            Invalidate;
          end;
        end;
  inherited KeyDown(Key, Shift);
end;


bummi - Fr 04.11.11 23:02

meinst Du mit Shortcut einen Hotkey?
also eine Tastenkombination die in der Anwendung Diener Komponente zugeordnet ist, dann kommst Du mit Deinem Ansatz nicht weiter.

Schau mal da : http://www.swissdelphicenter.ch/de/showcode.php?id=2375


galagher - Sa 05.11.11 10:12

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
meinst Du mit Shortcut einen Hotkey?
also eine Tastenkombination die in der Anwendung Diener Komponente zugeordnet ist, dann kommst Du mit Deinem Ansatz nicht weiter.

Schau mal da : http://www.swissdelphicenter.ch/de/showcode.php?id=2375

Ja, HotKey ist wohl die richtige Bezeichnung. Wenn also die Caption Klick mich an ist, soll man mit der Tastenkombination Alt+k die Komponente erreichen, wie das bei der Standard-Komponente TCheckBox ja auch der Fall ist.

Habe den Code im Link ausprobiert, aber wo soll ich den Hotkey registrieren? Im Constructor Create geht's nicht, das führt zu einem Fehler (Exception war es, denke ich).

Muss doch einfacher gehen?


bummi - Sa 05.11.11 10:58

SetParent überschreiben..., wie sinnvoll das ganze ist wenn mehrere Komponenten erzeugt werden ??

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:
procedure TMyEdit.SetParent(AParent: TWinControl);
const
  VK_R = $52;
begin
  inherited;
  if not (csDesigning in ComponentState) then
    begin
      if (FID1>0and not Assigned(AParent) then
        begin
          UnRegisterHotKey(FTheHandle, Fid1);
          GlobalDeleteAtom(Fid1);
          FID1 := 0;
        end
      else
        begin
              if FID1=0 then FID1 := GlobalAddAtom('Hotkey1');
              RegisterHotKey(Handle, Fid1, MOD_CONTROL, VK_R);
              FTheHandle := Handle;
        end;
    end;
end;
procedure TMyEdit.WMHotKey(var Msg: TWMHotKey);
begin
  if Msg.HotKey = Fid1 then
    ShowMessage('Ctrl + R pressed !');
end;


galagher - Sa 05.11.11 11:38

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
SetParent überschreiben..., wie sinnvoll das ganze ist wenn mehrere Komponenten erzeugt werden ??

Habe deinen Code (hoffentlich richtig) implementiert, aber da tut sich nix, auch nicht, wenn die Kompo den Focus hat.

Wie machen die anderen Komponenten das? :nixweiss: Ich konnte weder in den .pas-Files der Standard-Komponenten noch in anderen Komponenten, zB. TIAEverButton - da klappt der HotKey - etwas finden. Das gibt's nichts, was man als "Code für HotKeys" deuten könnte...
Bisher brauchte ich das ja nicht, und dachte nie darüber nach. Naja, und jetzt habe ich eine funktionierende Kompo mit Caption, die auch den Hotkey korrekt darstellt (= unterstrichen), aber man kann sie nicht per Tastatur steuern. Eine halbe Sache eben...

//Edit: Habe den Thread-Titel auf "HotKey in selbst entwickelter Komponente verwenden?" geändert.


bummi - Sa 05.11.11 11:56

Der Focus sollte nicht nötig sein, ich hab mal mein Testprojekt anghängt, bei mir tut es ... ist mit Sicherheit noch verbesserungswürdig.


galagher - Sa 05.11.11 12:52

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Der Focus sollte nicht nötig sein, ich hab mal mein Testprojekt anghängt, bei mir tut es ... ist mit Sicherheit noch verbesserungswürdig.

Hm, $51 ist Q, $52 ist R, $53 = S, dann gilt ja: $37 ist C, aber das klappt weder in deinem noch in meinem Programm.
Ausserdem ist das ja ein fixer HotKey (ok, man kann ja in Prozedur SetCaption rausbekommen, vor welchem Zeichen ein & steht und das dann umrechnen, um es als Hotkey zu erkennen).
Um die Alt-Taste zu verwenden, einfach RegisterHotKey(Handle, Fid1, MOD_ALT, VK_R); angeben - klappt.

Was hat es mit $52 auf sich? Wie kann man einfach herausbekommen, welche Taste der HotKey ist:
Pseudocode:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
//Vor irgendeinem Zeichen in Caption könnte & stehen, das nachfolgende Zeichen ist dann der Hotkey.
//Statt der Konstante VK_R nehmen wir hier VK_HotKey
for i := 1 to Length(fCaption) do
begin
  if (fCaption[i+1] = (65..90))  and (fCaption[i] = '&'then VK_HotKey = //Buchstabe A-Z  
  if (fCaption[i+1] = (97..122)) and (fCaption[i] = '&'then VK_HotKey = //Buchstabe a-z
  //hier das gleiche nochmal mit Zahlen 0 - 9
end;

Naja, so halt irgendwie...

Meine Frage also, was hat es mit $52 auf sich? Kann man das verallgemeinern, vereinfachen?
Und: Wie machen die Standard-Komponenten das?


bummi - Sa 05.11.11 13:33

Du kannst mal in die Windows.pas schauen

Delphi-Quelltext
1:
2:
{ VK_0 thru VK_9 are the same as ASCII '0' thru '9' ($30 - $39) }
{ VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' ($41 - $5A) }


in Menus.pas findest Du Code zum extrahieren von Shortkeys...


galagher - Sa 05.11.11 14:19

Man kann das auch mit dem HexEditor von mael http://www.delphi-forum.de/viewtopic.php?t=36173&highlight=hexeditor+hxd herausfinden. Das verstehe ich also jetzt.
Wenn ich es anwende, funktioniert es zwar prinzipiell (das Programm spricht darauf an), aber es kommt die Fehlermeldung:
'' ist kein gültiger Integerwert.

Es ist wohl einfacher, ich fange den HotKey per Form1 KeyPreview ab. Das löst zwar das Problem nicht, dass die Komponente die Tastenkombination nicht selbst erkennt, wird aber dafür funktionieren.


galagher - Di 08.11.11 20:56

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
SetParent überschreiben..., wie sinnvoll das ganze ist wenn mehrere Komponenten erzeugt werden ??
Es funktioniert prinzipiell, aber bei mehreren Komponenten in einem Projekt wirkt es sich nur auf die letzte Komponente aus, wohl abhängig von der Erstellungsreihenfolge.

Ich weiss aber immer noch nicht, wie das bei anderen, nicht nur bei den Standard-Komponenten funktioniert? :nixweiss: