| Autor |
Beitrag |
MasterrudE
Hält's aus hier
Beiträge: 4
|
Verfasst: Di 10.08.10 22:33
Hallo zusammen,
ich versuche gerade, ein Beispiel aus dem "Delphi 7 Kochbuch" umzuändern, um eine Tastenkombination abzufangen, das Programm lässt sich auch problemlos kompilieren und wird im Taskamanger aufgeführt, allerdings mag es nicht auf meine Tastenkombination reagieren...
Hier ist mal der Code, ich versuche, die Tastenkombination Strg + Shift abzufangen:
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:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;
type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); protected procedure HotKey(var msg: TMessage); message WM_HOTKEY; private id: Integer; public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.hotkey(var msg: TMessage); begin if (msg.WParam = VK_SHIFT) and (msg.LParam = VK_Control) then begin self.Visible := not self.Visible; if self.Visible then self.WindowState := wsNormal else self.WindowState := wsMinimized; end; end;
procedure TForm1.FormCreate(Sender: TObject); begin id := GlobalAddAtom('Hotkey1'); RegisterHotKey(handle, id, VK_SHIFT, VK_CONTROL); end;
end. |
Hat jemand einen Tipp, was ich falsch mache? Leider sind meine Kenntnisse bis jetzt noch ziemlich begrenzt, ich hab erst ein paar Sachen für den Eigenbedarf programmiert.
Herzlichen Dank schonmal im voraus für die Hilfe!
Grüße André
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Di 10.08.10 22:45
Hallo und  im DF!
Du willst als Hotkey nur Strg + Shift haben? Ob das geht ist fraglich. Aber probier mal statt dem VK_Shift MOD_SHIFT zu schreiben. Und aber dann auch in deiner HotkeyProcedure dann auch wirklich LParamLo und LParamHi zu verwenden.
lg elundril
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
MasterrudE 
Hält's aus hier
Beiträge: 4
|
Verfasst: Di 10.08.10 23:11
Hallo elundril,
Vielen Dank für die schnelle Antwort!
habe jetzt bei dem oberen Kommentar geschrieben
Delphi-Quelltext 1:
| if (msg.LParamHi = MOD_SHIFT) and (msg.LParam = VK_Control) then |
und bei dem unteren Kommentar:
Delphi-Quelltext 1:
| RegisterHotKey(handle, id, MOD_SHIFT, VK_CONTROL); |
Hattest du das so gemeint? Wenn ja, es funktioniert leider nicht...
Hast Du noch eine andere Idee? Kann ich auch mit GetAsyncKeyState (heißt die function so?) global den Status von Tasten abfragen? Ich bekomme ja dann keine WM_HOTKEY Nachricht.
Grüße
André
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Di 10.08.10 23:26
ne, eigentlich meinte ich sowas:
Delphi-Quelltext 1:
| if (msg.LParamLo = MOD_SHIFT) and (msg.LParamHi = VK_Control) then |
Grund ist der das anscheinend die niederen Bits (LParamLo) die ganzen Zusatztasten wie Shift, Alt und Strg kodieren und die hohen Bits (LParamHi) die eigentliche Taste die gedrückt wurde. (In deinem Beispiel war es die Taste mit dem VK-Code 83, was der Power-Knopf wäre soweit ich das richtig aus der VK-Codes-Tabelle rauslese)
Mit GetAsyncKeyState könnte es funktionieren, das musst du dann aber in ne Schleife, Timer oder sonswas packen um registieren zu können wann die Tastenkombination gedrückt wurde. Außerdem glaub ich nicht das man dann auch nur shift und strg verwenden kann, sondern man auch ne richtige taste braucht.
lg elundril
//Edit: Weiters könntest du auch nachsehen was RegisterHotKey zurück gibt.  Sollte nämlich True zurückgeben wenn du alles richtig gemacht hast. 
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
MasterrudE 
Hält's aus hier
Beiträge: 4
|
Verfasst: Di 10.08.10 23:38
Hallo mal wieder...
Schon wieder Danke für die schnelle Hilfe!
Leider hats auch dieses Mal nicht funktioniert. Ich hab es mehrmals in den folgenden Kombinationen versucht:
-nur die erste Zeile geändert
-beide Zeilen auf MOD_*** geändert
-Die MOD_*** Parameter wieder zusammengeschrieben als "MOD_SHIFT + MOD_CONTROL" im 3. Parameter in der zweiten Zeile
-Sowohl MOD_SHIFT und MOD_CONTROL als auch gleichzeitig VK_CONTROL abgefragt
Das Programm kompiliert in allen Versionen problemlos, allerdings reagiert es nicht auf die Tastenkombination.
Das mit der Ausgabe ist ne gute Idee, werd ich mal probieren.
Die Taste "83" ist das "S", in der Original-Version reagiert das Programm also auf Strg + Shift + S.
Wenn alle diese Funktionen nur auf "echte" Tastenkombinationen ansprechen, wie könnte man dann sowas noch anders realisieren?
Grüße
André
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Di 10.08.10 23:49
Probier mal folgendes:
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:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;
type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); protected procedure HotKey(var msg: TWMHotKey); message WM_HOTKEY; private id: Integer; public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.hotkey(var msg: TWMHotKey); begin if msg.HotKey = id then begin self.Visible := not self.Visible; if self.Visible then self.WindowState := wsNormal else self.WindowState := wsMinimized; end; end;
procedure TForm1.FormCreate(Sender: TObject); begin id := GlobalAddAtom('Hotkey1'); if not RegisterHotKey(handle, id, MOD_SHIFT, VK_CONTROL) then Showmessage(SysErrorMessage(GetLastError)); end;
end. |
Bin mir aber nicht sicher ob das geht. Kann durchaus sein das man zwingend einen Buchstaben braucht.
Alternative wäre eben ein GetAsyncKeyState oder ein Keyboard-Hook. Oder halt wenn du uns verratest was du vor hast, vielleicht noch was anderes.
lg elundril
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
MasterrudE 
Hält's aus hier
Beiträge: 4
|
Verfasst: Mi 11.08.10 00:03
So...
Hab jetzt mal ein Memo zum Formular hinzugefügt und verschiedene Kombinationen ausprobiert:
1.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure TForm1.hotkey(var msg: TMessage); begin if (msg.WParam = VK_SHIFT) and (msg.LParam = VK_Control) then begin self.Visible := not self.Visible; if self.Visible then self.WindowState := wsNormal else self.WindowState := wsMinimized; end; end;
procedure TForm1.FormCreate(Sender: TObject); begin id := GlobalAddAtom('Hotkey1'); if (RegisterHotKey(handle, id, VK_SHIFT, VK_CONTROL)) then Memo1.Lines.Add('RegisterHotKey = TRUE') else Memo1.Lines.Add('RegisterHotKey = FALSE, Action failed!'); end; |
Ergebnis: RegisterHotKey = FALSE
2.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure TForm1.hotkey(var msg: TMessage); begin if (msg.LParamLo = MOD_SHIFT + MOD_CONTROL) then begin self.Visible := not self.Visible; if self.Visible then self.WindowState := wsNormal else self.WindowState := wsMinimized; end; end;
procedure TForm1.FormCreate(Sender: TObject); begin id := GlobalAddAtom('Hotkey1'); if (RegisterHotKey(handle, id, MOD_SHIFT + MOD_CONTROL, 0)) then Memo1.Lines.Add('RegisterHotKey = TRUE') else Memo1.Lines.Add('RegisterHotKey = FALSE, Action failed!'); end; |
Ergebnis: RegisterHotKey = TRUE
3.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure TForm1.hotkey(var msg: TMessage); begin if (msg.LParamLo = MOD_SHIFT + MOD_CONTROL) and (msg.LParamHi = VK_SHIFT)then begin self.Visible := not self.Visible; if self.Visible then self.WindowState := wsNormal else self.WindowState := wsMinimized; end; end;
procedure TForm1.FormCreate(Sender: TObject); begin id := GlobalAddAtom('Hotkey1'); if (RegisterHotKey(handle, id, MOD_SHIFT + MOD_CONTROL, VK_SHIFT)) then Memo1.Lines.Add('RegisterHotKey = TRUE') else Memo1.Lines.Add('RegisterHotKey = FALSE, Action failed!'); end; |
Ergebnis: Funktioniert!!!
Allerdings nur, wenn man erst Strg und dann Shift drückt, setzt man VK_CONTROL ein, ist es dementsprechend andersrum. Werd noch ein bißchen dran rumbasteln, damit es in beiden Richtungen funktioniert.
Erstmal herzlichen Dank!
Grüße
André
EDIT: Hab gerade erst Deine letzte Antwort gelesen, weil ich parallel zum posten hier noch mit Delphi gespielt hatte. Wie gesagt, der Großteil des Codes stammte aus dem Kochbuch, über Optimierungen hatte ich noch gar nicht nachgedacht. danke für den Tip!
EDIT2: Ganz vergessen... Was ich vorhabe? Ich versuche mich daran, ein Plugin für VirtuaWin zu schreiben, dass ähnlich wie VWPreview funktionieren soll. Mal sehen, ob es was wird. Ich arbeite jetzt seit ein paar Wochen an verschiedenen Vorübungen und will sie dann hinterher zu einem Plugin zusammenfügen.
|
|
|