How to trigger like text expander? (No shortcut)

Hints, tips and tricks for newbies

Moderators: Dorian (MJT support), JRL

Post Reply
Jedt3D
Newbie
Posts: 10
Joined: Mon Jul 04, 2016 5:50 am

How to trigger like text expander? (No shortcut)

Post by Jedt3D » Mon Jul 04, 2016 5:53 am

like...

typing "_ami" then expand/paste/type "Acute Myocardial Infarction"

I don't want to use short cut like Ctrl, Alt here.

If it's not possible can anybody suggest alternative way?

hagchr
Macro Veteran
Posts: 277
Joined: Mon Jul 05, 2010 7:53 am
Location: Stockholm, Sweden

Re: How to trigger like text expander? (No shortcut)

Post by hagchr » Mon Jul 04, 2016 10:15 am

Hi, If you need it for the common Microsoft apps (excel, word, powerpoint outlook etc) then you can easily set up an auto-correct that will do what you want (eg Word -> options -> Proofing -> Autocorrect Options and add it there, eg _ami=A...). You set it up in one and it can be picked up by the others. However, if you need it for other apps or you need to send it to other people then it will probably not work. (Not sure if there is a general Windows one?)

To set it up in MS for one replacement, eg _ami=A... is easy but I guess you are thinking of having a list with different keywords with different replacements?

Jedt3D
Newbie
Posts: 10
Joined: Mon Jul 04, 2016 5:50 am

Re: How to trigger like text expander? (No shortcut)

Post by Jedt3D » Mon Jul 04, 2016 12:56 pm

@hagchr Thank you very much. Let's me elaborate more about my specific needs.

I'm working in a hospital and wish to create this kind of auto expanded keywords around 1000+ of them. Like templates for diagnosis, shortcut for a long name etc.

They will be used across many applications mostly for medical related software. From native win32 app, java swing, web app, .net win app, many different origins.

So make it available globally should be the best way that doctors, nurses etc can be familiar with it.

For MS Office it is good for its own use.

hagchr
Macro Veteran
Posts: 277
Joined: Mon Jul 05, 2010 7:53 am
Location: Stockholm, Sweden

Re: How to trigger like text expander? (No shortcut)

Post by hagchr » Mon Jul 04, 2016 8:58 pm

Hi, Here an attempt for a solution to your question. I put in trigger words in a label at the end of the script, however, could easily be read from a file instead. The label now has garbage words from _am1 up to _am20. I tried to load 1000 words from a file and that seemed to work fine (however, remembering 1000 trigger words is a different thing...).

You can exit the script by simply pressing Shift+esc

I did it fairly quickly so if something looks strange or not as you were thinking then let me know. Hope it helps.

Code: Select all

Dialog>Dialog1
object Dialog1: TForm
  HelpContext = 5000
  BorderIcons = [biSystemMenu]
  Caption = 'CustomDialog'
  ClientHeight = 83
  ClientWidth = 264
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = True
  ShowHint = True
  OnTaskBar = False
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 48
    Top = 24
    Width = 3
    Height = 13
  end
end
EndDialog>Dialog1

//Show small dialog during loading
CODEBLOCK
    GetScreenres>x1,y1
    SetDialogProperty>Dialog1,,left,{(%x1%/2)-200}
    SetDialogProperty>Dialog1,,top,{(%y1%/2)-100}
    SetDialogProperty>Dialog1,Label1,Caption,Pls Wait - Loading!
    Show>Dialog1
ENDCODEBLOCK

//Initiate Variables and create/activate OnEvents
CODEBLOCK
//Basically, a number of onEvents are needed for all the keyboard keys that can be used for
//the trigger/keywords. The code is created by looping through all relevant keys
//using a template (in the label templateSRT below). The code is then included at runtime.

    //This variable will be used to build up the code needed for all onEvents (based on loop and template below)
    Let>SRTtoInclude=

    //Read the template to a variable
    LabelToVar>templateSRT,templateSRT

    //triggerActive is a variable to control if the onEvents are active or not.
    //triggerActive=TRUE means all onEvents are active and waiting for key input.
    Let>triggerActive=FALSE

    //Read the triggerlist to a variable. Triggerlist is the list with all the keyword and expanded words. This list 
    //can be read from the label below or from an external file (eg txt, dat, ini etc).
    LabelToVar>TriggerList,TriggerList
    //ReadFile>c:\...triggerfile.txt,TriggerList

    //Read VK list. This is an internal list of codes for each keyboard key.
    LabelToVar>VK,VKList
    Separate>VKList,%CRLF%,VKListItem
  
    //Create the code for all the OnEvents.
    Let>ctr=0
    While>ctr<VKListItem_COUNT
        Add>ctr,1
        Let>tmp=VKListItem_%ctr%
        Let>tmp0=\d{3}(?=,)
        RegEx>tmp0,%tmp%,0,mx,nmx,0
        Let>tmpx=mx_1
        OnEvent>KEY_DOWN,VK%tmpx%,0,KeyPress%tmpx%
        OnEvent>KEY_DOWN,VK%tmpx%,1,KeyPress%tmpx%
        Let>SRTtoInclude=%SRTtoInclude%%templateSRT%
    EndWhile

    //Include the onEvents code
    IncludeFromVar>SRTtoInclude

    //This onEvent is for when _ is pressed (ie shift+"-"). This will activate the onEvents>    
    OnEvent>KEY_DOWN,-,1,SRT_WasPressed
    
    SRT>SRT_WasPressed
        Let>triggerActive=TRUE
    END>SRT_WasPressed
        
    //This onEvent is for when the spacebar is pressed - this will trigger the search/replace.
    OnEvent>KEY_DOWN,VK32,0,SRTSpaceBarWasPressed

    //resFlag is a flag that will be set to TRUE when the spacebar is pressed and the search/replace should start
    Let>resFlag=FALSE
        
    SRT>SRTSpaceBarWasPressed
        If>triggerActive=TRUE
            Let>resFlag=TRUE
        Endif
    END>SRTSpaceBarWasPressed

    //keyOld will contain the last pressed key
    Let>keyOld=
    
    //buffer is like a buffer containing the keys pressed since the _
    //bufferVK is the buffer with VK codes
    Let>buffer=
    Let>bufferVK=
    
    //keycount keeps track of how many keys have been entered since the _
    Let>keycount=0
ENDCODEBLOCK

//Dialog will say the script is ready for input, then closed after 1 sec
CODEBLOCK
    SetDialogProperty>Dialog1,Label1,Caption,Ok Ready!
    Wait>1
    CloseDialog>Dialog1
ENDCODEBLOCK

//This is the main loop:
//--------------------------------------------------------------------
Label>Main
    //Check that both the spacebar has been pressed AND at least one key pressed since _     
    If>{(%resFlag%=TRUE) AND (%keycount%>0)}
        
        //Turn off the onEvent action and spacebar indicator temporary so that
        // there is no interference.
        Let>triggerActive=FALSE
        Let>resFlag=FALSE

        //This variable will contain the keys that have been pressed since _
        //Note - different from bufferVK which contains the VK codes for keys pressed.
        Let>buffer=
        
        //bufferVK contains the VK codes, three numbers for each key pressed. Use RegEx to
        get each 3 digit block into the array m (m_1, m_2, ...m_nm)
        RegEx>\d{3},bufferVK,0,m,nm,0
        
        //Loop throught the keys pressed and put together the word (between _ and spacebar)
        Let>ctrx=0
        While>ctrx<%keycount%
            Add>ctrx,1
            Let>tmp1=m_%ctrx%
            Let>tmp0=(?m-s)^%tmp1%,\K.+
            RegEx>tmp0,VKList,0,m2,nm2,0
            Let>tmp=m2_1
            Let>buffer=%buffer%%tmp%
        EndWhile

        //Then look up the word in the trigger list - the match will be in m3_1
        Let>tmp0=(?m-s)^%buffer%,\K.+
        RegEx>tmp0,TriggerList,0,m3,nm3,0
        
        //If there is a match in the trigger list then highlight the keyed in word and replace with 
        //the word from the trigger list.        
        If>nm3>0
            Press>Shift
                Press>Left*{%keycount%+2}
            Release>Shift
            SendText>m3_1
            Press>Space
        Endif

        //reset the buffers
        Let>buffer=
        Let>bufferVK=
        Let>keycount=0
        Wait>0.05
    Endif
Goto>Main
//--------------------------------------------------------------------

//SRT to check time since last key press and possibly add key to bufferVK
SRT>timecheck
    Let>timeNew=timecheck_VAR_1
    Let>timeOld=timecheck_VAR_2
    Let>tdiff={%timeNew%-%timeOld%}

    //There needs to be at least 15 msec since the
    //(same) number was previously pressed.
    //Can be modified/optimized.
    If>%tdiff%>15
        Let>bufferVK=%bufferVK%%keyNew%
        Add>keycount,1
    Endif
END>timecheck

//--------------------------------------------------------------------
//Template that will create an SRT for each number with onEvent
/*
templateSRT:
SRT>KeyPress%tmpx%
    If>triggerActive=TRUE
        Let>keyNew=%tmpx%

        If>keyNew<>keyOld
            Let>bufferVK=%bufferVK%%keyNew%
            Add>keycount,1
        Else
            Timer>currtime
            GoSub>timecheck,currtime,timeOld
        Endif

        Let>keyOld=keyNew
        Timer>timeOld
    Endif
END>KeyPress%tmpx%
*/

//Label with VK codes for all relevant keys
/*
VK:
048,0
049,1
050,2
051,3
052,4
053,5
054,6
055,7
056,8
057,9
065,A
066,B
067,C
068,D
069,E
070,F
071,G
072,H
073,I
074,J
075,K
076,L
077,M
078,N
079,O
080,P
081,Q
082,R
083,S
084,T
085,U
086,V
087,W
088,X
089,Y
090,Z
096,0
097,1
098,2
099,3
100,4
101,5
102,6
103,7
104,8
105,9
*/

//Here is the trigger list
/*
TriggerList:
am1,Acute Myocardial Infarction1
am2,Acute Myocardial Infarction2
am3,Acute Myocardial Infarction3
am4,Acute Myocardial Infarction4
am5,Acute Myocardial Infarction5
am6,Acute Myocardial Infarction6
am7,Acute Myocardial Infarction7
am8,Acute Myocardial Infarction8
am9,Acute Myocardial Infarction9
am10,Acute Myocardial Infarction10
am11,Acute Myocardial Infarction11
am12,Acute Myocardial Infarction12
am13,Acute Myocardial Infarction13
am14,Acute Myocardial Infarction14
am15,Acute Myocardial Infarction15
am16,Acute Myocardial Infarction16
am17,Acute Myocardial Infarction17
am18,Acute Myocardial Infarction18
am19,Acute Myocardial Infarction19
am20,Acute Myocardial Infarction20
*/

hagchr
Macro Veteran
Posts: 277
Joined: Mon Jul 05, 2010 7:53 am
Location: Stockholm, Sweden

Re: How to trigger like text expander? (No shortcut)

Post by hagchr » Mon Jul 04, 2016 9:29 pm

In the previous script I used SendText> to return the expanded text. When I read your other post about SendText> problems it struck me that another way could be to use the clipboard instead (ie put the result into the clipboard and then paste the result back). This is the same script as before except a few lines and using the Clipboard instead of SendText>. You can try what works best.

Code: Select all

Dialog>Dialog1
object Dialog1: TForm
  HelpContext = 5000
  BorderIcons = [biSystemMenu]
  Caption = 'CustomDialog'
  ClientHeight = 83
  ClientWidth = 264
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = True
  ShowHint = True
  OnTaskBar = False
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 48
    Top = 24
    Width = 3
    Height = 13
  end
end
EndDialog>Dialog1

//Show small dialog during loading
CODEBLOCK
    GetScreenres>x1,y1
    SetDialogProperty>Dialog1,,left,{(%x1%/2)-200}
    SetDialogProperty>Dialog1,,top,{(%y1%/2)-100}
    SetDialogProperty>Dialog1,Label1,Caption,Pls Wait - Loading!
    Show>Dialog1
ENDCODEBLOCK

//Initiate Variables and create/activate OnEvents
CODEBLOCK
//Basically, a number of onEvents are needed for all the keyboard keys that can be used for
//the trigger/keywords. The code is created by looping through all relevant keys
//using a template (in the label templateSRT below). The code is then included at runtime.

    //This variable will be used to build up the code needed for all onEvents (based on loop and template below)
    Let>SRTtoInclude=

    //Read the template to a variable
    LabelToVar>templateSRT,templateSRT

    //triggerActive is a variable to control if the onEvents are active or not.
    //triggerActive=TRUE means all onEvents are active and waiting for key input.
    Let>triggerActive=FALSE

    //Read the triggerlist to a variable. Triggerlist is the list with all the keyword and expanded words. This list 
    //can be read from the label below or from an external file (eg txt, dat, ini etc).
    LabelToVar>TriggerList,TriggerList
    //ReadFile>c:\...triggerfile.txt,TriggerList

    //Read VK list. This is an internal list of codes for each keyboard key.
    LabelToVar>VK,VKList
    Separate>VKList,%CRLF%,VKListItem
  
    //Create the code for all the OnEvents.
    Let>ctr=0
    While>ctr<VKListItem_COUNT
        Add>ctr,1
        Let>tmp=VKListItem_%ctr%
        Let>tmp0=\d{3}(?=,)
        RegEx>tmp0,%tmp%,0,mx,nmx,0
        Let>tmpx=mx_1
        OnEvent>KEY_DOWN,VK%tmpx%,0,KeyPress%tmpx%
        OnEvent>KEY_DOWN,VK%tmpx%,1,KeyPress%tmpx%
        Let>SRTtoInclude=%SRTtoInclude%%templateSRT%
    EndWhile

    //Include the onEvents code
    IncludeFromVar>SRTtoInclude

    //This onEvent is for when _ is pressed (ie shift+"-"). This will activate the onEvents>    
    OnEvent>KEY_DOWN,-,1,SRT_WasPressed
    
    SRT>SRT_WasPressed
        Let>triggerActive=TRUE
    END>SRT_WasPressed
        
    //This onEvent is for when the spacebar is pressed - this will trigger the search/replace.
    OnEvent>KEY_DOWN,VK32,0,SRTSpaceBarWasPressed

    //resFlag is a flag that will be set to TRUE when the spacebar is pressed and the search/replace should start
    Let>resFlag=FALSE
        
    SRT>SRTSpaceBarWasPressed
        If>triggerActive=TRUE
            Let>resFlag=TRUE
        Endif
    END>SRTSpaceBarWasPressed

    //keyOld will contain the last pressed key
    Let>keyOld=
    
    //buffer is like a buffer containing the keys pressed since the _
    //bufferVK is the buffer with VK codes
    Let>buffer=
    Let>bufferVK=
    
    //keycount keeps track of how many keys have been entered since the _
    Let>keycount=0
ENDCODEBLOCK

//Dialog will say the script is ready for input, then closed after 1 sec
CODEBLOCK
    SetDialogProperty>Dialog1,Label1,Caption,Ok Ready!
    Wait>1
    CloseDialog>Dialog1
ENDCODEBLOCK

//This is the main loop:
//--------------------------------------------------------------------
Label>Main
    //Check that both the spacebar has been pressed AND at least one key pressed since _     
    If>{(%resFlag%=TRUE) AND (%keycount%>0)}
        
        //Turn off the onEvent action and spacebar indicator temporary so that
        // there is no interference.
        Let>triggerActive=FALSE
        Let>resFlag=FALSE

        //This variable will contain the keys that have been pressed since _
        //Note - different from bufferVK which contains the VK codes for keys pressed.
        Let>buffer=
        
        //bufferVK contains the VK codes, three numbers for each key pressed. Use RegEx to
        get each 3 digit block into the array m (m_1, m_2, ...m_nm)
        RegEx>\d{3},bufferVK,0,m,nm,0
        
        //Loop throught the keys pressed and put together the word (between _ and spacebar)
        Let>ctrx=0
        While>ctrx<%keycount%
            Add>ctrx,1
            Let>tmp1=m_%ctrx%
            Let>tmp0=(?m-s)^%tmp1%,\K.+
            RegEx>tmp0,VKList,0,m2,nm2,0
            Let>tmp=m2_1
            Let>buffer=%buffer%%tmp%
        EndWhile

        //Then look up the word in the trigger list - the match will be in m3_1
        Let>tmp0=(?m-s)^%buffer%,\K.+
        RegEx>tmp0,TriggerList,0,m3,nm3,0
        
        //If there is a match in the trigger list then highlight the keyed in word and replace with 
        //the word from the trigger list.        
        If>nm3>0
            Press>Shift
                Press>Left*{%keycount%+2}
            Release>Shift
            
            PutClipBoard>m3_1
            Wait>0.05
            WaitClipBoard
            
            //SendText>m3_1
            Press>CTRL
                SendText>v
            Release>CTRL
            
            Press>Space
        Endif

        //reset the buffers
        Let>buffer=
        Let>bufferVK=
        Let>keycount=0
        Wait>0.05
    Endif
Goto>Main
//--------------------------------------------------------------------

//SRT to check time since last key press and possibly add key to bufferVK
SRT>timecheck
    Let>timeNew=timecheck_VAR_1
    Let>timeOld=timecheck_VAR_2
    Let>tdiff={%timeNew%-%timeOld%}

    //There needs to be at least 15 msec since the
    //(same) number was previously pressed.
    //Can be modified/optimized.
    If>%tdiff%>15
        Let>bufferVK=%bufferVK%%keyNew%
        Add>keycount,1
    Endif
END>timecheck

//--------------------------------------------------------------------
//Template that will create an SRT for each number with onEvent
/*
templateSRT:
SRT>KeyPress%tmpx%
    If>triggerActive=TRUE
        Let>keyNew=%tmpx%

        If>keyNew<>keyOld
            Let>bufferVK=%bufferVK%%keyNew%
            Add>keycount,1
        Else
            Timer>currtime
            GoSub>timecheck,currtime,timeOld
        Endif

        Let>keyOld=keyNew
        Timer>timeOld
    Endif
END>KeyPress%tmpx%
*/

//Label with VK codes for all relevant keys
/*
VK:
048,0
049,1
050,2
051,3
052,4
053,5
054,6
055,7
056,8
057,9
065,A
066,B
067,C
068,D
069,E
070,F
071,G
072,H
073,I
074,J
075,K
076,L
077,M
078,N
079,O
080,P
081,Q
082,R
083,S
084,T
085,U
086,V
087,W
088,X
089,Y
090,Z
096,0
097,1
098,2
099,3
100,4
101,5
102,6
103,7
104,8
105,9
*/

//Here is the trigger list
/*
TriggerList:
am1,Acute Myocardial Infarction1
am2,Acute Myocardial Infarction2
am3,Acute Myocardial Infarction3
am4,Acute Myocardial Infarction4
am5,Acute Myocardial Infarction5
am6,Acute Myocardial Infarction6
am7,Acute Myocardial Infarction7
am8,Acute Myocardial Infarction8
am9,Acute Myocardial Infarction9
am10,Acute Myocardial Infarction10
am11,Acute Myocardial Infarction11
am12,Acute Myocardial Infarction12
am13,Acute Myocardial Infarction13
am14,Acute Myocardial Infarction14
am15,Acute Myocardial Infarction15
am16,Acute Myocardial Infarction16
am17,Acute Myocardial Infarction17
am18,Acute Myocardial Infarction18
am19,Acute Myocardial Infarction19
am20,Acute Myocardial Infarction20
*/

Jedt3D
Newbie
Posts: 10
Joined: Mon Jul 04, 2016 5:50 am

Re: How to trigger like text expander? (No shortcut)

Post by Jedt3D » Tue Jul 05, 2016 4:31 pm

Hi @hagchr

I'm not sure if I miss a step or two. I copy your code and run it.
When I type _am1 follow by spacebar in WordPad, NotePad, it's not auto expand to the full word.

I have expected something like this.
Image

hagchr
Macro Veteran
Posts: 277
Joined: Mon Jul 05, 2010 7:53 am
Location: Stockholm, Sweden

Re: How to trigger like text expander? (No shortcut)

Post by hagchr » Tue Jul 05, 2016 7:58 pm

Hi, I am travelling today and tomorrow so do not have the pc here. On my machine I typed shift+ - (shift + hyphen) to get _. Did you do that or type _ directly? maybe need to change the code for the trigger?

Jedt3D
Newbie
Posts: 10
Joined: Mon Jul 04, 2016 5:50 am

Re: How to trigger like text expander? (No shortcut)

Post by Jedt3D » Wed Jul 06, 2016 2:25 am

Hi @hagchr

It's not working... well, until I carefully read your code comment..

Good thing
It's working on Win 7 32 bit.

My fault, really ashamed of mine.
My first post, I use "_ami" as my trigger
Yours use "_am1, _am2, .." as the griggers

I ran your code but I still type _ami1, _ami2 that's why it's not working...

Small pitfall may change your life forever.... hahaha

Thank you sooooo much hagchr.

Bad thing
It' not working on Win 10 64 bit. The script only be triggered by a shortcut.

I've tested with the latest trial version 14.3 but still not work. My version is Pro 14.2.02

MacroScheduler should have a simple way to do it though :)
Since Macro Toolworks can do it just a click...
Well, didn't use/buy it since it has no Unicode support and inactive forum.

hagchr
Macro Veteran
Posts: 277
Joined: Mon Jul 05, 2010 7:53 am
Location: Stockholm, Sweden

Re: How to trigger like text expander? (No shortcut)

Post by hagchr » Wed Jul 06, 2016 5:45 am

Hi, strange, I am using Win10 64bit and it works just fine on my machine... It was just a quick solution so one could obviously adjust it to whatever requirements needed. If you have the pro version of MS you can also compile the script to an .exe and start by icon, menu, dialog, or automatically (... the imagination part). Still, whatever solution you find in the end - good luck (and thanks for the question, it helped me think and solve some other problems in new ways).

Post Reply
Sign up to our newsletter for free automation tips, tricks & discounts