argumentum Posted December 31, 2023 Share Posted December 31, 2023 (edited) GetAsyncKeyState vs. Bluetooth headset Using the keyboard, the play/pause button behaves as expected but pressing the button in my Bluetooth headset does not. My solution to this bad implementation in the driver is to add a "is held" vs "is pressed"/"is clicked" in an @extended return: ( 1 = that is held, vs 0 = keyboard repeat ) See edit below. Func _IsPressed($sHexKey, $vDLL = "user32.dll") Local $aCall = DllCall($vDLL, "short", "GetAsyncKeyState", "int", "0x" & $sHexKey) If @error Then Return SetError(@error, @extended, False) Return SetError(0, BitAND($aCall[0], 0x1), BitAND($aCall[0], 0x8000) <> 0) EndFunc ;==>_IsPressed So the question/help is: are you MVP/developers ok with this added feature ?, will any of you add this request to the trac system or should I add the request ? Is this code above perfect or should be coded differently? I'll use it for my case as: If _IsPressed("B3", $hDLL) And @extended Then ConsoleWrite("Play/Pause" & @CRLF) Thanks in advance for your participation. PS: do the same to _WinAPI_GetAsyncKeyState(). Not needed. Edit: Opened a trac ticket. Edit: 2024.01.29: A better description of the code, given that I've change the logic: The @extended holds the LSB ( least significant bit ). What is meant is that when the key is first pressed, the LSB is set to 1. On subsequent calls, the LSB is set to zero and the claim is to not trust the LSB ( BitAND($aCall[0], 0x1) @extended ) due to the nature of multitasking, hence the BitAND($aCall[0], 0x8000) return. A good description would be: @extended returns the LSB of the keypress. (See MSDN remarks) Edited January 29 by argumentum better code Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Andreik Posted December 31, 2023 Share Posted December 31, 2023 I am not sure if it's reliable. Please try this script: $hUser32 = DllOpen('user32.dll') While True If _IsPressed('1B', $hUser32) Then ExitLoop ; Exit if ESC key is pressed While _IsPressed('41', $hUser32) ConsoleWrite('A is pressed.' & @TAB & @extended & @CRLF) Sleep(10) WEnd Sleep(10) WEnd DllClose($hUser32) Func _IsPressed($sHexKey, $vDLL = "user32.dll") Local $aCall = DllCall($vDLL, "short", "GetAsyncKeyState", "int", "0x" & $sHexKey) If @error Then Return SetError(@error, @extended, False) Return SetError(0, $aCall[0] = 0xFFFF8000, BitAND($aCall[0], 0x8000) <> 0) EndFunc If I keep key A pressed down I would expect to get @extended = 1 until I release the key but I get mixed values of 0 and 1. When the words fail... music speaks. Link to comment Share on other sites More sharing options...
argumentum Posted December 31, 2023 Author Share Posted December 31, 2023 (edited) 43 minutes ago, Andreik said: but I get mixed values of 0 and 1. the 1's is the key pressed but, every so often the keyboard will replay the key held down ( by a delay declared in the registry ). Therefore between repeats, you'll get 1's and the 0's mean the key got pressed or repeated. My problem is that the Bluetooth driver play/pause on fast click but turns the volume up/down if the key in the headset is held. Is a driver misbehaving that gives me the problem. Using _WinAPI_SetWindowsHookEx(), it sees the single press (play/pause), but not the volume up/down. Hence it is a problem with the OS ( by the way it integrates the Bluetooth and processes the user input device ). The @extended info, is just extra info, that in my case is useful and does not brake prior code. Usually that extra info is meaningless. The post, is to make sure that I -not being a programmer-, came up with an implementation that is sound for production and not just a hack for my issue. That is coded as it should be from the point of view of an experienced programmer. Edited December 31, 2023 by argumentum clarify Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Andreik Posted December 31, 2023 Share Posted December 31, 2023 (edited) For your specific case it's perfect, what I'm saying it's that probably it's not the best idea to change the actual _IsPressed() function since your proposed function it's working just in certain conditions. It might be better since it gives you additional info but not very consistent. Anyway I am happy that you posted because others might use this additional info so it's good to have another version of this function. 19 minutes ago, argumentum said: I -not being a programmer You have plenty of good code around. I'll ask mods to delete all your posts if you will keep saying this in 2024. PS: this is how you know you are getting old, when there are like 5 minutes until this year will pass but you are too lazy for anything else and prefer to test random code Edited December 31, 2023 by Andreik argumentum 1 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
argumentum Posted December 31, 2023 Author Share Posted December 31, 2023 2 minutes ago, Andreik said: since it gives you additional info but not very consistent. It is consistent. The 0's mean that the key press got printed. The 1's mean that the key is still pressed but is not the first press. If the key is still held after a set time, well, repeat the keypress. 5 minutes ago, Andreik said: if you will keep saying this in 2024. Thanks but, I have nowhere the experience or knowledge to say that what I present, is without a doubt the best there is. It may very well be, but I'm not that god like in regards to code. I do present myself to my clients as god like, but is because I, in fact am, for them Andreik 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Andreik Posted December 31, 2023 Share Posted December 31, 2023 1 minute ago, argumentum said: It is consistent. The 0's mean that the key press got printed. The 1's mean that the key is still pressed but is not the first press. If the key is still held after a set time, well, repeat the keypress. Ahhh I see now. I understand so hard and I'm not even drunk. In this case it's a nice addition. I'll have some more tests. 3 minutes ago, argumentum said: I do present myself to my clients as god like, but is because I, in fact am, for them Just don't overprice them because you feel like a god. argumentum 1 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
argumentum Posted December 31, 2023 Author Share Posted December 31, 2023 (edited) 8 minutes ago, Andreik said: I'll have some more tests. ...I see that on auto-repeat it does not show the reliability that a first press shows. Maybe a software de-bounce or go figure. Edited December 31, 2023 by argumentum Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Andreik Posted December 31, 2023 Share Posted December 31, 2023 11 minutes ago, argumentum said: Maybe a software de-bounce or go figure. For general purpose the function it's good as it is. If someone needs something else or more info, the keyboard hooks or other windows APIs can provide additional data. The only code I'm going to figure it out this night will be this: ConsoleWrite(@YEAR & @CRLF) argumentum 1 When the words fail... music speaks. Link to comment Share on other sites More sharing options...
Nine Posted January 2 Share Posted January 2 The reason why we cannot rely on isHeld approach is well explained in MSDN : Quote Although the least significant bit of the return value indicates whether the key has been pressed since the last query, due to the preemptive multitasking nature of Windows, another application can call GetAsyncKeyState and receive the "recently pressed" bit instead of your application. The behavior of the least significant bit of the return value is retained strictly for compatibility with 16-bit Windows applications (which are non-preemptive) and should not be relied upon. argumentum 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Solution argumentum Posted January 29 Author Solution Share Posted January 29 I've changed the code to do the opposite. The new code and notes are in the first post. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now