Ich suche eine Möglichkeit, um festzustellen, ob eine (beliebige) Taste
gedrückt ist.
Access ist mit Funktionen wie KeyDown/KeyUp bestückt, die aber leider
nicht zuverlässig sind - der KeyUp-Event wird zuweilen verschluckt.
Nämlich dann, wenn man bei gedrückt gehaltener Taste aus Access in eine
andere anwendung wechselt. Wenn man dort dann die Taste loslässt, kann
Access das natürlich nicht registrieren, und im Access gilt die Taste
weiterhin als "gedrückt gehalten"
Daher suche ich eine API, die feststellen kann, ob immer noch ein
Tastendruck vorliegt. Welche Taste gerade gedrückt wird, ist egal. Ich
kenne nur APIs, die eine bestimmte Taste prüfen können. Es ist natürlich
unsinnig, jede einzelne Taste abzufragen, ob sie noch gedrückt ist. Eine
"KeyPressed Funktion" hatte mein Homecomputer in früheren Zeiten schon.
Die lieferte TRUE, wenn "irgendeine Taste" gedrückt war. Und das gibts
in der Access/VBA/API Welt nicht mehr ??
Jypama schrieb:> Eine> "KeyPressed Funktion" hatte mein Homecomputer in früheren Zeiten schon.
Auf dem liefen aber auch nicht viele Programme gleichzeitig.
Was wäre dir denn lieber: nur das Programm, das den Tastatur-Fokus hat,
erfährt ob eine Taste gedrückt oder losgelassen wird, das ist die
normale Windows-Version.
Oder alle laufenden Programme reagieren auf jeden Tastendruck. Muss ich
wirklich erklären, dass das unsinnig ist?
Jypama schrieb:> wenn man bei gedrückt gehaltener Taste aus Access in eine> andere anwendung wechselt. Wenn man dort dann die Taste loslässt, kann> Access das natürlich nicht registrieren
Genau, das ist ja auch die einzig brauchbare Alternative.
Georg
Georg schrieb:> Genau, das ist ja auch die einzig brauchbare Alternative.
Nein, das ist völliger Quatsch, weil es in dem beschriebenen Fall zu
keiner Lösung führt.
Heinz B. schrieb:> https://activevb.de/tutorials/tut_keylogger/keylogger.html
Ja, sowas in der Richtung. Die APIs GetKeyState und GetAsyncKeyState
verwende ich anderweitig bereits. Leider muss man bei beiden Funktionen
wissen, WELCHE Taste man abfragen will. Die Frage, on eine beliebige
Taste gedrückt ist, lässt sich damit nicht bzw. nur sehr umständlich
lösen, z.B. indem man ALLE Tasten der Reihe nach abfragt.
Weiß keiner eine Lösung für das Problem?
Ist, wie ich oben schon sagte, am einfachsten mit einem
Tastaturhook. Für mein XProfan gibt es sowas :
https://xprofan.net/intl/de/dlls/keyboardhook-dll/
Ob man sowas für Access verwenden kann, weiß ich nicht.
Man braucht auf jeden Fall das Instanzhandle vom laufenden
Access und auch das Fensterhandle, damit die DLL weiß, wohin
sie die Message schicken soll. Der Tastenwert steht dann in
wParam (siehe auch SendMessage, wparam, lparam).
Da Access keine UserMessages bereitstellt, müßte man das
Access eigene Fenster subclassen (wm_command usw.), um
diese spezielle Message (4444) herauszufischen und wparam
auszulesen.
Schau auch mal bei der API RegisterWindowMessageA zum
Registrieren einer solchen Message.
Ist, wie gesagt nicht ganz einfach und ob Access das mit
denke mal mit VBA das kann ? Die Messageverwaltung muß
man dann selber übernehmen (GetWindowProc und SetWindowProc),
indem man die Windowproc überschreibt bzw. erweitert.
Da müßtest du dich mal in dieser Richtung schlau machen.
Nachtrag :
Was das Instanzhandle und Fensterhandle betrifft, sind die Funktionen
~GetWindowLong(%hWnd, ~GWL_HINSTANCE)
~FindWindow(lpClassName, lpWindowName)
die Anlaufstellen.
Jypama schrieb:> Daher suche ich eine API, die feststellen kann, ob immer noch ein> Tastendruck vorliegt. Welche Taste gerade gedrückt wird, ist egal. Ich> kenne nur APIs, die eine bestimmte Taste prüfen können.
GetKeyboardState() aus winuser tut, was du glaubst zu brauchen. Naja,
zumindest mit ein wenig obertrivialer Nacharbeit.
Wirklich brauchen tut man das aber eigentlich nie, nur dann, wenn man
schon ringsrum Scheiße programmiert hat, glaubt man sowas zu brauchen...
Jypama schrieb:> Nämlich dann, wenn man bei gedrückt gehaltener Taste aus Access in eine> andere anwendung wechselt. Wenn man dort dann die Taste loslässt, kann> Access das natürlich nicht registrieren, und im Access gilt die Taste> weiterhin als "gedrückt gehalten"
Dann betrachte es einfach als "Taste nicht mehr gedrückt", wenn das
Access den Focus verliert (weil jetzt ein anderes Programm den Focus
hat), bzw. mache die Aktionen rückgängig, die bei Key_down gemacht
wurden (falls das relevant sein sollte)
c-hater schrieb:> Wirklich brauchen tut man das aber eigentlich nie, nur dann, wenn man> schon ringsrum Scheiße programmiert hat, glaubt man sowas zu brauchen...
Ja, so denke ich auch ...
Jens G. schrieb:> Ja, so denke ich auch ...
Die Idee, dass eine Anwendung, die nicht den Focus hat, Tasten auswerten
soll, ist von vornherein völlig irre.
Eine Taste gedrückt zu halten, während man das laufende Programm
wechselt kann auch nur einem kranken Gehirn entspringen.
Irgendwann fährt man dann mit solchen Ideen gegen eine Wand.
Georg
c-hater schrieb:> Wirklich brauchen tut man das aber eigentlich nie, nur dann, wenn man> schon ringsrum Scheiße programmiert hat, glaubt man sowas zu brauchen...
Schon klar. Ich weiß bescheid :-)
Georg schrieb:> Eine Taste gedrückt zu halten, während man das laufende Programm> wechselt kann auch nur einem kranken Gehirn entspringen.
Du weißt auch, was man wissen muss. Aber keinen Fitzel mehr gell ;-)
Gut Georg, ich erklär halt, wofür ich das will. Wenn die Shift-Taste
gehalten wird, soll sich beim Klick auf einen Button der Explorer
öffnen. Der Text des Button soll rot sein, solange die Shift-Taste
gedrückt ist. Funktioniert ja alles, der Explorer öffnet sich. Nur den
roten Text setzt Access nicht zurück, weil das Loslassen der Shift-Taste
im Explorer geschieht, und Access daher keinen Key-Up-Event mehr
auslösen kann. Na gut, wenn das einem kranken Hirn entsprungen sein
soll, dann ist es halt so.
Ich habe das mit einem Timer gefixt. Der prüft halt, ob die Shift-Taste
noch gedrückt ist und holt dann den Key-Up-Event "von Hand" nach. Ich
dachte, es wäre nett, wenn man eine allgemeine Funktion hätte, die nicht
nur auf eine bestimmte Taste prüft, hier die Shift-Taste. Aber so
wichtig ist das nun auch nicht.
Ich danke für die Hilfe, sind ja ein paar gute Anregungen gekommen :-)
Jypama schrieb:> Nur den> roten Text setzt Access nicht zurück, weil das Loslassen der Shift-Taste> im Explorer geschieht, und Access daher keinen Key-Up-Event mehr> auslösen kann.
Wenn du ein KEY-Ereignis auslöst, startet du eine Sub-Routine wie jede
andere auch. Am Ende der Sub-Routine wird die Taste automatisch
losgelassen.
ABER. WO löst du das KEY-Ereignis aus. ??
In einen Eingabe-Feld oder in der Form. Es gibt das übergeordnete
KEY-Ereignis der Form. Wenn das aktiviert ist, wird es VOR jeden anderen
KEY-Ereignis ausgelöst.
So viel dazu.
Was den Rest angeht kann man auch tricksen.
Man legt eine globale Variable an, Status Boolean. Wenn das KEY-Ereignis
ausgelöst wird ändert man den Status. Fertig ist.
Ob der Mist in VBA funktioniert weiß ich nicht.
In VB mache ich ähnliches dauernd. Ach und wenn man etwas auslösen will
reicht auch ein .performclick . Finde ich schöner als die Ereignis-sub
aufzurufen. ;)
Meine Frage wurde ja beantwortet. Nochmals vielen Dank :-)
Ich lese aber trotzdem noch. Kommen ja immer mal interessante Tipps.
z.B. das hier :-D
Schlaumaier schrieb:> Wenn du ein KEY-Ereignis auslöst, startet du eine Sub-Routine wie jede> andere auch. Am Ende der Sub-Routine wird die Taste automatisch> losgelassen.
Ich weiß gerade nicht, welche Tastatur eine Taste automatisch loslässt,
wenn sie nicht mehr gebraucht wird? Bitte mehr Info, so eine Tastatur
will ich auch :-)
Schlaumaier schrieb:> Ob der Mist in VBA funktioniert weiß ich nicht.
VBA gilt als Kinderkram. Meiner Ansicht nach ist das ungerechtfertigt,
denn VBA kann eine ganze Menge. Mit APIs gibts eigentlich keine
unlösbaren Aufgaben. Und JA, es funktioniert mit der Variablen. Tue ich
ja auch. Was aber, wenn der Event ausbleibt, der die Variable
zurücksetzt? Darum ging es mir.
Jypama schrieb:> Ich weiß gerade nicht, welche Tastatur eine Taste automatisch loslässt,> wenn sie nicht mehr gebraucht wird? Bitte mehr Info, so eine Tastatur> will ich auch :-)
gar keine.
Ich meinte das das Ereignis mehrfach ausgelöst wird. Der
Tastatur-Prozessor senden die Information das die Taste drückt und
GEHALTEN wird, mehrfach als Gedrückt. Diese Eigenschaft kann man unter
Windows sogar einstellen.
JEDES Ereignis löst das Key_* Ereignis aus.
Was mir gerade einfällt und ich testen würde ist. Wenn du das
key_down_Ereignis auslöst und dann via shell die App anhältst würde sie
vielleicht das KEY_UP ereignis auslösen wenn sie weiter läuft. Ist aber
nur Theorie. Kein Bock zu Testen.
Jypama schrieb:> Was aber, wenn der Event ausbleibt, der die Variable> zurücksetzt? Darum ging es mir.
Sollte durch das KEY_UP ereignis nicht passieren.
Das ganze ist für spielprogrammierung interessant.
Key_down = Männchen läuft los solange Taste gehalten. Dank
Tastenwiederholung wird das Ereignis widerholt ausgelöst. Da aber KEIN
Key_up_Ereignis ausgelöst wird, bleibt das Männchen nicht steht bzw.
stolpert daher :)
Klar, die Tastenwiederholung könnte man auch nutzen, und auf das Key-Up
Ereignis vielleicht sogar ganz verzichten. Indem man einen Timer bei
jedem Key-Down re-triggert, so dass er bei gedrückter Taste nie auslösen
kann, und den Timer-Ablauf dann als Key-Up interpretiert. So ähnlich
habe ich implementiert. Es funktioniert, aber ich fand das nicht so
elegant. Ich werde mir dann die APIs noch mal ansehen, ob ich da was
basteln kann, was schicker ist. Mir stört auch, dass Zusatztasten wie
Shift oder CTRL Anschlagwiedrerholung haben. Sowas dürfte gar nicht sein
und andere Systeme, wo ich noch programmiere, haben das auch nicht. Da
ist SHIFT ein statischer Zustand, der entweder TRUE oder FALSE ist,
punkt.
Schlaumaier schrieb:> Jypama schrieb:>> Was aber, wenn der Event ausbleibt, der die Variable>> zurücksetzt? Darum ging es mir.>> Sollte durch das KEY_UP ereignis nicht passieren.
Ja doch, genau DAS ist doch das Problem. Bei gedrückter Shift-Taste auf
einen Button geklickt, öffnet sich der Explorer, und zwar im Vordergrund
bei voller Größe. Access, nun im Hintergrund, empfängt dann das
Loslassen der Shift-Taste nicht mehr.
Jypama schrieb:> Ja doch, genau DAS ist doch das Problem. Bei gedrückter Shift-Taste auf> einen Button geklickt, öffnet sich der Explorer, und zwar im Vordergrund> bei voller Größe. Access, nun im Hintergrund, empfängt dann das> Loslassen der Shift-Taste nicht mehr.
Aber es empfangt auf jeden Fall die Nachricht über den Verlust des
Focus. Die braucht man bloß auswerten und der Drops ist gelutscht. Wurde
übrigens auch schon mehrfach im Thread drauf hingewiesen, möchte ich
meinen...
"Wenn shifttaste gedrückt soll Explorer starten, text rot..."
UIs aus der Hölle. Access, VBA, da weiss man was man als Anwender für
einen Müll erwarten darf.
Schleimfasten schrieb:> "Wenn shifttaste gedrückt soll Explorer starten, text rot...">> UIs aus der Hölle. Access, VBA, da weiss man was man als Anwender für> einen Müll erwarten darf.
Chromium: <shift> + Bookmark. Macht genau das (statt text rot ist
button/pressed)
c-hater schrieb:> Aber es empfangt auf jeden Fall die Nachricht über den Verlust des> Focus. Die braucht man bloß auswerten und der Drops ist gelutscht. Wurde> übrigens auch schon mehrfach im Thread drauf hingewiesen, möchte ich> meinen...
Arroganz und große Töne haben in noch keinem Forum jemanden weiter
gebracht. Vor allem dann nicht, wenn es Schnellschüsse sind, die
überhaupt nicht funktionieren. Zum einen stellt Access keine Hausmittel
zur Verfügung, um festzustellen, dass es den Fokus verloren hat.
Formulare können das. Nur löst dieses Event z.B. auch dann aus, wenn in
diesem Formular auf ein Unterformular gewechselt wird. Denn das
Hauptformular wurde ja verlassen. Der Anwender muss eine Grenze zwischen
Form und UFo übrigens nicht erkennen, das ist der Sinn eingebetteter
Unterformulare. Daneben könnte man noch mindestens 10 weitere
Situationen aufzählen, wo der Lost-Focus-Event auch nicht auslöst. Aber
lassen wir das jetzt. Mir nur danach, festzustellen, dass Sprücheklopfer
wie "c-hater" immer nur destruktiv daherkommen. Im übrigen frage ich
mich gerade, wenn einer c "hatet" und von VBA auch keine Ahnung hat,
wovon er überhaupt Ahnung hat ... ;-)