How to turn off/block/trap the Windows (System) Key?

Started by IanMartin, February 13, 2018, 19:19:34

Previous topic - Next topic

IanMartin

I think I remember seeing a way to turn off the Windows Key in BlitzMax, or at least trap the input, something like that.  If I hit the Windows Key (System Key) (Const MODIFIER_SYSTEM=8   'windows or apple key) while playing a game on the keyboard the dang ole Windows menu comes up (on Windows 10/64 anyway).  At some point I thought I saw a way to turn it off on the old forums, but I'm searching everywhere on here and can't find it.

Does anyone know how to trap the Windows key so it won't work in the middle of my typing game?!   :'(
Platfinity (made with BlitzMax) on Steam:
http://store.steampowered.com/app/365440/Platfinity/


IanMartin

Yes, I think this is exactly what I'm looking for! 

I'm getting an error when I try to run the demo though. 

It's saying:
Compile Error
Unable to convert from 'Int' to 'Byte Ptr'
on this line:
   If enable wkhook = SetWindowsHookExA( 13, KeyboardProc, GetModuleHandleA( 0 ), 0 ) Else UnhookWindowsHookEx( wkhook )

I split it up to see if I could narrow it down:
'If enable wkhook = SetWindowsHookExA( 13, KeyboardProc, GetModuleHandleA( 0 ), 0 ) Else UnhookWindowsHookEx( wkhook )
If enable Then
wkhook = SetWindowsHookExA( 13, KeyboardProc, GetModuleHandleA( 0 ), 0 )
Else
UnhookWindowsHookEx( wkhook )
EndIf


and now it gives the same error on:
wkhook = SetWindowsHookExA( 13, KeyboardProc, GetModuleHandleA( 0 ), 0 )

...and I'm too dumb to know what that means.  I think it's trying to convert wkhook (an Int) into SetWindowsHookExA (which must be the Byte pointer(?) and I suppose if it works it sets wkhook to True (1)?

If I take out wkhook= in that line like so:
SetWindowsHookExA( 13, KeyboardProc, GetModuleHandleA( 0 ), 0 )
I get the error on this bit so I guess the bug is there?:
SetWindowsHookExA( 13, KeyboardProc, GetModuleHandleA( 0 ), 0 )

I'm not sure what's going wrong :/







Platfinity (made with BlitzMax) on Steam:
http://store.steampowered.com/app/365440/Platfinity/

peteswansen

#3
in Blitz3D these are the scancodes,  (not sure why this wouldnt work in BlitzMax..)

Left Windows   219 Left Windows Key
Right Windows 220 Right Windows Key

so looking at keycodes in BMAX I see this:

Sys key (Left)   KEY_LSYS
Sys key (Right)   KEY_RSYS

This sounds like it...  please respond and tell me if I am right!   :o


Derron

Use "Superstrict" to catch your errors.

"local variable=1" is an "int"
But the linked code sometimes uses "byte ptr" but does not explicitely define it that way - so BCC does silently make assumptions/casts.

Solution is to define a variable/param to be of type "byte ptr" when it is required.


bye
Ron

IanMartin

Hi Ron!

Thanks for your help again :)

It's in SuperStrict mode already.


Should wkhook be a byte ptr?  I tried changing that to (Global wkhook:Byte Ptr )
but then I get:
Compile Error - Unable To convert from 'Int' to 'Byte Ptr'
on this line:
   If( code <= 0 ) CallNextHookEx( wkhook, code, wparam, lparam )
of this function:
' Die Hook-Funktion, die bei jedem Tastendruck von Windows aufgerufen wird
Function KeyboardProc:Int( code:Int, wparam:Int, lparam:Int )
   If( code <= 0 ) CallNextHookEx( wkhook, code, wparam, lparam )
   
   ' Herausfinden, welche Taste gedrückt wurde
   Local key:Int = Byte Ptr( lparam )[0]

   If wparam = WM_KEYDOWN Or wparam = WM_KEYUP
      If( ( lwin And key = $5b ) Or ( rwin And key = $05c ) ) Return 1
   End If
   
   Return CallNextHookEx( wkhook, code, wparam, lparam )
End Function


Do I need to make CallNextHookEx a Byte Ptr too?  I'm not sure if that's what I need to do or how to do it.   Can an Extern function be changed like that?  I think I'm way out of my depth here, heheheh
Platfinity (made with BlitzMax) on Steam:
http://store.steampowered.com/app/365440/Platfinity/

IanMartin

Hi Pete!

Yes, the scancodes for the system keys are KEY_LSYS and KEY_RSYS.  I can read them fine with KeyDown() etc. 
What I'm trying to do is make it so the Windows key is deactivated while playing the game.  As it is now, if the user presses the Windows key during the game, the game loses focus and the Windows menu comes up in the bottom left corner.  Since it's a typing game, I can see players, especially new typists, accidentally hitting the Windows key while searching for Z or X or LShift.  Thanks for your help!

Platfinity (made with BlitzMax) on Steam:
http://store.steampowered.com/app/365440/Platfinity/

Derron

I think many of these things should be "byte ptr" rather than "int". The "lparam" and "wparam" will need an adjustment too - once you use NG (as WParam and LParam are types like Int/Float and so on). But for vanilla you need to stay with int/byte ptr (so you will add "?bmxng" conditionals).

Think for this "system.mod" would need some "superstrictness" to make it more clear. For now it defaults to "int" but feel free to cast it to "byte ptr"


byte ptr( CallNextHookEx(hhk,ncode,wparam,lparam) )
would cast the returned value from the assumed "int" to a byte pointer. You need such changes then to make them "fit" to what they really do.

Result of the above function is "LResult", so no "int".
https://msdn.microsoft.com/en-us/library/windows/desktop/ms644974(v=vs.85).aspx


Users like Col or Brucey (and many more) are used to do this stuff, so they might come up with something working. I am just a user benefiting from their skill. Sorry.

bye
Ron

Brucey

Hallo,

I have a working patch for NG (for both 32-bit and 64-bit).
I've put the function into pub.win32, for want of a better place to put it... unless someone has a better location. It doesn't belong in brl.system, because that's a backend-specific module, so if you wanted to use SDL, that function wouldn't be available.
Whereas, pub.win32 seems a fairly safe place...

If the consensus agrees, I will commit it, and then look at implementing the same for the legacy stuff...

:-X

IanMartin

Thanks Derron, but I'm still not sure what that means.  I'm well over my head here.  I figured you knew about it since you seem to be more knowledgeable than me!
I know what pointers are in theory, but never use them.  I'm not sure how to fix this code so the types match.  I've guessed a few things but they didn't work and I'm just moving the error from one spot to another.  Thanks again for trying to help me with it.  Maybe if I post the code someone can make the example work?

Platfinity (made with BlitzMax) on Steam:
http://store.steampowered.com/app/365440/Platfinity/

IanMartin

Hi Brucey!

You have a patch to make locking the keys work?  Like adding a LockWinKeys() function?
I haven't tried NG much.  I'm doing everything with vanilla BlitzMax with a few modules installed.  Forgive me if I'm a bit dumb about this stuff. 

Ian




Platfinity (made with BlitzMax) on Steam:
http://store.steampowered.com/app/365440/Platfinity/

IanMartin


The include file:
'lockwinkeys.bmx

' --- Funktionen ---
'--- Functions ---
?win32

Extern "win32"

   Function SetWindowsHookExA:Int( id:Int, hookproc:Int( code:Int, wparam:Int, lparam:Int ), instance:Int, thread:Int )
   Function UnhookWindowsHookEx:Int( hook:Int )
   Function CallNextHookEx:Int( hook:Int, code:Int, wparam:Int, lparam:Int )

End Extern

' Globale variablen, bitte nicht verändern ;)
'Global variables, please do not change;)
Global wkhook:Int
Global lwin:Int, rwin:Int

Const WH_KEYBOARD_LL:Int = 13

' Die Hook-Funktion, die bei jedem Tastendruck von Windows aufgerufen wird
'The hook function that is invoked each time Windows is pressed
Function KeyboardProc:Int( code:Int, wparam:Int, lparam:Int )
   If( code <= 0 ) CallNextHookEx( wkhook, code, wparam, lparam )
   
   ' Herausfinden, welche Taste gedrückt wurde
'Find out which key was pressed
   Local key:Int = Byte Ptr( lparam )[0]

   If wparam = WM_KEYDOWN Or wparam = WM_KEYUP
      If( ( lwin And key = $5b ) Or ( rwin And key = $05c ) ) Return 1
   End If
   
   Return CallNextHookEx( wkhook, code, wparam, lparam )
End Function

?

' Funktion zum Ein-/Ausschalten des Hooks. Vor dem Beenden sollte EnableKeyLock( False ) aufgerufen werden.
'Hook on / off function. Before closing, EnableKeyLock (False) should be called.
Function EnableKeyLock( enable:Int )
   ?win32
   
   If enable wkhook = SetWindowsHookExA( 13, KeyboardProc, GetModuleHandleA( 0 ), 0 ) Else UnhookWindowsHookEx( wkhook )
   
   ?
End Function

' Sperrt die linke oder rechte Windowstaste
'Locks the left or right Windows key
Function LockWinKeys( leftkey:Int, rightkey:Int )
   lwin = leftkey
   rwin = rightkey
End Function


The example:
' --- Beispiel ---
' --- Example ---
Framework brl.d3d7max2d
Import pub.win32

SuperStrict

Include "lockwinkeys.bmx"

Graphics 660, 220, 0

' Hook aktivieren
'Ativate hook
EnableKeyLock( True )

Local s1:Int, s2:Int

While Not( KeyDown( KEY_ESCAPE ) Or AppTerminate( ) )
   Cls
   
   If KeyHit( KEY_1 )
      s1 = 1 - s1
       
      ' Tasten sperren
'Lock keys
      LockWinKeys( s1, s2 )
   End If
   
   If KeyHit( KEY_2 )
      s2 = 1 - s2
       
      ' Tasten sperren
'Lock keys
      LockWinKeys( s1, s2 )
   End If
   
   DrawText( "--- Dieses Programm sperrt die Windowstasten ( made by Christian Klaussner ) ---", 10, 10 )
   DrawText( "Druecke die Tasten '1' und '2', um den Status zu wechseln.", 10, 70 )
   DrawText( "Null steht fuer normal, eins fuer gesperrt.", 10, 100 )
   DrawText( "Status der linken Taste: " + s1, 10, 150 )
   DrawText( "Status der rechten Taste: " + s2, 10, 180 )
   'DrawText ("--- This program locks the Windows keys (made by Christian Klaussner) ---", 10, 10)
   'DrawText ("Press the '1' and '2' keys to change status.", 10, 70)
   'DrawText ("Zero stands for normal, one for locked.", 10, 100)
   'DrawText ("Status of left Key: "+ s1, 10, 150)
   'DrawText (" Right Button Status: "+ s2, 10, 180)

   Flip
Wend

' Hook deaktivieren
'Disable hook
EnableKeyLock( False )

' Programm beenden
'Exit program
End


This says it was made by Christian Klaussner.  Does anyone know if he's on here?
Platfinity (made with BlitzMax) on Steam:
http://store.steampowered.com/app/365440/Platfinity/

peteswansen

#12
how about getting the program to invoke ESC if the Window Key (left or right is pressed). In B3D that unlocks the focus back to the program.
Or alternately trigger an external Right-Window or Left-Window.... that will return focus back to (in this case the B3D program).
:)

Brucey

Hallo,

I've added support for my legacy Pub.Win32 module, the commit can be found here : https://github.com/maxmods/pub.mod/commit/e0d3273a776db96f7d008cd02a86f0b86da49b31

The function is called EnableWindowsKeyLock()

It is a port from the NG version, and appears to work as expected from my limited testing, intercepting calls to the Windows keys (although I have only "left" Windows key on my keyboard, so was only able to test that one).

I generally recommend using the maxmods PUB and BRL modules over the official ones because they contain generally up-to-date third-party libraries, and other "fixes" that you won't find in the official ones. I consider the official modules deprecated...


IanMartin

Awesome!  That worked!  No more annoying Windows key :)  Thanks Brucey, you're the best!

I don't think I have a right windows/system key on my keyboard either.  Neither of my keyboards have a right windows key.  Not sure what's up with that but problem solved!

Thanks again :D

Platfinity (made with BlitzMax) on Steam:
http://store.steampowered.com/app/365440/Platfinity/