Great stuff, guys. Thanks!
I now took it a step further and rewritten it all to combine features from all the above versions, and have a UI to work with.
I called it Toddler Friend and it's in version 0.9b (beta, not tested enough)
Features:
- Override key (as before - defaulted it to NumLock but easy to change)
- Convert blocked keys to space (for 'hit any key' games)
- Ability to allow mouse, alphanumerics, arrows independently
- Prevent key repeat (not working quite right though)
- Hotkeys to toggle all features
- UI to modify the features in a user friendly way
- Easy to change settings
Code:
; Toddler Friend v 0.9b
; v1.0 48.02 April 09
;
; AutoHotkey Version: 1.x (fails with version 1.0.44.07)
; Platform: WinNT/2k/XP
; Author: Greg De Haas (PlaceboZA, www.grelly.com)
;
; Script Function:
; Allows you to block keyboard and mouse functions selectively, to prevent your adorable wadget
; from doing something silly (like closing the window or rebooting)
; There is also an override key of NumLock (easily changeable) which will allow you to use the keyboard normally while holding
; In addition, you can force all blocked keys to produce a space (Nice for games where 'hit any key' applies)
; And that's not all... you get key repeat prevention as well (although this isn't quite right as at time of writing)
; Feel free to change settings below
;
; Things you might like to change:
; - The override key & startup settings. Just change it in the Public Settings section below
; - If you, for example, want spacebar hotkey to be considered as part of the alpha-numeric keys,
; then simply move it into the alpha-numeric section
; - I don't convert mouse buttons to spaces when using the 'replace keys with space' option, because my daughter hits the touchpad too easily
; - Compile to exe, give it an icon, remove tray icon, etc
;
; TODO:
; - When enabled & with allow mouse buttons, you still can't drag windows. Not sure why.
; - The prevention of repeat keys doesn't quite work right.. seems to still allow for a single follup repeat
; - Left Control and Shift keys couldn't be blocked because they interfere with the global shortcuts
; - Some laptops' touchpad scrolls aren't blocked apparently
; - Block Ctrl-Alt-Del ? Debatable.. and not really necessary IMO
;
; Credits:
; Boris Mazic and bobbo for the original idea of the Toddler Keyboard scripts
#NoEnv ;
SendMode Input ;
;----------- Public Settings (Change as needed) -------------------
OverrideKey := "NumLock" ;Remember to comment it out from the hotkeys below (don't block it) and uncomment the one that was used previously
ShowSettingsOnStart = true
StartEnabled := false
StartWithAllowAlphaNumeric := false
StartWithAllowArrows := false
StartWithConvertToSpace := false
StartWithPreventRepeats := true
AllowConvertMouseButtonsToSpace := false ;If false, then only keyboard actions result in space, if Convert To Space is on
;----------- Private Settings -------------------------------------
Version := "0.9b"
;----------- Initial Values ---------------------------------------
m_enabled := (StartEnabled) ? 1 : 0
m_allowAlphanumerics := (StartWithAllowAlphaNumeric) ? 1 : 0
m_allowMouse := (StartWithAllowMouse) ? 1 : 0
m_allowArrows := (StartWithAllowArrows) ? 1 : 0
m_replaceWithSpace := (StartWithConvertToSpace) ? 1 : 0
m_preventRepeats := (StartWithPreventRepeats) ? 1 : 0
m_hintState := 0 ;0=no hint, 1=hint displayed, 2=busy building
;Suspend if needed
if !m_enabled
Suspend On
;Set up menu
Menu, TRAY, NoStandard
Menu, TRAY, Add, Show Settings..., OnShowSettings
Menu, TRAY, Add, Exit, OnExitApp
Menu, TRAY, Default, Show Settings...
if ShowSettingsOnStart
DisplaySettings()
return
ResendKeyEx(key, prevKey, timeSince, noRepeat)
{
if (!noRepeat or !CheckIfRepeat(key, prevKey, timeSince))
ResendKey(key)
}
CheckIfRepeat(key, prevKey, timeSince)
{
return (key = prevKey and timeSince < 150) ? true : false
}
ResendKey(key)
{
global OverrideKey
mod := (GetKeyState("RShift", "P") ? "+" : "")
mod .= (GetKeyState("Alt", "P") ? "!" : "")
mod .= (GetKeyState("Control", "P") ? "^" : "")
mod .= (GetKeyState("LWin", "P") || GetKeyState("RWin", "P") ? "#" : "")
key := RegExReplace(key, "^" . OverrideKey . "\s+\&\s*") ;Remove override key if necessary
key := RegExReplace(key, "^\*")
;FileAppend, %mod% + %key%`n, C:\keys.txt
;Resend key
hotkey := "*" . key
Hotkey, %hotkey%, Off, UseErrorLevel
Send, %mod%{%key%}
Hotkey, %hotkey%, On, UseErrorLevel
}
CheckForOverride()
{
global OverrideKey
state := GetKeyState(OverrideKey, "P")
return state
}
DisplaySettings()
{
global Version
global m_allowAlphanumerics
global m_replaceWithSpace
global m_allowMouse
global m_enabled
global m_allowArrows
global m_preventRepeats
global OverrideKey
grayed := (m_enabled = 0) ? "Disabled" : ""
note := "Global Shortcuts: " . OverrideKey . " + Ctrl + Shift + [Option]"
Gui 8: Default
Gui, Destroy
Gui, +AlwaysOnTop +LastFound +ToolWindow ; +ToolWindow avoids a taskbar button and an alt-tab menu item.
Gui, Color, EEF2FF
Gui, Font, s8, Tahoma
Gui, Add, CheckBox, x12 y7 Autosize h20 vm_enabled Checked%m_enabled% gOnEnable, [E]nable Toddler Control
Gui, Add, CheckBox, x12 y27 Autosize h20 %grayed% Checked%m_replaceWithSpace% vm_replaceWithSpace, [R]eplace blocked keys with space
Gui, Add, CheckBox, x12 y47 Autosize h20 %grayed% Checked%m_preventRepeats% vm_preventRepeats, [P]revent held keys from repeating
Gui, Add, GroupBox, x12 y70 w300 h90, Block everything except...
Gui, Add, CheckBox, x22 y87 Autosize h20 %grayed% Checked%m_allowAlphanumerics% vm_allowAlphanumerics, [A]lpha-numeric keys
Gui, Add, CheckBox, x22 y107 Autosize h20 %grayed% Checked%m_allowMouse% vm_allowMouse, [M]ouse buttons
Gui, Add, CheckBox, x22 y127 Autosize h20 %grayed% Checked%m_allowArrows% vm_allowArrows, [C]ursor/arrow keys
Gui, Add, Text, x15 y165 w300 h20, %note%
Gui, Add, Button, x162 y192 w70 h20 gOnOK Default, &OK
Gui, Add, Button, x242 y192 w70 h20 gOnCancel, &Cancel
Gui, Show, Center h196 Autosize, [T]oddler Friend v%Version%, PlaceboZA (grelly.com) ; NoActivate avoids deactivating the currently active window.
Gui 1: Default
return
8GuiEscape:
Gui 8: Cancel
return
OnEnable:
Gui 8: Default
GuiControlGet, state, , m_enabled
enable := (state = 1) ? "Enable" : "Disable"
GuiControl, %enable%, m_replaceWithSpace
GuiControl, %enable%, m_preventRepeats
GuiControl, %enable%, m_allowAlphanumerics
GuiControl, %enable%, m_allowMouse
GuiControl, %enable%, m_allowArrows
Gui 1: Default
return
OnOK:
Gui 8: Submit
if m_enabled
Suspend Off
else
Suspend On
return
OnCancel:
Gui 8: Cancel
return
}
DisplayQuickHint(HintText, Delay) ;Gui #9 is the hint
{
;Use HintState and close window if still displaying
global HintState
if HintState = 1
Gui, 9: Destroy ;Close it
;Init
HintState = 2
;Set Gui
Gui 9: +AlwaysOnTop +LastFound +ToolWindow ; +ToolWindow avoids a taskbar button and an alt-tab menu item.
Gui 9: Color, EEF2FF
Gui 9: Font, s8 bold, Verdana
Gui 9: Add, Text, cBlack, %HintText%
Gui 9: -Caption +Border ; Remove the title bar and window borders.
Gui 9: Show, x2 y2 NoActivate AutoSize ; NoActivate avoids deactivating the currently active window.
HintState = 1
SetTimer, CloseHintLabel, %Delay%
return
CloseHintLabel:
SetTimer, CloseHintLabel, Off
if HintState = 1
Gui, 9: Destroy ;Close it
return
}
ToggleEnabled()
{
global m_enabled
m_enabled := (m_enabled = 1) ? 0 : 1
if m_enabled = 1
Suspend Off
else
Suspend On
DisplayQuickHint("Toddler Friend: " . ((m_enabled = 1) ? "Enabled" : "Disabled"), 1500)
}
ToggleSpaceConvert()
{
global m_replaceWithSpace
m_replaceWithSpace := (m_replaceWithSpace = 1) ? 0 : 1
DisplayQuickHint("Toddler Friend: Blocked keys" . ((m_replaceWithSpace = 1) ? " will be " : " are no longer ") . "converted to a space", 1500)
}
ToggleAllowMouse()
{
global m_allowMouse
m_allowMouse := (m_allowMouse = 1) ? 0 : 1
DisplayQuickHint("Toddler Friend: Mouse buttons" . ((m_allowMouse = 1) ? " will be allowed" : " will be blocked"), 1500)
}
ToggleAllowArrows()
{
global m_allowArrows
m_allowArrows := (m_allowArrows = 1) ? 0 : 1
DisplayQuickHint("Toddler Friend: Cursor/arrow keys" . ((m_allowArrows = 1) ? " will be allowed" : " will be blocked"), 1500)
}
ToggleAllowAlphanumerics()
{
global m_allowAlphanumerics
m_allowAlphanumerics := (m_allowAlphanumerics = 1) ? 0 : 1
DisplayQuickHint("Toddler Friend: Alpha-numeric keys" . ((m_allowAlphanumerics = 1) ? " will be allowed" : " will be blocked"), 1500)
}
TogglePreventRepeats()
{
global m_preventRepeats
m_preventRepeats := (m_preventRepeats = 1) ? 0 : 1
DisplayQuickHint("Toddler Friend: Held keys will" . ((m_preventRepeats = 1) ? " cause a single keypress" : " will repeat the keypress "), 1500)
}
OnExitApp: ;Used by tray menu
ExitApp
return
OnShowSettings: ;Used by tray menu
DisplaySettings()
return
; Global system shortcuts
^+e:: ;Enable/Disable
Suspend, Permit ;Allow when suspended
if CheckForOverride()
ToggleEnabled()
return
^+t:: ;Display Settings
Suspend, Permit ;Allow when suspended
if CheckForOverride()
DisplaySettings()
return
^+r:: ;Replace spaces
Suspend, Permit ;Allow when suspended
if CheckForOverride()
ToggleSpaceConvert()
return
^+p:: ;Prevent repeats of held keys
Suspend, Permit ;Allow when suspended
if CheckForOverride()
TogglePreventRepeats()
return
^+m:: ;Allow mouse
Suspend, Permit ;Allow when suspended
if CheckForOverride()
ToggleAllowMouse()
return
^+c:: ;Allow cursor
Suspend, Permit ;Allow when suspended
if CheckForOverride()
ToggleAllowArrows()
return
^+a:: ;Allow alphanumerics
Suspend, Permit ;Allow when suspended
if CheckForOverride()
ToggleAllowAlphanumerics()
return
; Alpha-numerics
*a::
*b::
*c::
*d::
*e::
*f::
*g::
*h::
*i::
*j::
*k::
*l::
*m::
*n::
*o::
*p::
*q::
*r::
*s::
*t::
*u::
*v::
*w::
*x::
*y::
*z::
*0::
*1::
*2::
*3::
*4::
*5::
*6::
*7::
*8::
*9::
if CheckForOverride() or m_allowAlphanumerics = 1
ResendKeyEx(A_ThisHotkey, A_PriorHotkey, A_TimeSincePriorHotkey, (m_preventRepeats = 1) ? true : false)
else if (m_replaceWithSpace = 1 and (m_preventRepeats = 0 or !CheckIfRepeat(A_ThisHotkey, A_PriorHotkey, A_TimeSincePriorHotkey)))
Send, {Space}
return
; Mouse buttons
*LButton::
*RButton::
*MButton::
*WheelDown::
*WheelUp::
*XButton1::
*XButton2::
if CheckForOverride() or m_allowMouse = 1
ResendKeyEx(A_ThisHotkey, A_PriorHotkey, A_TimeSincePriorHotkey, (m_preventRepeats = 1) ? true : false)
else if (m_replaceWithSpace = 1 and AllowConvertMouseButtonsToSpace)
Send, {Space}
return
; Arrows
*Up::
*Down::
*Left::
*Right::
if CheckForOverride() or m_allowArrows = 1
ResendKeyEx(A_ThisHotkey, A_PriorHotkey, A_TimeSincePriorHotkey, (m_preventRepeats = 1) ? true : false)
else if (m_replaceWithSpace = 1 and (m_preventRepeats = 0 or !CheckIfRepeat(A_ThisHotkey, A_PriorHotkey, A_TimeSincePriorHotkey)))
Send, {Space}
return
; Other keys (starting with ones you might want to include above)
*Space::
*Enter::
*Tab::
*Escape::
*Backspace::
*Numpad0::
*NumpadIns::
*Numpad1::
*NumpadEnd::
*Numpad2::
*NumpadDown::
*Numpad3::
*NumpadPgDn::
*Numpad4::
*NumpadLeft::
*Numpad5::
*NumpadClear::
*Numpad6::
*NumpadRight::
*Numpad7::
*NumpadHome::
*Numpad8::
*NumpadUp:
*Numpad9::
*NumpadPgUp::
*NumpadDot::
*NumpadDel::
*NumpadDiv::
*NumpadMult::
*NumpadAdd::
*NumpadSub::
*NumpadEnter::
*Delete::
*Insert::
*Home::
*End::
*PgUp::
*PgDn::
*ScrollLock::
*CapsLock::
;*NumLock:: ;This interferes with global shortcuts and overrides
*F1::
*F2::
*F3::
*F4::
*F5::
*F6::
*F7::
*F8::
*F9::
*F10::
*F11::
*F12::
*F13::
*F14::
*F15::
*F16::
*F17::
*F18::
*F19::
*F20::
*F21::
*F22::
*F23::
*F24::
*AppsKey::
*LWin::
*RWin::
;*LControl:: ;These interfere with global shortcuts
*RControl::
;*LShift:: ;These interfere with global shortcuts
*RShift::
*LAlt::
*RAlt::
*PrintScreen::
*CtrlBreak::
*Pause::
*Break::
*Help::
*Sleep::
*Browser_Back::
*Browser_Forward::
*Browser_Refresh::
*Browser_Stop::
*Browser_Search::
*Browser_Favorites::
*Browser_Home::
*Volume_Mute::
*Volume_Down::
*Volume_Up::
*Media_Next::
*Media_Prev::
*Media_Stop::
*Media_Play_Pause::
*Launch_Mail::
*Launch_Media::
*Launch_App1::
*Launch_App2::
if CheckForOverride()
ResendKeyEx(A_ThisHotkey, A_PriorHotkey, A_TimeSincePriorHotkey, (m_preventRepeats = 1) ? true : false)
else if (m_replaceWithSpace = 1 and (m_preventRepeats = 0 or !CheckIfRepeat(A_ThisHotkey, A_PriorHotkey, A_TimeSincePriorHotkey)))
Send, {Space}
return