AutoHotKey: move to next program when press a key - autohotkey

For example, I have Notepad, Word, and Chrome open. How do I write the script in AutoHotKey such that when I press the F9 key on the keyboard, it will move to the next application?

Try:
AltTab_ID_List_ := []
setTimer, updateList, 100
+f9::WinActivate, % "AHK_ID" AltTab_ID_List_[(pointer == 1 or pointer == 0
? AltTab_ID_List_.Count()-1 : --pointer)]
f9::WinActivate, % "AHK_ID" AltTab_ID_List_[++pointer]
updateList:
list := AltTab_window_list()
if (AltTab_ID_List_.MaxIndex() != list.MaxIndex())
AltTab_ID_List_ := list
cur:=WinExist("A")
for e, v in AltTab_ID_List_
if (cur == v)
pointer := AltTab_ID_List_.MaxIndex() == e ? 0 : e, break
return
AltTab_window_list()
{
WS_EX_CONTROLPARENT =0x10000
WS_EX_APPWINDOW =0x40000
WS_EX_TOOLWINDOW =0x80
WS_DISABLED =0x8000000
WS_POPUP =0x80000000
AltTab_ID_List_ := [] ;AltTab_ID_List_ =0
WinGet, Window_List, List ; Gather a list of running programs
id_list =
Loop, %Window_List%
{
wid := Window_List%A_Index%
WinGetTitle, wid_Title, ahk_id %wid%
WinGet, Style, Style, ahk_id %wid%
If ((Style & WS_DISABLED) or ! (wid_Title)) ; skip unimportant windows ; ! wid_Title or
Continue
WinGet, es, ExStyle, ahk_id %wid%
Parent := Decimal_to_Hex( DllCall( "GetParent", "uint", wid ) )
WinGetClass, Win_Class, ahk_id %wid%
WinGet, Style_parent, Style, ahk_id %Parent%
If ((es & WS_EX_TOOLWINDOW)
or ((es & ws_ex_controlparent) and ! (Style & WS_POPUP) and !(Win_Class ="#32770") and ! (es & WS_EX_APPWINDOW)) ; pspad child window excluded
or ((Style & WS_POPUP) and (Parent) and ((Style_parent & WS_DISABLED) =0))) ; notepad find window excluded ; note - some windows result in blank value so must test for zero instead of using NOT operator!
continue
AltTab_ID_List_.push(wid)
}
return AltTab_ID_List_
}
Decimal_to_Hex(var)
{
SetFormat, integer, hex
var += 0
SetFormat, integer, d
return var
}

I changed the "errorseven" code for better performance (removing the update timer from the list) and usability
!WheelDown::
gosub UpdateWindowsList
Item_ID_List.Push(Item_ID_List.RemoveAt(1))
gosub PrintList
WinActivate, % "AHK_ID" Item_ID_List[1]
return
!WheelUp::
gosub UpdateWindowsList
Item_ID_List.InsertAt(1, Item_ID_List.Pop())
gosub PrintList
WinActivate, % "AHK_ID" Item_ID_List[1]
return
; Update list order
!MButton::
Item_ID_List := Get_Windows_List()
return
UpdateWindowsList:
New_Item_ID_List := Get_Windows_List()
FirstNow := New_Item_ID_List[1]
; Checks if the active program was already on the old list
for index, value in Item_ID_List {
if (value = FirstNow)
break
}
; If the active program is not at the beginning of the list, bring it to the beginning
if (value = New_Item_ID_List[1]) {
while(FirstNow != Item_ID_List[1]) {
RemovedValue := Item_ID_List.RemoveAt(1)
Item_ID_List.Push(RemovedValue)
}
}
; Delete closed items from the old list
TempArray := []
for index, value in Item_ID_List {
for index2, value2 in New_Item_ID_List {
if (value = value2) {
TempArray.push(New_Item_ID_List.RemoveAt(index2))
break
}
}
}
; Updates the old list with new open programs
for index2, value2 in New_Item_ID_List {
TempArray.push(value2)
}
Item_ID_List := TempArray
; If the active program is not at the beginning of the list, bring it to the beginning
while(FirstNow != Item_ID_List[1]) {
RemovedValue := Item_ID_List.RemoveAt(1)
Item_ID_List.Push(RemovedValue)
}
return
Get_Windows_List()
{
WS_EX_CONTROLPARENT =0x10000
WS_EX_APPWINDOW =0x40000
WS_EX_TOOLWINDOW =0x80
WS_DISABLED =0x8000000
WS_POPUP =0x80000000
AltTab_ID_List := [] ;AltTab_ID_List =0
WinGet, Window_List, List ; Gather a List of running programs
id_List =
Loop, %Window_List%
{
wid := Window_List%A_Index%
WinGetTitle, wid_Title, ahk_id %wid%
WinGet, Style, Style, ahk_id %wid%
if ((Style & WS_DISABLED) or ! (wid_Title)) ; skip unimportant windows ; ! wid_Title or
Continue
WinGet, es, ExStyle, ahk_id %wid%
Parent := Decimal_to_Hex( DllCall( "GetParent", "uint", wid ) )
WinGetClass, Win_Class, ahk_id %wid%
WinGet, Style_parent, Style, ahk_id %Parent%
if ((es & WS_EX_TOOLWINDOW)
or ((es & ws_ex_controlparent) and ! (Style & WS_POPUP) and !(Win_Class ="#32770") and ! (es & WS_EX_APPWINDOW)) ; pspad child window excluded
or ((Style & WS_POPUP) and (Parent) and ((Style_parent & WS_DISABLED) =0))) ; notepad find window excluded ; note - some windows result in blank value so must test for zero instead of using NOT operator!
continue
AltTab_ID_List.push(wid)
}
return AltTab_ID_List
}
Decimal_to_Hex(var)
{
Setformat, integer, hex
var += 0
Setformat, integer, d
return var
}
PrintList:
names =
for index, value in Item_ID_List {
WinGetTitle, OutputVar , AHK_ID %value%
frase = % "Item " index " is '" OutputVar "'"
names = %names%%frase%`n
}
ToolTip, %names%
SetTimer, RemoveToolTip, -1000
return
RemoveToolTip:
ToolTip
return

Related

How to reset a key sequence with a specific key?

So this sequence resets itself after 1.5 sec (t:=1500) which means if i dont hit the left mouse button for 1.5 sec it always sends A. Otherwise it sends the next letter after each click.
I want to further tweak this code with another function which is to be able to reset the sequence with right mouse button too. So if i hit RButton any time it should reset to A.
Thx.
global s:=0, c:=0, t:=1500
*LButton::
Send % Seqkeys("A","B","C")
KeyWait, LButton
Send, R
return
Seqkeys(params*) {
global s, c, t
max := params.MaxIndex()
(A_TickCount-s<=t && (c+=1)<=max) ? c : c:=1
s := A_TickCount
return params[c]
}
Merely reset the current key index 'c', and the last clicked time 's':
*RButton::
c := 1
s := 0
return
I think your script would benefit with more meaningful variable names:
global lastClickedTime:=0, currentKeyIndex:=0, clickThreshold:=1500
*LButton::
Send % Seqkeys("A","B","C")
KeyWait, LButton
Send, R
return
*RButton::
currentKeyIndex := 1
clickThreshold := 0
return
Seqkeys(params*) {
global lastClickedTime, currentKeyIndex, clickThreshold
max := params.MaxIndex()
currentKeyIndex += 1
if((A_TickCount - lastClickedTime) <= clickThreshold && currentKeyIndex <= max) {
; Do nothing
} else {
currentKeyIndex := 1
}
lastClickedTime := A_TickCount
return params[currentKeyIndex]
}

Double tap SHIFT key followed by a letter

I would like to be able to double tap a SHIFT key followed by a letter to activate an action. Can anyone help? It would be nice to be able to double tap either SHIFT key.
Something like??
<+<+ or >+>+ then d
do something
return
~Shift Up::
If (A_ThisHotkey == A_PriorHotkey && A_TimeSincePriorHotkey < 500)
{
Double_SHIFT := true
Sleep, 2000
Double_SHIFT := false
}
return
; Press a key within two seconds after double tapping the Shift key, to activate an action:
#If (Double_SHIFT)
a:: MsgBox, This macro has not yet been enabled. Contact IT for suggestions.
b:: FormatTime, CurrentDateTime,,MM/dd/yy - hh:mmtt
SendInput %CurrentDateTime%
c:: MsgBox, This macro has not yet been enabled. Contact IT for suggestions.
return
~Shift Up::
If (A_ThisHotkey == A_PriorHotkey && A_TimeSincePriorHotkey < 500)
{
Double_SHIFT := true
ToolTip, Double_SHIFT ; remove this line, if you don't want a tooltip displayed
Sleep, 2000
Double_SHIFT := false
ToolTip ; remove this line, if you don't want a tooltip displayed
}
return
; Press a key within two seconds after double tapping the Shift key, to activate an action:
#If (Double_SHIFT)
a:: MsgBox, Double_SHIFT + a
b:: MsgBox, Double_SHIFT + b
#If
Displays message box when shiftshiftd pressed
~LShift::ShiftPressed()
~RShift::ShiftPressed()
$d::DPressed()
ShiftPressed()
{
global t1,t2
t1 := t2
t2 := A_TickCount
}
DPressed()
{
global t1,t2
if (A_TickCount < t1 + 1000) && (A_TickCount < t2 + 1000)
MsgBox Shift Shift D Pressed
else
sendinput d
}

Is Autohotkey able to perform sequential pastes?

Is it possible to create a script for the multiple successive pastes?
Example: I copy ten different words with Ctrl+C (10 times) and paste into my doc pressing Ctrl+V (10 times).
Just for fun:
copiedText := []
~^C::
ClipWait, 0
copiedText.push(clipboard), clipboard := ""
return
^V::sendInput % copiedText.length() ? copiedText.remove(1) : _
something like this
loop,
{
position = 0
loop,
{
~^c::
if (a_index = 9){
position = 0
}
else
{
position := position + 1
}
ClipWait
var%position% := clipboard
return
}
::p1::
send, %var1%
return
::p2::
send, %var2%
return
::p3::
send, %var3%
return
::p4::
send, %var4%
return
::p5::
send, %var5%
return
::p6::
send, %var6%
return
::p7::
send, %var7%
return
::p8::
send, %var8%
return
::p9::
send, %var9%
return
::p10::
send, %var10%
return
}
save clipboard into var then input them where and how you like to.

CPU watch and email with AutoHotKey

I'm trying to setup an automatic email if the conditions are meet. I'm trying to watch my cpu load. if pass or drops over a number send a email.
CheckCPULoad:
CoordMode, ToolTip, Screen
SetFormat, float, 0.0
CPULoad := GetCPULoad_Short()
ToolTip, CPULoad = %CPULoad%%, 0 ,%A_ScreenHeight%
return
GetCPULoad_Short()
{
Static IdleTime, Tick
global ProcessorCount
SetBatchLines, -1
OldIdleTime = %IdleTime%
OldTick = %Tick%
VarSetCapacity( IdleTicks,8,0)
DllCall("kernel32.dll\GetSystemTimes", "uint",&IdleTicks, "uint",0, "uint",0)
IdleTime := *(&IdleTicks)
Loop 7
IdleTime += *( &IdleTicks + A_Index ) << ( 8 * A_Index )
Tick := A_TickCount
Return 100 - 0.01*(IdleTime - OldIdleTime)/(Tick - OldTick) / ProcessorCount
}
#############
#IfEqual, CPUload, 0,
#or
if (CPUload = 0)
{
IfWinNotExist Inbox - Email#Email.com - Outlook
return ; Outlook isn't open to the right section, so do nothing.
WinActivate ; Activate the window found by the above command.
Send ^n ; Create new/blank e-mail via Control+N.
WinWaitActive Untitled - Message (HTML)
Send, sentEmailto#help.com
Send {Tab 3} computer has stopped ; Set the subject line.
Send {Tab} more txt. ; etc.
return ; This line serves to finish the hotkey.
}
But I tried with a simple
if (CPULoad = 0)
msgBox testing
and it won't give me a message. why can i get a message box to show. or email to send?
This post got me curious to see if this had been done before and I instantly found a solution posted on the ahkscript forums:
Loop {
If (CPULoad() > 25) ; Assign the Number you want.
; Your EMAIL Code here! If MultiLine Use {...code...}
Sleep 250
}
CPULoad() { ; By SKAN, CD:22-Apr-2014 / MD:05-May-2014. Thanks to ejor, Codeproject: http://goo.gl/epYnkO
Static PIT, PKT, PUT ; http://ahkscript.org/boards/viewtopic.php?p=17166#p17166
IfEqual, PIT,, Return 0, DllCall( "GetSystemTimes", "Int64P",PIT, "Int64P",PKT, "Int64P",PUT )
DllCall( "GetSystemTimes", "Int64P",CIT, "Int64P",CKT, "Int64P",CUT )
, IdleTime := PIT - CIT, KernelTime := PKT - CKT, UserTime := PUT - CUT
, SystemTime := KernelTime + UserTime
Return ( ( SystemTime - IdleTime ) * 100 ) // SystemTime, PIT := CIT, PKT := CKT, PUT := CUT
}

Trying to capture value in class tag using ahk script

I am trying to capture the value in <span class="latlon"></span> at http://nominatim.openstreetmap.org/search.php?q=MK3+5JE&viewbox=-147.13%2C72.78%2C147.13%2C-55.67:
For example 51.99,-0.76 in this case:
But whenever I run my AHK script this is the output:
Why does it not read the value in the latlon field?
This is my code so far:
Loop, read, test.csv
{
Loop, parse, A_LoopReadLine, %A_Tab%
{
; Run IE
IE := ComObjCreate("InternetExplorer.Application")
IE.Visible:=True
; Copy current postcode row to clipboard
Clipboard = %A_LoopField%
Postcode = %A_LoopField%
ClipWait
; Debugging - wait 1s then check output
; Sleep 1000
; MsgBox, %Clipboard%
; Navigate to Bing Maps and paste the postcode
IE.Navigate("http://nominatim.openstreetmap.org/")
Sleep 300
Send, ^v
Send {Enter}
; Debugging - wait 1s then check output
; Sleep 1000
; IE.Navigate("javascript: alert(document.getElementsByClassName('name')[0].innerHTML)")
; IE.Navigate("javascript: alert(document.getElementsByClassName('latlon')[0].innerHTML)")
; Collect results
j := 0
i := 1
Addr := {}
while (i <= 1)
{
Sleep 1000
Addr[i] := IE.document.getElementsByClassName("name")[j].innertext
LatLon[i] := IE.document.getElementsByClassName("latlon")[j].innertext
Addr_Object := StrSplit(Addr[i], "`,")
LatLon_Object := StrSplit(LatLon[i], "`,")
If (Substr(Addr[i], 1, 2) = "MK")
{
Addr[i] := Addr_Object[2] . "," . Trim(Addr_Object[3]) . "," . PostCode . "," . LatLon_Object[1] . "," . LatLon_Object[2]
MsgBox, % Addr[i]
}
Else
{
Addr[i] := Addr_Object[1] . "," . Trim(Addr_Object[2]) . "," . PostCode . "," . LatLon_Object[1] . "," . LatLon_Object[2]
MsgBox, % Addr[i]
}
j++
i++
}
; Close IE
IE.quit()
}
}
Content of test.csv:
MK3 5JE
MK1 1AS
Would appreciate any pointers in the right direction.
I think you've got to be a bit more precise... Well, it doesn't hurt to be...
document.getElementById("searchresults").getElementsByClassName("result")[0].getElementsByClassName("latlon")[0].innerHTML
Here's an example:
You can change to loop though all of the results, but in this example, only the first result is retrieved.
SetWorkingDir, %A_scriptdir%
FileRead,data,test.csv
data := StrSplit(data,"`r`n",A_Tab)
Gui Add, ActiveX, xm w640 h480 vWB, Shell.Explorer
ComObjConnect(WB, WB_events) ; Connect WB's events to the WB_events class object.
Gui Show
WB.silent := true ;Surpress JS Error boxes
ProcessDone:=0 ; "Universal" signal
for each, item in data
{
ToolTip Loading...`nPlease wait...
PostCode:=item
WB.Navigate("http://nominatim.openstreetmap.org/search.php?q=" item) ;search it
while (!ProcessDone) {
;wait
}
ProcessDone:=0
}
return
class WB_events
{
DocumentComplete(wb, NewURL)
{
global ProcessDone
global PostCode
while (StrLen(wb.document.getElementById("searchresults").innerHTML)==0) {
;wait
}
/* Information nested as:
#searchresults
.result
.latlon
*/
numResult := wb.document.getElementById("searchresults").getElementsByClassName("result").length
addr := wb.document.getElementById("searchresults").getElementsByClassName("result")[0].getElementsByClassName("name")[0].innerHTML
coords := wb.document.getElementById("searchresults").getElementsByClassName("result")[0].getElementsByClassName("latlon")[0].innerHTML
ToolTip
MsgBox,,OpenStreenMap - First result,Address:`t%addr%`nPostal code:`t%PostCode%`nCoordinates:`t%coords%`nNumber of results:`t%numResult%`nURL: %NewURL%
ProcessDone:=1
}
}
GuiClose:
ExitApp