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 Strg-Taste per Button einrasten! (https://www.delphipraxis.net/31307-strg-taste-per-button-einrasten.html)

valon 7. Okt 2004 08:08


Strg-Taste per Button einrasten!
 
Hallo Leute!
Brauche eure Hilfe!

Wenn ich in einer ListBox das Property MultiSelect auf true setze, dann hab ich die Möglichkeit mehrere Einträge zu selektieren.
Dabei muss ich aber die "Strg" Taste gedrückt halten.
Wie kann ich einfach per Button die Strg-Taste einrasten um dann zu selektieren.und wenn ich nicht mehr selectieren will die Strg-taste wieder per Button lösen.

Ich sollte nähmlich auf ein Touchscreen die Möglichkeit haben zu selektieren.und da hab ich ja keine Strg-Taste.
Danke

Steve 7. Okt 2004 08:53

Re: Strg-Taste per Button einrasten!
 
Ein Beispiel für das "Einrasten" via CheckBox, Button etc läuft analog.
Beim Einrasten wird ein Befehl gesendet, dass Ctrl gedrückt wird, beim "Ausrasten" wird ein Befehl gesendet, dass die Taste losgelassen wird.

Delphi-Quellcode:
IF cbCtrl.Checked THEN
  Keybd_Event(VK_CONTROL,0,0,0)
ELSE
  Keybd_Event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
Das funzt natürlich nur, solange zwischendrin keiner an der "echten" Ctrl-Taste rumfummelt :)
Schau Dir halt am besten mal das Kapitel [oh]"Keyboard Input"[/oh] an ;)

Gruß
Stephan :dance:

himitsu 7. Okt 2004 09:03

Re: Strg-Taste per Button einrasten!
 
Ich hätte zwar erst gedacht dass, wenn man die Strg-Taste mitten innerhalb von onMouseDown drücken läßt, es dann zu spät wäre, weil ja das Mausereignis schon begonnen und eigentlich TShiftState (also auch Strg) schon ausgelesen wurde, aber es geht :gruebel:

Delphi-Quellcode:
Procedure TForm1.ListBox1MouseDown ...
  Begin
    If cbCtrl.Checked Then Keybd_Event(VK_CONTROL, 0, 0, 0);
  End;

Procedure TForm1.ListBox1MouseUp ...
  Begin
    If cbCtrl.Checked Then Keybd_Event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
  End;

Steve 7. Okt 2004 09:06

Re: Strg-Taste per Button einrasten!
 
Ja, das erst während MouseUp/Down zu setzen ist die bessere Lösung.. Sonst bleibt Strg eingerastet, wenn man vergisst, das Häkchen wieder zu entfernen :wall: Das kann böse Folgen haben :mrgreen:

Gruß
Stephan :dance:

Stevie 7. Okt 2004 09:19

Re: Strg-Taste per Button einrasten!
 
Zitat:

Zitat von himitsu
Ich hätte zwar erst gedacht dass, wenn man die Strg-Taste mitten innerhalb von onMouseDown drücken läßt, es dann zu spät wäre, weil ja das Mausereignis schon begonnen und eigentlich TShiftState (also auch Strg) schon ausgelesen wurde, aber es geht :gruebel:

Wie bitte??? Das funktioniert doch überhaupt nicht! Zumindest bei mir (Delphi 6 Pro).
Kann auch überhaupt nicht, weil die Prozedur TCustomListBox.WMLButtonDown vor OnButtonDown ausgelöst wird, und dort der ShiftState überprüft wird!

himitsu 7. Okt 2004 09:49

Re: Strg-Taste per Button einrasten!
 
hatte ich ja auch gedacht, aber komisch ... vorhin ging es noch, als ich es so hatte:
Delphi-Quellcode:
Procedure TForm1.ListBox1MouseDown ...
  Begin
    Keybd_Event(VK_CONTROL, 0, 0, 0);
  End;

Procedure TForm1.ListBox1MouseUp ...
  Begin
    Keybd_Event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
  End;
Hab's jetzt noch 4, 5-mal versucht und jetzt wills nichtmehr gehn :gruebel:

Na ja, man könnte es ja auch mal vorm Klickereignis machen und dann über'nen Timer wieder abschalten, da es ja kein onMouseLeave bei der Listbox gibt:
Delphi-Quellcode:
  Procedure TForm1.ListBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    Begin
      If CheckBox1.Checked Then Begin
        Keybd_Event(VK_CONTROL, 0, 0, 0);
        ListBox1.Tag := 1;
      End;
    End;

  Procedure TForm1.Timer1Timer(Sender: TObject);
    {ein Interval von 10 bis 10 ms reicht voll aus}
    Var P: TPoint;

    Begin
      P := ListBox1.ScreenToClient(Mouse.CursorPos);
      If CheckBox1.Checked and (ListBox1.Tag <> 0) and
        ((P.X < 0) or (P.Y < 0) or (P.X >= ListBox1.Width) or (P.Y >= ListBox1.Height)) Then Begin
        Keybd_Event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
        ListBox1.Tag := 0;
      End;
    End;
mehrfach getestet ^^
Klar, wenn man die Maus nicht bewegt und zwischendurch mal auf 'ne Taste drückt, dann wird gibt es auf diese Weise Probleme -.-''

Die ander Möglichkeit mit 'nem Timer wäre dann
Delphi-Quellcode:
  Procedure TForm1.Timer1Timer(Sender: TObject);
    {ein Interval von 10 bis 10 ms reicht voll aus}
    Var P: TPoint;

    Begin
      If CheckBox1.Checked Then Begin
        P := ListBox1.ScreenToClient(Mouse.CursorPos);
        If (P.X >= 0) and (P.Y >= 0) and (P.X < ListBox1.Width) and (P.Y < ListBox1.Height) Then
          Keybd_Event(VK_CONTROL, 0, 0, 0)
        Else
          Keybd_Event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
      End;
    End;

  Procedure TForm1.CheckBox1Click(Sender: TObject);
    Begin
      If not CheckBox1.Checked Then Keybd_Event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
    End;
Dort ist dann das Problem mit dem Drücken einer Taste nicht mehr so groß.

Oder über 'nen Maus-Hook, da sollte es auch möglich sein.


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