1
Post New Requests Here / "PazzPort Helper"
« on: May 17, 2010, 02:27 AM »So I recently bought a little gadget called an iPazzPort (among other aliases) and am getting another as a present for someone. Basically, this thing is a tiny wireless QWERTY keyboard and touchpad (picture here, review here). I'm generally enjoying it; wouldn't want to do extensive typing on it at all, though. But--I'm finding out just how spoiled I usually am in terms of navigation on a laptop. This thing doesn't have a scroll region on the touchpad, and it's missing several important (to me) keys: Function keys, Win key, Tab, Shift, Home, End, PgUp, PgDown, Prnt Scrn, etc. You can see the keyboard layout in the above picture. Yep, no Alt+F4, no Alt+Tab, no Win+E, no Ctrl+Shift+End, etc. - all the shortcut keys that I normally use so often.
Especially since I'll be "gifting" one of these shortly, I'm trying to figure out a way to fill the void as far as navigation goes. I've been messing around with a combination of the portable mouse gestures program StrokeIt and an AutoHotkey script. My goal is to have something as simple, yet functional, as possible. Here's what I was thinking so far, but if anyone has better ideas I don't mind scrapping this. This has a lot of re-mapping to remember, which can just get confusing. I'm a newbie at AHK and the below took me an embarrassing number of hours, so if someone else wants to start from scratch, I wouldn't mind that either...
#SingleInstance force
;Alt+F4
; missing: Function keys, Win key, Tab, Shift, Home, End, PgUp, PgDown, Prnt Scrn,
; `::Tab
Ctrl & Backspace::AltTabMenu
~t::RapidHotkey("{TAB}",3, 0.2)
~a::RapidHotkey("!^a", 3, 0.2)
~q::RapidHotkey("#zqdir{Enter}""!{F4}",2)
~e::RapidHotkey("#z""#r""#e",3, 0.2)
~Esc::RapidHotkey("SusScript""ReloadScript""exit", 3, 0.2, 1) ;Press Esc 5 times rapidly to exit this script
Ctrl & Esc::
send {LAlt down}
send {LWin down}
sleep 1500
send {LWin up}
send {LAlt up}
return
Alt & Esc::
send {Shift down}
sleep 3000
send {Shift up}
return
SusScript:
Suspend on
sleep 3000
Suspend off
return
ReloadScript:
Reload
MsgBox,0,,Reloaded
return
Exit:
ExitApp
; ------- HotKeyIt's "RapidHotkey" function --------
RapidHotkey(keystroke, times="", delay=0.15, IsLabel=0)
{
Pattern := Morse(delay*1000)
If (StrLen(Pattern) < 2 and Chr(Asc(times)) != "1")
Return
If (times = "" and InStr(keystroke, """"))
{
Loop, Parse, keystroke,""
If (StrLen(Pattern) = A_Index+1)
continue := A_Index, times := StrLen(Pattern)
}
Else if (RegExMatch(times, "^\d+$") and InStr(keystroke, """"))
{
Loop, Parse, keystroke,""
If (StrLen(Pattern) = A_Index+times-1)
times := StrLen(Pattern), continue := A_Index
}
Else if InStr(times, """")
{
Loop, Parse, times,""
If (StrLen(Pattern) = A_LoopField)
continue := A_Index, times := A_LoopField
}
Else if (times = "")
continue = 1, times = 1
Else if (times = StrLen(Pattern))
continue = 1
If !continue
Return
Loop, Parse, keystroke,""
If (continue = A_Index)
keystr := A_LoopField
Loop, Parse, IsLabel,""
If (continue = A_Index)
IsLabel := A_LoopField
hotkey := RegExReplace(A_ThisHotkey, "[\*\~\$\#\+\!\^]")
Loop % times
backspace .= "{Backspace}"
keywait = Ctrl|Alt|Shift|LWin|RWin
Loop, Parse, keywait, |
KeyWait, %A_LoopField%
If ((!IsLabel or (IsLabel and IsLabel(keystr))) and InStr(A_ThisHotkey, "~") and !RegExMatch(A_ThisHotkey
, "i)\^[^\!\d]|![^\d]|#|Control|Ctrl|LCtrl|RCtrl|Shift|RShift|LShift|RWin|LWin|Escape|BackSpace|F\d\d?|"
. "Insert|Esc|Escape|BS|Delete|Home|End|PgDn|PgUp|Up|Down|Left|Right|ScrollLock|CapsLock|NumLock|AppsKey|"
. "PrintScreen|CtrlDown|Pause|Break|Help|Sleep|Browser_Back|Browser_Forward|Browser_Refresh|Browser_Stop|"
. "Browser_Search|Browser_Favorites|Browser_Home|Volume_Mute|Volume_Down|Volume_Up|MButton|RButton|LButton|"
. "Media_Next|Media_Prev|Media_Stop|Media_Play_Pause|Launch_Mail|Launch_Media|Launch_App1|Launch_App2"))
Send % backspace
If (WinExist("AHK_class #32768") and hotkey = "RButton")
WinClose, AHK_class #32768
If !IsLabel
Send % keystr
else if IsLabel(keystr)
Gosub, %keystr%
Return
}
Morse(timeout = 400) { ;by Laszo -> http://www.autohotkey.com/forum/viewtopic.php?t=16951 (Modified to return: KeyWait %key%, T%tout%)
static lastkey
tout := timeout/1000
key := RegExReplace(A_ThisHotKey,"[\*\~\$\#\+\!\^]")
Loop {
t := A_TickCount
KeyWait %key%, T%tout%
Pattern .= A_TickCount-t > timeout
If(ErrorLevel)
Return Pattern
KeyWait %key%,DT%tout%
If (ErrorLevel)
Return Pattern
}
}
;Alt+F4
; missing: Function keys, Win key, Tab, Shift, Home, End, PgUp, PgDown, Prnt Scrn,
; `::Tab
Ctrl & Backspace::AltTabMenu
~t::RapidHotkey("{TAB}",3, 0.2)
~a::RapidHotkey("!^a", 3, 0.2)
~q::RapidHotkey("#zqdir{Enter}""!{F4}",2)
~e::RapidHotkey("#z""#r""#e",3, 0.2)
~Esc::RapidHotkey("SusScript""ReloadScript""exit", 3, 0.2, 1) ;Press Esc 5 times rapidly to exit this script
Ctrl & Esc::
send {LAlt down}
send {LWin down}
sleep 1500
send {LWin up}
send {LAlt up}
return
Alt & Esc::
send {Shift down}
sleep 3000
send {Shift up}
return
SusScript:
Suspend on
sleep 3000
Suspend off
return
ReloadScript:
Reload
MsgBox,0,,Reloaded
return
Exit:
ExitApp
; ------- HotKeyIt's "RapidHotkey" function --------
RapidHotkey(keystroke, times="", delay=0.15, IsLabel=0)
{
Pattern := Morse(delay*1000)
If (StrLen(Pattern) < 2 and Chr(Asc(times)) != "1")
Return
If (times = "" and InStr(keystroke, """"))
{
Loop, Parse, keystroke,""
If (StrLen(Pattern) = A_Index+1)
continue := A_Index, times := StrLen(Pattern)
}
Else if (RegExMatch(times, "^\d+$") and InStr(keystroke, """"))
{
Loop, Parse, keystroke,""
If (StrLen(Pattern) = A_Index+times-1)
times := StrLen(Pattern), continue := A_Index
}
Else if InStr(times, """")
{
Loop, Parse, times,""
If (StrLen(Pattern) = A_LoopField)
continue := A_Index, times := A_LoopField
}
Else if (times = "")
continue = 1, times = 1
Else if (times = StrLen(Pattern))
continue = 1
If !continue
Return
Loop, Parse, keystroke,""
If (continue = A_Index)
keystr := A_LoopField
Loop, Parse, IsLabel,""
If (continue = A_Index)
IsLabel := A_LoopField
hotkey := RegExReplace(A_ThisHotkey, "[\*\~\$\#\+\!\^]")
Loop % times
backspace .= "{Backspace}"
keywait = Ctrl|Alt|Shift|LWin|RWin
Loop, Parse, keywait, |
KeyWait, %A_LoopField%
If ((!IsLabel or (IsLabel and IsLabel(keystr))) and InStr(A_ThisHotkey, "~") and !RegExMatch(A_ThisHotkey
, "i)\^[^\!\d]|![^\d]|#|Control|Ctrl|LCtrl|RCtrl|Shift|RShift|LShift|RWin|LWin|Escape|BackSpace|F\d\d?|"
. "Insert|Esc|Escape|BS|Delete|Home|End|PgDn|PgUp|Up|Down|Left|Right|ScrollLock|CapsLock|NumLock|AppsKey|"
. "PrintScreen|CtrlDown|Pause|Break|Help|Sleep|Browser_Back|Browser_Forward|Browser_Refresh|Browser_Stop|"
. "Browser_Search|Browser_Favorites|Browser_Home|Volume_Mute|Volume_Down|Volume_Up|MButton|RButton|LButton|"
. "Media_Next|Media_Prev|Media_Stop|Media_Play_Pause|Launch_Mail|Launch_Media|Launch_App1|Launch_App2"))
Send % backspace
If (WinExist("AHK_class #32768") and hotkey = "RButton")
WinClose, AHK_class #32768
If !IsLabel
Send % keystr
else if IsLabel(keystr)
Gosub, %keystr%
Return
}
Morse(timeout = 400) { ;by Laszo -> http://www.autohotkey.com/forum/viewtopic.php?t=16951 (Modified to return: KeyWait %key%, T%tout%)
static lastkey
tout := timeout/1000
key := RegExReplace(A_ThisHotKey,"[\*\~\$\#\+\!\^]")
Loop {
t := A_TickCount
KeyWait %key%, T%tout%
Pattern .= A_TickCount-t > timeout
If(ErrorLevel)
Return Pattern
KeyWait %key%,DT%tout%
If (ErrorLevel)
Return Pattern
}
}
So far my "strategy" has been to use not-likely-used key combinations (e.g. Ctrl+Esc), or multiple key presses with the RapidHotkey function. But there are only so many unused key combinations, and I don't know that they might do something horrible in some programs. And RapidHotkey uses backspace to clear the triggering text entry, which of course causes something else entirely in an Explorer or Internet Explorer window. Plus it's hard to remember, potentially unreliable if the iPazzPort/my fingers are finicky, etc. One of the other things I was doing is to send "down" messages for certain unavailable modifier keys, sleep for a few seconds to give me time for key combinations, then send the "up" messages. Again, there are probably better, more efficient, more easily remembered ways of doing that?
Help! :)