AutoHotkey Community

It is currently May 25th, 2012, 10:44 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 14 posts ] 
Author Message
PostPosted: January 18th, 2008, 8:08 am 
Offline

Joined: December 6th, 2007, 12:48 pm
Posts: 364
This time (2 in 24, I'm no flooder :P) I was thinking about sending a macro by pressing a modificator key, like CTRL, then, with it pressed, we type a hotstring. This could be to perform other actions, not only sending keystroke macros.

Example:
::btw:: = by the way;
{shiftdn}::btw::{shiftup} = BY THE WAY <-- this is already possible

Ctrl+::ff:: (hold Ctrl then type ff) --> Run \...\Firefox.exe <-- not possible yet as far as I know.

Got it?
How do we do that?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 18th, 2008, 8:42 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
Here's one way:
Code:
Ctrl::
    Input, cmd
    MsgBox %cmd%
return
Ctrl Up::Input ; end Input
Unfortunately Ctrl must be blocked (Ctrl:: vs ~Ctrl::) since it would otherwise prevent the keystrokes from being recognized as regular text. You could use LCtrl or RCtrl instead, if you still need a Ctrl key.

Here's another way that "hooks" only alphabetic keys:
Code:
~Ctrl::
    ; Create/enable a hotkey for each letter of the alphabet.
    Loop 26
        Hotkey % "^" Chr(A_Index+96), Type, On
return
~Ctrl Up::
    Loop 26
        Hotkey % "^" Chr(A_Index+96), Type, Off

    if text
    {
        MsgBox %text%
        text =
    }
return

Type:
    text .= SubStr(A_ThisHotkey,2)
return


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 18th, 2008, 8:51 am 
Offline

Joined: May 10th, 2007, 2:52 am
Posts: 194
Location: China/ Canada
Code:
^f::
KeyPressRec := KeyPressRec A_ThisHotkey
If KeyPressRec = ^f^f
{
 msgbox, done
 KeyPressRec =
}
return

_________________
Sakurako ^_^


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 18th, 2008, 9:27 am 
Offline

Joined: December 6th, 2007, 12:48 pm
Posts: 364
Sakurako wrote:
Code:
^f::
KeyPressRec := KeyPressRec A_ThisHotkey
If KeyPressRec = ^f^f
{
 msgbox, done
 KeyPressRec =
}
return


This appears to be the closest to the goal, but I couldn't understand the logic as a whole. In that code, the only thing I can do is to set "Ctrl+FF" to trigger the action, but I couldn't change it to any other combination, for example: Holding CTRL then typing "fight" to perform the action (msgbox in the case). Where exactly should I put the letters f i g h t ?

@lexikos: your second code is almost perfect, it actually works but doesn't release the CTRL key for further different uses. I relized that although I can set any little text to be used in the hotstring while holding ctrl, this includes the traditional uses like ctrl+c, ctrl+v etc. Actually I'm seeking a way to have it trigger only when some specific hotstrings are input, not any text like your code suggests :(


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 18th, 2008, 10:02 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
Da Rossa wrote:
@lexikos: your second code is almost perfect, it actually works but doesn't release the CTRL key for further different uses.
You have full control over what it does when you type something. i.e. All you need to do is explicitly tell it what "further different uses" to allow. The following will allow Ctrl+single-key-press to perform its usual function (with the exception that you must release Ctrl first):
Code:
~Ctrl::
    ; Create/enable a hotkey for each letter of the alphabet.
    Loop 26
        Hotkey % "^" Chr(A_Index+96), Type, On
return
~Ctrl Up::
    Loop 26
        Hotkey % "^" Chr(A_Index+96), Type, Off

    if text
    {
        if StrLen(text) = 1
            Send ^%text%
        else

            MsgBox %text%
        text =
    }
return

Type:
    text .= SubStr(A_ThisHotkey,2)
return

Alternately, you could allow multiple key-presses if the string isn't recognized:
Code:
Send {Ctrl Down}%text%{Ctrl Up}
If you also pressed other keys/key combinations that aren't caught by the script, the keystrokes would end up out of order, with the ^alphabetic keystrokes grouped at the end.

Perhaps a better solution would be to check at each key-press whether the text matches part of a recognized command. If it does not, send what was typed and disable the hotkeys until Ctrl is pressed again.

Consider using a key that isn't usually used as a modifier. For instance:
Code:
$Space::
    SpaceTick := A_TickCount
   
    ; Let user enter a command/text. Does not return
    Input, seq    ; until terminated by Space Up::
   
    if (A_TickCount-SpaceTick < 250 or seq="")
    {  ; So as to not interfere with quick typing, count this as having
        Send {Space}%seq%   ; released Space before entering %seq%.
        return
    }
    ; Show entered text.
    MsgBox %seq%
return
Space Up::Input ; end Input-in-progress
I posted this as a reply to spacebar as a hotkey trigger, plus more..


Report this post
Top
 Profile  
Reply with quote  
PostPosted: January 18th, 2008, 4:12 pm 
Offline

Joined: December 20th, 2005, 4:15 am
Posts: 165
Location: Malaysia
Sounds like a "detect double-presses of a hotkey" problem; you're checking whether the user pressed ctrl-f twice. The SetTimer documentation has example code for this (scroll to example #3):

http://www.autohotkey.com/docs/commands/SetTimer.htm

As a bonus, you can define the time window (e.g. within 500ms) for the double-press.

Da Rossa wrote:
This time (2 in 24, I'm no flooder :P) I was thinking about sending a macro by pressing a modificator key, like CTRL, then, with it pressed, we type a hotstring. This could be to perform other actions, not only sending keystroke macros.

Example:
::btw:: = by the way;
{shiftdn}::btw::{shiftup} = BY THE WAY <-- this is already possible

Ctrl+::ff:: (hold Ctrl then type ff) --> Run \...\Firefox.exe <-- not possible yet as far as I know.

Got it?
How do we do that?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 18th, 2008, 5:03 pm 
Offline

Joined: May 10th, 2007, 2:52 am
Posts: 194
Location: China/ Canada
Da Rossa wrote:
Sakurako wrote:
Code:
^f::
KeyPressRec := KeyPressRec A_ThisHotkey
If KeyPressRec = ^f^f
{
 msgbox, done
 KeyPressRec =
}
return


This appears to be the closest to the goal, but I couldn't understand the logic as a whole. In that code, the only thing I can do is to set "Ctrl+FF" to trigger the action, but I couldn't change it to any other combination, for example: Holding CTRL then typing "fight" to perform the action (msgbox in the case). Where exactly should I put the letters f i g h t ? ...
Code:
KeyCheck = ^f|^i|^g|^h|^t ;List of key to detect
Loop, Parse, KeyCheck, |
 If StrLen(A_LoopField) = 1
  Hotkey, ~%A_LoopField%, KeyPress
 Else if (A_LoopField = "^c") or (A_LoopField = "^v") ;~Hotkey
  Hotkey, ~%A_LoopField%, KeyPress
 Else ;Hotkey
  Hotkey, %A_LoopField%, KeyPress
KeyNum = 0
return

KeyPress:
KeyPressRec := KeyPressRec A_ThisHotkey
IfInString, KeyPressRec, ~
{
 StringReplace, KeyPressRec, KeyPressRec, ~
 If StrLen(A_ThisHotkey) = 2
  KeyNum += 1
}
if KeyPressRec contains ^t,^f^f ;^t, ^f^f
{
 SendInput, {Backspace %KeyNum%}
 {
  msgbox, %KeyPressRec% ;command(s) to perform
 }
 KeyPressRec =
 KeyNum = 0
}
return

_________________
Sakurako ^_^


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 19th, 2008, 7:07 am 
Offline

Joined: December 6th, 2007, 12:48 pm
Posts: 364
@ Lexikos:

your first code, this
Code:
~Ctrl::
    ; Create/enable a hotkey for each letter of the alphabet.
    Loop 26
        Hotkey % "^" Chr(A_Index+96), Type, On
return
~Ctrl Up::
    Loop 26
        Hotkey % "^" Chr(A_Index+96), Type, Off

    if text
    {
        if StrLen(text) = 1
            Send ^%text%
        else
            MsgBox %text%
        text =
    }
return

Type:
    text .= SubStr(A_ThisHotkey,2)
return

has a drawback: it slows down the past process. Also, it is impossible to have CTRL held down and pressing V repeated times to past repeated times, instead, your msgbox will popup.

(to be concluded :D)

_________________
AHK is perfect.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 20th, 2008, 2:13 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
Da Rossa wrote:
your first code ... has a drawback: it slows down the past process. Also, it is impossible to have CTRL held down and pressing V repeated times to past repeated times, instead, your msgbox will popup.
Obviously you can't have Ctrl+V work immediately and allow it to be typed. That's just greedy. :P Of course, you could always avoid registering a hotkey for it, but then you'd get false positives like "fvf" = "ff".

Anyway, I am certain my other suggestion would solve the problem more completely.
I wrote:
Perhaps a better solution would be to check at each key-press whether the text matches part of a recognized command. If it does not, send what was typed and disable the hotkeys until Ctrl is pressed again.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 20th, 2008, 12:59 pm 
Offline

Joined: December 6th, 2007, 12:48 pm
Posts: 364
Although I'm still a primary newbie, I realize that using CTRL can be too hassling. what if I chose Shift instead? The intention is: Hold down shift, press some numbers on the numpad and release Shift to run the command, either launching a program, a file, or playing a macro, making something similar to some characters triggered by alt+169 for example. It even would be fancy, like those "alarm codes" you install in your houses for protection, isn't that cool? :P

However I still have to do some research before asking you further about this subject, I'm not following you. :(

Thanks anyway!

_________________
AHK is perfect.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 21st, 2008, 2:12 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
It's basically the same whatever keys you choose: on trigger-key press, enable the "code" hotkeys. When one is pressed, append the appropriate character to the string. On trigger-key release, do something with the string and disable the "code" hotkeys.

Unfortunately Shift + Numpad has a complication: Windows sends different key-codes for the numpad when you hold Shift. You'll never get +Numpad4, for example, only +NumpadLeft. This makes it slightly more complicated to build the "code" string.

Personally, I think Shift + Numpad is awkward. Numpad0 + Numpad1-9 makes more sense, since it can be used one-handed.

Anyway, this is roughly what I meant earlier (additions in dark red):
Code:
#UseHook  ; doesn't seem to work correctly without this?
words =  ; this should contain the list of valid command words
(
copy
paste
)


~Ctrl::
    ; Create/enable a hotkey for each letter of the alphabet.
    Loop 26
        Hotkey % "^" Chr(A_Index+96), Type, On
return
~Ctrl Up::
    Loop 26
        Hotkey % "^" Chr(A_Index+96), Type, Off

    if text
    {
        if RegExMatch(words, "m`n)^\Q" text "\E$")  ; if %text% matches a complete word
            MsgBox %text%
        else
            Send {Ctrl Down}%text%{Ctrl Up}
        text =
    }
return

Type:
    text .= SubStr(A_ThisHotkey,2)
    if ! RegExMatch(words, "m`n)^\Q" text "\E")  ; if no word begins with %text%
        goto ~Ctrl Up  ; end now
return
Basically, it stops accepting input as soon as it knows no word can match.

Regular expressions (RegExMatch) can be considered an advanced topic. There are other ways, but RegExMatch is probably the shortest.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 21st, 2008, 6:34 am 
Offline

Joined: December 6th, 2007, 12:48 pm
Posts: 364
Hum, let's say I understood 1% of it :D
How do I append the hotkeys I'm willing to set to your code?
The other problem is that I simply don't know most basic/fundamental concepts and definitions, aggravated by the fact that English is not my native language... what's, for example, a "hook"? :$

_________________
AHK is perfect.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 21st, 2008, 7:42 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
"Hook" may be defined as:
anything that catches; snare; trap.

In the context of AutoHotkey, it refers to the "keyboard hook", which is a feature of the Windows API; it "catches, snares or traps" keystrokes.

In this case, I use #UseHook as an alternative to manually prepending the $ modifier to each hotkey. Either one will force a hotkey to use the "keyboard hook", and as a side-effect prevent Send from triggering the hotkey.

All of the individual pieces of the script I posted are explained in the manual (which is of course written in English...)
Quote:
How do I append the hotkeys I'm willing to set to your code?

Code:
words =  ; this should contain the list of valid command words
(
copy
paste
ff
)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: January 29th, 2008, 4:32 am 
Offline

Joined: December 6th, 2007, 12:48 pm
Posts: 364
Thanks Lexikos...
But I have a better idea: I'm gonna read the entire help file, so that I can have a clue about those things. If there are other texts/articles/subjects that I should read prior to learning the AHK intermediates (I know the beginning of the introduction to basics), please let me know!

_________________
AHK is perfect.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: krajan, LazyMan, Leef_me, RaptorX, Yahoo [Bot] and 3 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group