AutoHotkey is powerful free software you can use to control your computer and generate simple (or complex) macros to automate tedious or repetitive tasks.
For radiology, I consider the most important ability AHK enables is true hands-free dictation.
Ultimately, you can go crazy with this power, and it only takes a few minutes to learn how to use the software. The AHK website includes beginner tutorials and examples, and ChatGPT is even familiar enough with AHK scripting to get you most of the way. You don’t really need to understand very much in order to use it.
Randall Munroe, author of the always wonderful XKCD and Thing Explainer, illustrates why basically every radiologist should be doing this:
Please note that I am far from an expert on AHK or scripting in general. I started this journey in order to more effectively ditch the dictaphone, and–once I started–realized I also just dislike wasting my time.
I promise: The small investment in time and energy is absolutely worth it.
Context, Location, & Deployment
You create AutoHotkey scripts in a simple text file like Notepad (with the extension .ahk), and you launch the scripts by double-clicking the file on any computer with the free AutoHotkey software installed. The easiest way to create a new one is to right-click on the desktop or in a folder, mouse over “New,” and then select “Autohotkey Script.” To edit a script, right-click on it and select “Edit Script” or “Open with” -> Notepad.
In situations where you can’t install the AHK software, you can create a portable executable (.exe) file of a script you’ve already made through the right-click menu by clicking on the script file icon and selecting “Compile Script”). This means that if you can get that .exe file onto a work computer that generally doesn’t allow for software installation (via USB key, email, OneDrive, shared folder, etc.), you can often still run your personal productivity suite. Of course, begging IT is always an option, it will just take more doing. Note: You can’t edit the .exe files directly, so if you need to make changes, you’ll have to re-compile a new version.
Note that everyone’s combination of PACS, dictation software, and personal preferences is a little different, so it really is worth spending ten minutes to make sure you have the combination of features you want (and ideally the understanding of how to adjust them for troubleshooting).
I will include examples of the macros I use in this post as an illustration of some things you might want to do, explain how they work, and use them to teach you the basics of AHK’s very simple syntax. You can paste these into your own script and adjust if necessary.
At the end of the post, I will include several of the less idiosyncratic functions together into a complete script that you can just copy and paste as a starting point. It works for me in the contexts in which I work, but your mileage may vary. There are probably better ways for smarter people to accomplish similar tasks (remember: not an expert). Again, it’s absolutely worth reading this post (and probably others) to understand at least enough to tweak the hotkeys to your liking.
My context: In my practice, I currently use Powerscribe 360 for dictation, Intelliviewer for outpatient imaging, and GE Visage for hospital PACS.
Pair AHK with Better Input
Before we get in the weeds, please note that while you can create a robust number of macros that do a wide variety of things, the benefits of AutoHotkey for radiology really come alive when you combine AHK triggers with a more powerful/versatile input source like a gaming mouse and/ or a dedicated off-hand device like the Contour Shuttle Pro V2 (my choice), Razer Tartarus V2, or a one-hand macro keypad with onboard memory like the ELSRA Smart or offerings from KEEBMONKEY.
For example, this allows me to assign the trigger shortcuts for my macros to otherwise totally unused weird key combinations (e.g. ctrl+q, ctrl+alt+p) and then assign those combinations to a single mouse button or a button on my Shuttle. This leaves my typing experience completely normal in addition to a few other benefits we’ve discussed in a separate post. This is how I control dictation and several other features as well or better than I ever could have with the PowerMic. In practice, it means that I never hold a microphone and rarely need to touch my keyboard when reading routine cases.
Please see the equipment post for more discussion of productivity toy options.
Things You Might Try with AutoHotkey
Let’s illustrate how versatile, powerful, and helpful a few simple scripts can be to your workflow. If you want to just start and stop with hands-free dictation, that’s fine too.
PowerScribe Dictation Controls
In order to ditch the PowerMic and achieve seamless hands-free dictation, we need to be able to control dictation and template field navigation regardless of whether PowerScribe is the currently active application or just running in the background. Without AHK, you’ll need to either use voice controls (e.g. say “next field”) or click on the PowerScribe window first to make it active in order for it to respond to keyboard shortcuts. Neither is ideal.
But we can replicate the dictaphone functionality perfectly by using AHK to trigger the following simple sequence of two events: activate Powescribe, then toggle dictation/switch fields.
For reference, in PowerScribe 360, ‘F4’ toggles dictation, ‘TAB’ moves to the next dictation field, and ‘SHIFT+TAB’ goes to the previous field. The script looks like this:
`::
WinActivate, PowerScribe
Send, {F4}
Return
^`::
WinActivate, PowerScribe
Send, +{Tab}
Return
^1::
WinActivate, PowerScribe
Send, {Tab}
Return
In AHK, you put the trigger in the first line followed by two colons, then each command on its own line, ending the sequence with return. The WinActivate command changes the currently active application (we’ll discuss this more later). Send sends an input. In AHK scripting, the caret (^) means the CTRL key and the plus sign (+) means SHIFT. (!) is for Alt. The comma is optional.
So, in this example, the backtick (`) key toggles dictation, CTRL+` moves to the previous field, and CTRL+1 moves to the next field. I then map those combinations to buttons on my Shuttle. I never actually control these from the keyboard, though you certainly could.
A Pause Wrapper
Before we get into more examples, one thing you might want to do is create a trigger to manually turn the script on and off. This way, if you do use keys or key combinations that are necessary in some situations, you can pause the script. This is very helpful if you plan to use regular keyboard keys instead of a dedicated productivity mouse or off-hand device, or when you want to change the keymapping on one of those devices when the script is already running.
As in: You could set yourself up to turn the script on and off with a rarely used key like the backtick (the one beneath the escape key to the left of 1), just use single keystrokes to control all your favorite macros, and then toggle the script whenever you want to actually type something.
The way I have my script set up is that the top of the script contains the following:
; Set the initial state of the script to active
isActive := true
; Define the hotkey combination to toggle the script
^!p:: ; Ctrl + Alt + P
isActive := !isActive ; Toggle the state
if (isActive)
MsgBox Script is now active.
else
MsgBox Script is now paused.
return
; Optionally, any script code here will always be active
#If (isActive)
; Place all of your actual script code here.
#If
This toggles the script on/off through the shortcut CTRL+ALT+P (P was chosen for “Pause”). In AHK, semicolons precede comments, which are just to make things readable but do not affect functionality.
Powerscrolling
If your PACS requires you to hold the mouse button down to power scroll, that can wreak havoc on your index finger over a long shift. This script maps the backslash to a “click-lock” that toggles between holding the left mouse button down and releasing it.
;toggle holding down the left mouse button
\::
alt := not alt
if (alt)
{
Click Down
}
else
{
Click Up
}
Return
Remove Annoying Double Periods and Double Spaces
One of my favorite functions is cleaning up reports with a series of find-and-replace functions in PowerScribe to remove double spaces between words and double periods. Keeping them in your reports is common but sloppy. Hunting for them and removing them manually is grossly inefficient.
^q::
WinActivate, PowerScribe
Send ^h
Sleep, 100
Send ..
Send {tab}
Send .
Send {tab} {tab} {tab}
Send {Enter}{Escape}{Escape}{Escape}
Send ^h
Sleep, 100
Send {space}{space}
Send {tab}
Send {space}
Send {tab} {tab} {tab}
Send {Enter}{Escape}{Escape}
Send ^h
Sleep, 100
Send {space}.
Send {tab}
Send .
Send {tab} {tab} {tab}
Send {Enter}{Escape}{Escape}{Escape}
return
The Sleep function is a forced delay (in milliseconds); it gives the application a chance to complete the previous command before inputting the next. Depending on the speed of your system and the applications you’re using, you may need more and longer delays between steps (seriously).
This script opens the Find & Replace window in PowerScribe and puts in a whole bunch of inputs in sequence to navigate through the menu and get rid of (respectively): two periods in a row, two spaces in a row, and a space before a period (‘ .’). You could easily add more variants like double commas, but these three automatically do the majority of polishing you could want.
We all know PowerScribe should do this automatically.
Searching Radiopaedia
Here’s another fun one. Let’s say you want to be able to search Radiopaedia faster (perhaps when you see a disease you don’t recognize in the EMR, something else typed into the history, a phrase from the comparison, or even just a few words you’ve specifically put into your own report to use this shortcut):
; Pressing Ctrl+Alt+R will copy the selected text to the clipboard and search Radiopaedia
^!r::
; Copy the selected text to the clipboard
SendInput, ^c
ClipWait
; Build the search URL for Radiopaedia
search_url := "https://radiopaedia.org/search?utf8=✓&q=" . UrlEncode(Clipboard)
; Open the search results in the default browser
Run %search_url%
return
; Custom UrlEncode function
UrlEncode(str)
{
static chars := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~"
encoded := ""
loop, parse, str
{
char := asc(A_LoopField)
; If the character is in the allowed set, keep it as is; otherwise, encode it
if (char >= 0x20 && char <= 0x7E && instr(chars, A_LoopField))
encoded .= A_LoopField
else
encoded .= "%" . format("{:02X}", char)
}
return encoded
}
Highlight some text and trigger this macro, and AHK will copy the text string to the clipboard and then search Radiopaedia for it.
Don’t worry about how we build the URL for searching Radiopaedia. It’s just an illustration, and it’s the kind of thing that’s partially unique to each site (the encoding function itself you can find online or make with ChapGPT).
SendInput is a more specific version of Send for inputting keystrokes and mouse clicks; either version will work for our purposes in all of these examples, and technically SendInput is actually faster and generally preferred for most processes. I’ve found it’s sometimes too fast and requires adding Sleep commands after to give programs time to respond. Feel free to try SendInput in your own scripts, and if things are too instantaneous, you can try switching commands or adding in the delays.
The one other command here you might want to know is ClipWait, which waits for text copied via Ctrl+C to be saved to memory before using it somewhere else. On some computers, I’ve found adding an additional short Sleep command after copying the text is still necessary as a buffer to make sure it works properly.
Macros for Common Exams
Obviously, you’ve been using voice commands in PowerScribe to use templates or other blocks of text, but if there are certain things you do dozens of times per day (e.g. insert normal chest radiograph), a button can be even more frictionless. (I don’t actually do this, but I know others who do).
AutoCorrection and Text Expansion
AHK lets you create your own version of AutoCorrect like on your phone via hotstrings. The syntax is easy.
; autocorrect examples
::teh::the
::dont::don't
::cant::can't
; text expansion is the same idea
::btw::by the way
Note this only works with typed text and not what PowerScribe transcribes. To make PowerScribe itself suck less, please see this post: Making the Most of PowerScribe.
More on hotstrings here. That page also includes this link to a fantastic AHK script that will automatically replace 4700 common English misspellings on the fly and has a built-in function to add more whenever you want by pressing Win+H. No reason to reinvent the wheel!
If you find yourself typing the same things frequently, text expansion can save you buckets of time (especially for emails).
Opening Up Frequently Used Websites
If there are certain websites you always open when you start your shift, you could create a macro to open them up all at once in the default browser:
^!t::
Run, https://gmail.com/
Run, https://mail.live.com/
Run, https://radiopaedia.org/
Run, https://www.imaios.com/en/e-anatomy
return
Creating Your Own Login Scripts
Another example would be making your own single sign-on when these processes have not already been bundled effectively by launching various programs using the Run command and then logging in to each as needed. It’ll take some trial and error to see how to navigate through the input fields and Sleeps to get the delays right.
Use Your Imagination
What repetitive tasks are sources of frustration in your day? How about getting through the multiple input fields needed to mark a case “correct” for peer review in PowerScribe? Even if the total time saved is minimal, sometimes just the reduced friction has a meaningful cognitive/psychological benefit.
To give you an idea of the coolness/creativity that’s possible, check out the Radiology Right Click script by Magnetron85, which bakes a bunch of formulas/calculators into a right-click menu that you use with highlighted text in PowerScribe.
I’ll give you two very idiosyncratic ones I use when reading for our hospital that may not apply to you but further illustrate the kind of approach you can use to spark your own joy.
AutoDelete BS Verbiage
Our hospital PowerScribe instance puts in a useless “dose reduction” paragraph in every CT report for MIPS/billing reasons. But, all of the templates we use include the text already in the technique field. So either you delete it every single time, or the duplicate stays at the bottom of the report distracting from your impression. Yuck.
^3::
WinActivate, PowerScribe
Send ^a
Send {delete}
Send {F4}
Return
In this quick macro, CTRL+3 (mapped to a button on my Shuttle) activates Powerscribe, highlights all of the current text, deletes it, and turns on dictation. I press it whenever I open up a new case.
Poor Man’s EMR Integration
At the hospital, we have EMR integration so that Epic loads the patient chart automatically when you open a case from the worklist. At home, no dice. Opening up charts manually is a huge waste of time and requires a whole bunch of clicks and keystrokes.
If in your practice you are forced to manually input MRNs or Accession numbers to look up patient information, you need to adopt a version of this.
^4::
SendInput, ^c
ClipWait
Sleep, 100
WinActivate, ahk_exe WFICA32.EXE
Send ^2
Sleep, 300
Send ^v
Sleep, 100
Send {Enter}
Sleep, 200
Send {Enter}
Return
In our worklist, I double-click on the accession number to highlight the number. I then activate this macro (through a button on my shuttle, which inputs CTRL+4), which copies the number, switches to Epic, opens the “Study Review” window, pastes the number, and hits {Enter} a couple of times to finish the process. Voila, a chart opened with a mouse click and a single button press. (Note: This exact script will almost certainly not work for you.)
Should I even have to do this? Of course not. Is this better than what I used to do? Absolutely.
Troubleshooting Scripts
Potentially tons to unpack on this dimension, but I want to discuss two common pitfalls I’ve found when working with AHK to control my computer:
Application Selection
When it comes to controlling your computer, one of the key commands is WinActivate. AHK comes with a helpful but scarily-named helper program called “Windowspy” that allows you to see information about active processes. When running Windowspy, you can see the name of the active program and other information that can be important for isolating features you need to make your scripts work.
If you want to use the WinActivate command to switch applications, you can find and copy the specific application title from there. Note that this isn’t always strictly necessary; it depends on how unique and consistent the title is. I have found that a simple “Powerscribe” is enough of a title. But, if I want to activate Epic running through an instance of Citrix, I need either the complete title (which for our instance changes with every login–annoying) or one of the alternative AHK WinActivate variants/variables identifiable through Windowspy (ahk_class, ahk_exe, ahk_pid).
Again, don’t be discouraged by needing some trial and error.
You can read more about WinActivate here.
Incomplete Macro Execution
If you find that a particular macro doesn’t seem to work consistently or cuts off in the middle, consider adding or lengthening the “sleeps” in between steps. You need to delay long enough for the last input to take effect. In my experience, the necessary delay for things like my punctuation macro varies with computer speed.
When our hospital “upgraded” to a new version of Epic, I had to more than double the delay steps in my DIY Epic Integration.
Conclusion
To reiterate, you’ll map these macros to your choice of underutilized keyboard keys or key combinations, and then as an optional step, you can map those triggers to the buttons on your magical device like a Shuttle or gaming mouse. I cannot stress how good these combinations work and feel.
Other than hands-free dictation, are most of these things a big deal? Not at all. They’re minor pain points. But they’re fixable, and removing these little bits of friction is awesome.
Just because the cost of inaction is invisible doesn’t mean it’s not real.
You can absolutely figure out what you want and how to do it.
Here’s a take-home script example you can use as a starting point that includes the dictation controls and the double space/period removal wrapped in the pause function.
(Okay, one more final point: many older scripts and examples online (including this one) use the mostly unchanged but slightly older syntax of AHK Version 1.1. There is now a 2.0 version. When you try to run a script using the older syntax, AutoHotkey will simply offer to download the older version. That’s 100% okay. They both work fine.)
; Set the initial state of the script to active
isActive := true
; Define the hotkey combination to toggle the script
^!p:: ; Ctrl + Alt + P
isActive := !isActive ; Toggle the state
if (isActive)
MsgBox Script is now active.
else
MsgBox Script is now paused.
return
; Place your always-on script code here
; Example hotkeys that are only active when the script is active
#If (isActive)
; toggle dictation
`::
WinActivate, PowerScribe
Send, {F4}
Return
; previous field
^`::
WinActivate, PowerScribe
Send, +{Tab}
Return
;next field
^1::
WinActivate, PowerScribe
Send, {Tab}
Return
; CTRL+q to remove extra spaces and periods
^q::
WinActivate, PowerScribe
Send ^h
Sleep, 100
Send ..
Send {tab}
Send .
Send {tab} {tab} {tab}
Send {Enter}{Escape}{Escape}{Escape}
Send ^h
Sleep, 100
Send {space}{space}
Send {tab}
Send {space}
Send {tab} {tab} {tab}
Send {Enter}{Escape}{Escape}
Send ^h
Sleep, 100
Send {space}.
Send {tab}
Send .
Send {tab} {tab} {tab}
Send {Enter}{Escape}{Escape}{Escape}
return
#If
Automate away, folks.
26 Comments
Thank you! I have been waiting for this!!!
thanks for this, got me pushed into going hands free
a note, these scripts don’t work in the 2.0 version I guess they changed the scripting language. I initially tried 2.0 and gave up, went back to the 1.1 and things working good so far
2.0 must be kinda new, other tutorial videos I’ve watched seem to reference the 1.X scripting conventions
Yes, I mentioned that at the end. Things work just fine in the old version, and–as you noted–most examples online still use the old syntax as well, so I personally haven’t felt the need to revise and update.
no one ever reads to the very end ;)
check out the X-keys keypads as another left hand device for folks that don’t want the wheel / scroll function. Lots of buttons packed in and good software and on board memory if you’re not getting too complex with key functions
If anyone has done a compare/contrast between x-keys and the cheaper options like those from other companies like the ones I’ve linked to above, let me know.
I just bought the contour last week. I downloaded the contour driver and the autohotkey app. And everything is working on my home computer.
Im going to try it at work tomorrow. I assume this will only work if my work computer allows me to download the contour driver and the autohotkey app?
Yes, you need to be able to install the contour shuttle driver. Usually most IT departments are willing to install software to manage hardware peripherals.
For AHK, see the above discussion. You can install the software and run the scripts as normal, or you can try to compile your script at home into an .exe file and then bring it over via a usb key, onedrive, a shared drive folder, or whatever is allowed. Depends on your local security situation, but you can often run that even in situations where you can’t install software because the permissions for installation and for execution are different. Most places only need an administrator login/password for installation.
Great article! Another script that I’ve found helpful is to have a button to automatically push the current study into PowerScribe – some places may have this automatically happen via their worklist manager, but our Epic-driven worklists force us to click the “Dictate” button in Epic. To avoid that, I use the script below so that clicking NumLock will launch the current study in PowerScribe to have it ready to dictate.
NumLock::Epic_Dictate()
Epic_Dictate()
{
WinActivate Hyperspace
Send !d
}
Came back to this page to steal some more of your script snippets and realized you were using a more complex method of making the script active/inactive. You can also easily do this just by adding something like
^!p::Suspend
That simple line would use your ctrl-alt-p to “suspend” the whole script so you could use the keys normally. It also has a nice benefit of changing the AHK icon from an H to an S to give a subtle visual that your script is suspended.
Another nice benefit is for when you have a specific key (or combination) mapped to your script, but it’s also needed as a hotkey within a specific application. E.g. What if you wanted to make “F4” a global hotkey to toggle dictation in PS off/on. You’d use something like the below to suspend and then un-suspend the capture of “F4” so that the key does its original purpose instead of just re-triggering the script ad infinitum.
{F4}::
WinActivate PowerScribe
Suspend
Send {F4}
Suspend
Return
Suspend does look more elegant. I’m sure there are better ways to do a lot of what I’ve been using for those more savvy than I am!
I’ve had the hardest time figuring out how to get AHK to work for Philips speechmike. Anyone out there have some success and willing to share their script?
Nice blog! I’ve been using AHK in radiology for years. I want to emphasize using ChatGPT 4 (not free 3.5) for script generation–it’s next level. Like with any coding, it can help you do things an order of a magnitude faster, with annotated scripts. Or, it can allow you to do things you never would have attempted because it would have been too complex or time consuming. Just make sure to tell the AI whether you use AHK 1.1 or 2.0.
Absolutely, the AI tools are really very helpful here.
Try hyponyms and you will get the best of hands free dictation, speed and accuracy. I see current AI making all these tasks mainstream but the excitement will be with conversational AGI reporting and interpretation.
http://www.hyponym.org
I find that it is preferable for AHK scripts to speak to powerscribe via ControlSend and ControlClick commands, which enables powerscribe to remain as a non-active window, and keeps the focus on PACS so your scrolling is not interrupted. For example, my dictaphone control script works by sending controlclick to the coordinate of the red circle “mic on” button in the powerscribe toolbar.
Another very useful script is to be able to pick picklist items with a button press. My contour shuttle pro’s top row is programmed to pick picklist items 1-4 (and 5-8 with a combo press modifier key). This can be done using postmessage to send a double click to the class NN of the picklist listbox targeting the coordinate of the picklist item (with respect to the top left corner of the listbox).
Both of my PACS still scroll when not the active window so WinActivate has no detrimental effects for my usage, but that’s a good tip for anyone else potentially struggling with that problem.
If you want to drop the script examples for those to illustrate, I’m sure a future reader will be grateful.
bump! need these scripts!
AHK is awesome. Thanks for the script for tidying up powerscribe.
I have a logitech g600 with each key mapped to F13-F24. I pair the extended F keys with AHK to minimize interference with Windows and program specific key combinations.
Some of my favorite scripts are:
Toggling between windows desktops (you need to have the extra desktop already created first though). I have these mapped to Mouse wheel right and left respectively.
^F23::
SetKeyDelay, 100
Sendinput, {LWin Down}{Ctrl down}{Left down}{Left up}{Ctrl up}{Lwin up}
Return
^F24::
SetKeyDelay, 100
Sendinput, {LWin Down}{Ctrl down}{Right down}{Right up}{Ctrl up}{Lwin up}
Return
My other favorite script automatically expands the image viewer to the size of my diagnostic monitor and then arranges powerscribe and other windows on my non diagnostic monitor. I do have to make a quick edit to the script if I change workstations but it only takes 30 seconds. It could be condensed
This script assumes you have 1 non diagnostic monitor and that your diagnostic monitor counts as two monitors (ie Barcos).
;————–workstation #1
SysGet, MonA, MonitorWorkArea, 3
SysGet, MonB, MonitorWorkArea, 1
SysGet, MonC, MonitorWorkArea, 2
Global MonAW := MonARight – MonALeft
Global MonAH := MonABottom – MonATop
Global MonBW := MonBRight – MonBLeft
Global MonBH := MonBBottom – MonBTop
Global MonCW := MonCRight – MonCLeft
Global MonCH := MonCBottom – MonCTop
Global DiagMonitorLeft := MonBLeft
Global DiagMonitorRight := MonCRight
Global DiagMonitorTop := MonBTop
Global DiagMonitorBottom := MonBBottom
Global DiagMonitorWidth := MonCRight – MonBLeft
Global NonDiagMonitorLeft := MonALeft
Global NonDiagMonitorRight := MonARight
Global NonDiagMonitorTop := MonATop
Global NonDiagMonitorBottom := MonABottom
Global NonDiagMonitorWidth := MonAW
Global NonDiagMonitorHeight := MonAH
Global DiagMonitorHeight := MonBH
;—–normal——–derived desktop variables————–STATIC—-
Global DiagMonitorOneFourthWidth := (DiagMonitorWidth)*(1/4)
Global DiagMonitorOneThirdWidth := (DiagMonitorWidth)*(1/3)
Global DiagMonitorOneHalfWidth := (DiagMonitorWidth)*(1/2)
Global DiagMonitorTwoThirdsWidth := (DiagMonitorWidth)*(2/3)
Global DiagMonitorThreeFourthsWidth := (DiagMonitorWidth)*(3/4)
Global DiagMonitorMiddle := DiagMonitorLeft + DiagMonitorOneHalfWidth
Global DiagMonitorOneFourthHeight := (DiagMonitorHeight)*(1/4)
Global DiagMonitorOneThirdHeight := (DiagMonitorHeight)*(1/3)
Global DiagMonitorOneHalfHeight := (DiagMonitorHeight)*(1/2)
Global DiagMonitorTwoThirdsHeight := (DiagMonitorHeight)*(2/3)
Global DiagMonitorThreeFourthsHeight := (DiagMonitorHeight)*(3/4)
Global NonDiagMonitorOneFourthWidth := NonDiagMonitorWidth*(1/4)
Global NonDiagMonitorOneHalfWidth := NonDiagMonitorWidth*(1/2)
Global NonDiagMonitorOneThirdWidth := NonDiagMonitorWidth*(1/3)
Global NonDiagMonitorTwoThirdsWidth := NonDiagMonitorWidth*(2/3)
Global NonDiagMonitorThreeFourthsWidth := NonDiagMonitorWidth*(3/4)
Global NonDiagMonitorOneFourthHeight := NonDiagMonitorHeight*(1/4)
Global NonDiagMonitorOneHalfHeight := NonDiagMonitorHeight*(1/2)
Global NonDiagMonitorOneThirdHeight := NonDiagMonitorHeight*(1/3)
Global NonDiagMonitorTwoThirdsHeight := NonDiagMonitorHeight*(2/3)
Global NonDiagMonitorThreeFourthsHeight := NonDiagMonitorHeight*(3/4)
;————-Desktop 1 Variables————————
Global PowerJacketWinX := NonDiagMonitorLeft – NonDiagMonitorWidth*0.00195
Global PowerJacketWinY := NonDiagMonitorTop
Global PowerJacketWinH := NonDiagMonitorHeight
Global PowerJacketWinW := NonDiagMonitorWidth*0.31
Global CentricityWinX := PowerJacketWinX + PowerJacketWinW – NonDiagMonitorWidth*0.0057
Global CentricityWinY := NonDiagMonitorTop
Global CentricityWinH := NonDiagMonitorHeight*0.97
Global CentricityWinW := NonDiagMonitorWidth*0.28
Global PowerScribeWinX := CentricityWinX + CentricityWinW – NonDiagMonitorWidth*0.005
Global PowerScribeWinY := NonDiagMonitorTop
Global PowerScribeWinH := NonDiagMonitorHeight
Global PowerScribeWinW := NonDiagMonitorWidth*0.395
Global WorklistWinX := DiagMonitorLeft – DiagMonitorLeft*.003
Global WorklistWinY := DiagMonitorTop – DiagMonitorHeight*0.01
Global WorklistWinW := DiagMonitorWidth*1.007
Global WorklistWinH := DiagMonitorHeight*1.02
Global ViewerWinX := DiagMonitorLeft – DiagMonitorLeft*.003
Global ViewerWinY := DiagMonitorTop + DiagMonitorHeight*0.01
Global ViewerWinW := DiagMonitorWidth*1.007
Global ViewerWinH := DiagMonitorHeight*1.00
;—————————–User defined functions for desktop 1 —————————
PowerScribePosition(){
WinActivate, Nuance
WinWait, Nuance
WinMove, Nuance PowerScribe One,, PowerScribeWinX, PowerScribeWinY, PowerScribeWinW, PowerScribeWinH
Sleep, 100
}
PowerJacketPosition(){
WinActivate, PowerJacket
WinMove,, PowerJacket, PowerJacketWinX, PowerJacketWinY, PowerJacketWinW, PowerJacketWinH, One
Sleep, 100
}
CentricityPosition(){
WinActivate, Centricity
WinMove,, Centricity, CentricityWinX, CentricityWinY, CentricityWinW, CentricityWinH
Sleep, 100
}
WorklistPosition(){
WinActivate, Worklist
WinMove,, Worklist, WorklistWinX, WorklistWinY, WorklistWinW, WorklistWinH, Nuance
Sleep, 100
}
ViewerPosition(){
WinActivate, Viewer
WinMove,, Viewer, ViewerWinX, ViewerWinY, ViewerWinW, ViewerWinH, Nuance
Sleep, 100
}
RestoreWindowsFirstDesktop(){
WinGet, WinList, List
Loop % WinList {
WinGet, WinState, MinMax, % “ahk_id ” WinList%A_Index%
WinGetTitle, Title, % “ahk_id ” WinList%A_Index%
if (WinState = -1 && InStr(Title, “Worklist”))
{
WinRestore, % “ahk_id ” WinList%A_Index% ; Restore the window by its ID
}
if (WinState = -1 && InStr(Title, “PowerScribe”))
{
WinRestore, % “ahk_id ” WinList%A_Index% ; Restore the window by its ID
}
if (WinState = -1 && InStr(Title, “Centricity”))
{
WinRestore, % “ahk_id ” WinList%A_Index% ; Restore the window by its ID
}
if (WinState = -1 && InStr(Title, “Viewer”))
{
WinRestore, % “ahk_id ” WinList%A_Index% ; Restore the window by its ID
}
if (WinState = -1 && InStr(Title, “PowerJacket”))
{
WinRestore, % “ahk_id ” WinList%A_Index% ; Restore the window by its ID
}
}
sleep, 100
}
OrganizeDesktop1(){
RestoreWindowsFirstDesktop()
PowerScribeInitiate()
SynapseWorklistInitiate()
PowerScribePosition()
WorklistPosition()
ViewerPosition()
PowerJacketPosition()
CentricityPosition()
}
PrintScreen::
OrganizeDesktop1()
Return
Another great script toggles between the worklist and viewer per key press.
WorkListViewerCentricityToggle()
{
if WinActive(“Worklist”)
{
if WinExist(“Viewer”,,”Series”)
{
WinActivate, Viewer
WinActivate, Centricity
WinActivate, Powerscribe
WinActivate, Powerjacket
}
}
else {
WinActivate, Worklist
}
}
F13::
WorkListViewerCentricityToggle()
Return
Just getting started with AHK. If I could have dreamed up the perfect article to get started, with a few specific examples of things I wanted to do, this would be the exact article. Thank you so much for this valuable resource.
Thank you, glad to hear it!
Thanks for the excellent overview.
I have used AHK for dictation efficiency with PS 360 in the past. I never figured out how to toggle PS forward/back (visible/ behind other windows ie epic, powerjacket, etc).
I am moving to a new full time gig with PS one and philips intellispace pacs. Anyone have high yield scripts built for either?
thanks