AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Thread kann Tastatur-Status nicht korrekt ändern
Thema durchsuchen
Ansicht
Themen-Optionen

Thread kann Tastatur-Status nicht korrekt ändern

Offene Frage von "maheca"
Ein Thema von maheca · begonnen am 12. Feb 2010 · letzter Beitrag vom 13. Feb 2010
Antwort Antwort
maheca

Registriert seit: 12. Feb 2010
6 Beiträge
 
Delphi 2007 Enterprise
 
#1

Thread kann Tastatur-Status nicht korrekt ändern

  Alt 12. Feb 2010, 20:25
Hallo!

Bis jetzt konnte mir die Suchen-Funktion dieses Forums alle Fragen beantworten, die ich zu Delphi hatte, doch jetzt ist leider der Punkt gekommen, an dem ich selbst fragen muss ich hoffe, mir kann jemand weiterhelfen

Ich habe eine Funktion geschrieben, welche die Lämpchen auf der Tastatur (also Num Lock, Caps Lock und Scroll Lock) ein- und ausschaltet:

Delphi-Quellcode:
//SetLED dient dazu, die Leuchtdioden auf der Tastatur anzusteuern.
//LED erhält die LED, deren Zustand geändert werden soll (1 bis 3 v.l.n.r.)
//NewStatus erhält die Information, ob die LED leuchten soll oder nicht.
procedure SetLED(LED : KeyboardLED; NewStatus : Boolean);
var
  vi : TOSVersionInfo;
  KS : TKeyboardState;
  Key : Byte;
begin
  vi.dwOSVersionInfoSize:=SizeOf(vi);
  GetKeyboardState(KS);

  case LED of
    1: Key := VK_NUMLOCK;
    2: Key := VK_CAPITAL;
    3: Key := VK_SCROLL;
  end;

  if ((KS[Key] <> 0) xor NewStatus) then
  begin
      keybd_event(Key, $45, KEYEVENTF_EXTENDEDKEY, 0);
      keybd_event(Key, $45, KEYEVENTF_EXTENDEDKEY or
        KEYEVENTF_KEYUP, 0);
  end;
end;
Das ganze funktioniert auch super, solange ich die Funktion durch z.B. Buttons aufrufe. 2x Anschalten bleibt bei Buttons auch immernoch an (soll ja auch).
Wenn ich jetzt allerdings einen Thread nutze, der dafür sorgt, dass ein Lämpchen angeschaltet bleibt, indem er es einfach jede Sekunde erneut anschaltet, ergibt sich folgendes Problem:
Das Lämpchen bleibt nicht an, sondern es blinkt... Und zwar im Sekundentakt, also arbeitet meine Funktion nun vermutlich als Umschalter statt als Anschalter.

Meine Threadprozedur sieht wie folgt aus:
Delphi-Quellcode:
procedure TDMXSignal_Connected.Execute;
begin
  while not terminated do
  begin
    SetLED(3, True);
    Sleep(1000);
  end;
end;
Beinhaltet eigentlich keine potentielle Fehlerquelle (meiner bescheidenen Meinung nach... )
Beim Debuggen zeigt sich jedoch, dass der TKeyboardState für den Thread statisch wird, das heißt bei Aufruf von SetLED durch den Thread ist der KeyboardState für die jeweilige Taste immer 0.

WARUM

Ich bin ratlos und wäre echt dankbar, wenn mir jemand helfen könnte
Danke dafür im Voraus und schönes Wochenende!!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

Re: Thread kann Tastatur-Status nicht korrekt ändern

  Alt 12. Feb 2010, 20:54
Du weißt aber, daß du damit nicht direkt die LEDs steuerst, sondern die zugehörigen Tasten?
Sowas macht sich etwas "bescheuert", wenn man mit dem PC arbeiten will und wärend der Eingabe spielt ständig jemand (dein Programm) an der Tastatur rum.

Wenn GetKeyboardState das falsche Ergebnis liefert, dann wäre es besser (sowas ist allgemein keine schlechte Idee, auch wenn es ginge) den Rückgabewert dieser API zu prüfen und im Fehlerfall via GetLastError zu schauen was da schief läuft.

PS:

Es gab hier schon ein paar Themen, wo wirklich die LEDs gesteuert werden und nicht die Tasten.
z.B.: Hier im Forum suchenkeyboardled

Und wozu eigentlich ein Thread?
Dieses Intervall ließe sich doch auch sehr gut über einen einfachen Timer realisieren.
$2B or not $2B
  Mit Zitat antworten Zitat
maheca

Registriert seit: 12. Feb 2010
6 Beiträge
 
Delphi 2007 Enterprise
 
#3

Re: Thread kann Tastatur-Status nicht korrekt ändern

  Alt 13. Feb 2010, 14:05
Erst einmal danke für die Antwort

Dass ich damit tatsächlich die Tasten steuere und nicht nur die Lämpchen ist mir bewusst, aber da ich nur die Scroll-Lock-"Lampe" verwende sollte das nicht allzu kritisch sein...

Der Thread soll hinterher in wesentlich kleineren Intervallen arbeiten und die Verbindung mit einem USB-Gerät sicherstellen, der Status dieser Verbindung wird dann über das Lämpchen angezeigt.

Nur das Lämpchen zu steuern, wie es bei keyboardled der Fall ist, wäre natürlich eine noch wesentlich schönere Lösung, allerdings handelt es sich bei dem Gesamtprojekt um eine besondere Lernleistung im Rahmen meines Abiturs... Das heißt, Closed-Source-Rückgriffe sollten wenn möglich vermieden werden, da ich den Code und die Vorgänge im Programm im Zweifelsfall erklären können muss.

Das mit GetLastError habe ich nicht so richtig verstanden... Es entsteht ja gar kein Fehler, also was genau sollte ich da abrufen?

Bin natürlich für jede weitere Antwort dankbar
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

Re: Thread kann Tastatur-Status nicht korrekt ändern

  Alt 13. Feb 2010, 14:16
Zitat von maheca:
Das mit GetLastError habe ich nicht so richtig verstanden... Es entsteht ja gar kein Fehler, also was genau sollte ich da abrufen?
Der "Fehler" ist erstmal, daß GetKeyboardState nicht das von dir gewünschte Ergebnis liefert.

Also schaut man, ob GetKeyboardState überhaupt richtig arbeitet.
Die WinAPI erzeugt nur selten eine spürbare Exception, sondern gibt ihre Fehler z.B. über das Funktionsergebnis (Result) zurück, manchmal auch noch in Verbindung mit GetLastError.

Demnach sollte man auch dieses prüfen:
http://msdn.microsoft.com/en-us/library/ms646299.aspx
Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.


Du rennst doch auch nicht durch eine Tür, knallst dagegen und beschwerst dich dann lautstark, weil du dagegengerannt bist und das OHNE zu prüfen ob nicht vielleicht abgeschlossen ist.


Wenn die Funktion dennoch keinen Fehler meldet, dann prüft man, ob diese Funktion überhaupt das tut/kann, was man möchte.

Eventuell hilft aber auch schon Dieses:
http://www.vbarchiv.net/tipps/tipp_5...sschalten.html
$2B or not $2B
  Mit Zitat antworten Zitat
maheca

Registriert seit: 12. Feb 2010
6 Beiträge
 
Delphi 2007 Enterprise
 
#5

Re: Thread kann Tastatur-Status nicht korrekt ändern

  Alt 13. Feb 2010, 14:59
Also:

GetKeyboardState liefert bei meinem Funktionsaufruf niemals 0 zurück, erzeugt demnach auch keinen Fehler, welchen ich mit GetLastError hätte abfragen können (habs trotzdem versucht, aber logischer weise halt nichts bekommen)...

Der Tipp aus dem VBArchiv sieht ziemlich ähnlich aus wie das, was ich bereits in SetLED geschrieben habe.

Und die Funktion SetLED lässt sich wie gesagt mithilfe von Buttons zum Ein- und Ausschalten vollkommen fehlerfrei ansprechen:

Delphi-Quellcode:
procedure TForm_Debug.Btn_LEDOnClick(Sender: TObject);
begin
  SetLED(3, True);
end;
Delphi-Quellcode:
procedure TForm_Debug.Btn_LEDOffClick(Sender: TObject);
begin
  SetLED(3, False);
end;
Auch mehrmaliges Klicken auf den On-Button führt nicht zu dem Blinkeffekt, welcher beim Thread auftritt... (Mehrmaliges drücken von Off blinkt ebenfalls nicht, sondern bleibt halt einfach aus)

Ich bin leider ratlos
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:10 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