What to do when ControlSend or Send doesn't work? - autohotkey

I recently upgraded to Windows 8.1 x64, now script that i was using doesn't work anymore. That script would right click tray icon of a certain program than navigate to one of its options then click that option.
Here is the script:::
;#NoTrayIcon
DetectHiddenWindows, On
;Outlook on the Desktop--------------------------------------------------------------------------------------------------------------------------------
^1:: ;25,000$ Fine Tuned
Info := TrayIcons("OutlookDesktop.exe") ; OutlookDesktop.exe is the prog i tested with
StringSplit, TrayInfo, Info,|
PostMessage, TrayInfo1, TrayInfo2, 0x0205,, ahk_id %TrayInfo3% ; this is the right-click
Sleep 500
Send {Down 3}{Right}{Down 7}{Right}{Down 4}{Enter}
return
^2:: ;Projects
Info := TrayIcons("OutlookDesktop.exe") ; OutlookDesktop.exe is the prog i tested with
StringSplit, TrayInfo, Info,|
PostMessage, TrayInfo1, TrayInfo2, 0x0205,, ahk_id %TrayInfo3% ; this is the right-click
Sleep 500
Send {Down 3}{Right}{Down 7}{Right}{Down 1 4}{Enter}
return
^3:: ;Due This Week - unfinished
Info := TrayIcons("OutlookDesktop.exe") ; OutlookDesktop.exe is the prog i tested with
StringSplit, TrayInfo, Info,|
PostMessage, TrayInfo1, TrayInfo2, 0x0205,, ahk_id %TrayInfo3% ; this is the right-click
Sleep 500
Send {Down 3}{Right}{Down 7}{Right}{Down 2 4}{Enter}
return
^4:: ;To-do Bar Calendar View
Info := TrayIcons("OutlookDesktop.exe") ; OutlookDesktop.exe is the prog i tested with
StringSplit, TrayInfo, Info,|
PostMessage, TrayInfo1, TrayInfo2, 0x0205,, ahk_id %TrayInfo3% ; this is the right-click
Sleep 500
Send {Down 3}{Right}{Down 7}{Right}{Down 7 4}{Enter}
return
; Found and abused from
; http://www.autohotkey.com/forum/topic17314.html
; thx, Sean ... GREAT WORK!
TrayIcons(sExeName = "OutlookDesktop.exe")
{
WinGet, pidTaskbar, PID, ahk_class Shell_TrayWnd
hProc := DllCall("OpenProcess", "Uint", 0x38, "int", 0, "Uint", pidTaskbar)
pRB := DllCall("VirtualAllocEx", "Uint", hProc, "Uint", 0
, "Uint", 20, "Uint", 0x1000, "Uint", 0x4)
VarSetCapacity(btn, 20)
VarSetCapacity(nfo, 24)
VarSetCapacity(sTooltip, 128)
VarSetCapacity(wTooltip, 128 * 2)
SendMessage, 0x418, 0, 0, ToolbarWindow32, ahk_class Shell_TrayWnd
Loop, %ErrorLevel%
{
SendMessage, 0x417, A_Index - 1, pRB, ToolbarWindow32, ahk_class Shell_TrayWnd
DllCall("ReadProcessMemory", "Uint", hProc, "Uint", pRB, "Uint", &btn, "Uint", 20, "Uint", 0)
iBitmap := NumGet(btn, 0), idn := NumGet(btn, 4), Statyle := NumGet(btn, 8)
dwData := NumGet(btn,12), iString := NumGet(btn,16)
DllCall("ReadProcessMemory", "Uint", hProc, "Uint", dwData, "Uint", &nfo, "Uint", 24, "Uint", 0)
hWnd := NumGet(nfo, 0), uID := NumGet(nfo, 4)
nMsg := NumGet(nfo, 8)
WinGet, pid, PID, ahk_id %hWnd%
WinGet, sProcess, ProcessName, ahk_id %hWnd%
WinGetClass, sClass, ahk_id %hWnd%
If !sExeName || (sExeName = sProcess) || (sExeName = pid)
{
DllCall("ReadProcessMemory", "Uint", hProc, "Uint", iString
, "Uint", &wTooltip, "Uint", 128 * 2, "Uint", 0)
DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "str", wTooltip
, "int", -1, "str", sTooltip, "int", 128, "Uint", 0, "Uint", 0)
sTrayIcons .= nMsg "|" uID "|" hWnd
}
}
DllCall("VirtualFreeEx", "Uint", hProc, "Uint", pRB, "Uint", 0, "Uint", 0x8000)
DllCall("CloseHandle", "Uint", hProc)
Return sTrayIcons
}
;Outlook on the Desktop-----------------------END OF SCRIPT------------------------------------------------------------------------------
Now i googled some more and found this script:::
BlockInput, on
pos := Tray_Define("CCC.exe", "i")
Tray_Click(pos, "R")
WinWait, ahk_class #32768
; WinHide, ahk_class #32768 ;this and next line are to hide the menu.
; WinKill, ahk_class SysShadow
ControlSend,,{Down}{Down}{Down}{Down}{Down}{ENTER},ahk_class #32768
BlockInput, off
ExitApp
Interestingly enough, script is working perfectly on Catalyst Control Centar (CCC.exe) but not on that program i want it to work on, it successfully right clicks but sending control commands is not working. (Also have tried with just Send instead of ControlSend)
What do you guys think is the problem here, why are ControlSend and Send commands not working? What do you suggest that i try?

This is an partial answer:
Since Windows 7, AHK must be always run as administrator, otherwise it shows strange behavior (sometimes not listening to hotkeys, sometimes not sending keys).
Please post your point with BlockIntput into another answer.

Related

AHK Opening last opened windows explorer window if active, else starting new

This code figures out the current explorer windows open,
I would like to open the first in the list, and if the list is empty open a
new explorer instead.
I hope to the open/activate the either window at the current mouse position
#e::
list := ""
numberOfwindows := ""
wins := ""
WinGet, id, list, ahk_class CabinetWClass ahk_exe explorer.exe
Loop, %id%
{
numberOfwindows := A_Index
this_ID := id%A_Index%
WinGetTitle, title, ahk_id %this_ID%
wins .= A_Index A_Space title ? A_Index A_Space title "`n" : ""
}
MsgBox, number of explorer windows = %numberOfwindows%`n`n%wins%
return
This solves it. - however it can be optimized, anyone have any suggestions ?
#e::
list := ""
numberOfwindows := ""
wins := ""
WinGet, id, list, ahk_class CabinetWClass ahk_exe explorer.exe
Loop, %id%
{
numberOfwindows := A_Index
this_ID := id%A_Index%
WinGetTitle, title, ahk_id %this_ID%
if (A_Index = 1) { ; if it's the first index of the loop
;MsgBox %title%
win = %title% ; store the title in " win "
}
wins .= A_Index A_Space title ?½½ A_Index A_Space title "`n" : ""
}
IfWinNotExist ahk_class CabinetWClass
{
Run C:\Windows\explorer.exe
win := File Explorer
WinWait, %win% ahk_class CabinetWClass
WinMove, mxpos_new , mypos_new
WinActivate
}
;MsgBox, number of explorer windows = %numberOfwindows%`n`n%wins%
; above msgbox displays number and the names of the windows.
;~ ; we now know the win
; and its title, exe and class.
; we want it's current position.
WinGetPos, X, Y, Width, Height,%win% ahk_class CabinetWClass
;MsgBox, %X%, %Y%, %Width%, %Height%
; and we want the mouse position.
CoordMode, Mouse, Screen ; Coordinates are relative to the desktop (entire screen).
MouseGetPos, mxpos , mypos,
;MsgBox, %mxpos%, %mypos%
mxpos_new := mxpos - (Width / 2)
mypos_new := mypos - (Height / 2)
;MsgBox, %mxpos% %mypos% %Width% %Height% %mxpos_new% %mypos_new%
; activate that specific window
WinWait, %win% ahk_class CabinetWClass
WinMove, mxpos_new , mypos_new
WinActivate
return

get keyboard layout of active window (win 10)

I use this script to track the keyboard layout on Win 7, it works ok:
getactiveKL() {
active_hwnd := WinExist("A")
threadID := dllCall("GetWindowThreadProcessId", "uint", active_hwnd)
code := dllCall("GetKeyboardLayout", "uint", threadID, "uint") & 0xFFFF
return code
}
; 1049 - RU (hex: 419)
; 1033 - EN (hex: 409)
loop {
sleep, 600
KL := getactiveKL()
tooltip, %KL%
}
But it dooes not work on win 10. Namely it works only once - if I set the layout to RU, and then run this script, it detects correctly, but when I switch the layout - nothing changes.
Do you know how to make it work on windows 10?
The problem was in this line:
threadID := dllCall("GetWindowThreadProcessId", "uint", active_hwnd)
It should be:
threadID := dllCall("GetWindowThreadProcessId", "uint", active_hwnd, "uint", 0)
There are many examples in the web with different spelling of this dll call, so the latter works on windows 10 correctly.

Autohotkey Open Folder of Current Application or Process

In this code no open current application folder because the FilePath variable include exe file name
F11::
PID = 0
WinGet, hWnd,, A
DllCall("GetWindowThreadProcessId", "UInt", hWnd, "UInt *", PID)
hProcess := DllCall("OpenProcess", "UInt", 0x400 | 0x10, "Int", False
, "UInt", PID)
PathLength = 260*2
VarSetCapacity(FilePath, PathLength, 0)
DllCall("Psapi.dll\GetModuleFileNameExW", "UInt", hProcess, "Int", 0, "Str", FilePath, "UInt", PathLength)
DllCall("CloseHandle", "UInt", hProcess)
Run, Explorer %FilePath%
Thanks in advance for any assistance.
F11::
WinGet, path, ProcessPath, A
SplitPath, path, name, dir
Run, explorer.exe %dir%
return
or:
F11::
WinGet, path, ProcessPath, A
Run, % "explorer.exe /select," . path
return

Resize window after taskbar hidden

Below hotkey script hides/displays taskbar when lWin&H is keyed :
LWin & h::
if toggle := !toggle
{
WinHide ahk_class Shell_TrayWnd
WinHide Start ahk_class Button
}
else
{
WinShow ahk_class Shell_TrayWnd
WinShow Start ahk_class Button
}
return
Script is taken from a comment at http://lifehacker.com/taskbar-control-hides-and-unhides-the-windows-taskbar-w-1573974951
But when the taskbar is hidden the space which occupied the taskbar is unusable : windows do not drag to this area, newly opened program do not occupy this space.
Can script be modified so that when taskbar is hidden the entire screen area is usable ?
Here is a way that sets the work area to include the taskbar space to.
LWin & h::
if toggle := !toggle
{
WinHide ahk_class Shell_TrayWnd
WinHide Start ahk_class Button
SysGet, Mon, Monitor
SetWorkArea(MonLeft, MonTop, MonRight, MonBottom)
}
else
{
WinShow ahk_class Shell_TrayWnd
WinShow Start ahk_class Button
SysGet, Mon, MonitorWorkArea
SetWorkArea(MonLeft, MonTop, MonRight, MonBottom)
}
return
SetWorkArea(left,top,right,bottom) ; set main monitor work area ; windows are not resized!
{
VarSetCapacity(area, 16)
NumPut(left, area, 0, "UInt") ; left
NumPut(top, area, 4, "UInt") ; top
NumPut(right, area, 8, "UInt") ; right
NumPut(bottom,area,12, "UInt") ; bottom
DllCall("SystemParametersInfo", "UInt", 0x2F, "UInt", 0, "UPtr", &area, "UInt", 0) ; SPI_SETWORKAREA
}
Hope it helps
Instead of using autohotkey I use this utility :
http://www.itsamples.com/taskbar-hider.html
This appears to work (just tested on Windows7) :
lWin & h::
;#NoEnv
#NoTrayIcon
;#SingleInstance force
DetectHiddenWindows, Off ;for IfWinExist
VarSetCapacity( APPBARDATA, 36, 0 )
;------------------------------------------------------------
; Fetch current hidden/showing status
IfWinNotExist, ahk_class Shell_TrayWnd
TaskbarAndStartToggleState = 0 ;Currently [color=darkred]hidden[/color] (not showing)
Else
TaskbarAndStartToggleState = 1 ;Currently [color=darkred]non-hidden[/color] (showing)
;------------------------------------------------------------
Gosub +z ;Toggle the taskbar/SM state
;------------------------------------------------------------
Exit
;------------------------------------------------------------
+z::
TaskbarAndStartToggleState := Func(TaskbarAndStartToggleState)
Return
Func(TaskbarAndStartToggleState)
{
Global APPBARDATA
If TaskbarAndStartToggleState = 0
{
NumPut( (ABS_ALWAYSONTOP := 0x2), APPBARDATA, 32, "UInt" ) ;Enable "Always on top" [color=darkred](& disable auto-hide)[/color]
DllCall( "Shell32.dll\SHAppBarMessage", "UInt", ( ABM_SETSTATE := 0xA ), "UInt", &APPBARDATA )
WinShow ahk_class Shell_TrayWnd
Return 1 ;Now showing
}
If TaskbarAndStartToggleState = 1
{
NumPut( ( ABS_AUTOHIDE := 0x1 ), APPBARDATA, 32, "UInt" ) ;Disable "Always on top" [color=darkred](& enable auto-hide to hide Start button)[/color]
DllCall( "Shell32.dll\SHAppBarMessage", "UInt", ( ABM_SETSTATE := 0xA ), "UInt", &APPBARDATA )
WinHide ahk_class Shell_TrayWnd
;WinHide ahk_class Shell_TrayWnd ;[color=darkred]don't need this 2nd one?[/color]
Return 0 ;Now hidden
}
}
return
Slightly modified from :
http://www.autohotkey.com/board/topic/25932-trying-to-toggle-autohide-taskbar-with-keystroke-in-vista/page-2
Update : This script causes unexpected behavior when using multiple desktops. The taskbar is hidden but when toggle to restore just windows icon is display. Hiding the taskbar and unhiding the taskbar in taskbar properties appears to fix this, but this makes the script unusable if using multiple desktops.

How to hook a window focused event in win7

I want to turn off capslock when I switch to the mintty window. And according Autohotkey: Toggle caps lock on/off on activating certain windows I try to hook the focused event using autohotkey. But this does not work on my pc(win7-64bit).
How to do to fix this on win7, or is there a better way or workaround?
My code is exactly the same as the answer to the link I referenced:
#Persistent ; Don't close when the auto-execute ends
SetTitleMatchMode, 2 ; Partial title matching
WinGet, myHwnd, ID, AutoHotKeys; Get the handle to the your window
; Listen for activation messages to all windows
DllCall("CoInitialize", "uint", 0)
if (!hWinEventHook := DllCall("SetWinEventHook", "uint", 0x3, "uint", 0x3, "uint", 0, "uint", RegisterCallback("HookProc"), "uint", 0, "uint", 0, "uint", 0))
{
MsgBox, Error creating shell hook
Exitapp
}
;MsgBox, Hook made
;DllCall("UnhookWinEvent", "uint", hWinEventHook) ; Remove the message listening hook
return
; Handle the messages we hooked on to
HookProc(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
global myHwnd
static lastHwnd
WinGetTitle, title, ahk_id %hwnd%
if (hwnd == myHwnd) ; If our window was just activated
{
tooltip, Gained focus
}
else if (lastHwnd == myHwnd) ; If our window was just deactivated
{
tooltip, Lost focus
}
lastHwnd := hwnd
}
Note that I am trying to use a handle of the window of notepad to test the functionality. And if this works I will replace the 'notepad' to 'mintty'.
And the info in the panel of AHK is:
Script lines most recently executed (oldest first). Press [F5] to refresh. The seconds elapsed between a line and the one after it is in parentheses to the right (if not 0). The bottommost line's elapsed time is the number of seconds since it executed.
025: SetTitleMatchMode,2
026: WinGet,myHwnd,ID,AutoHotKeys; Get the handle to the your window
029: DllCall("CoInitialize", "uint", 0)
030: if (!hWinEventHook := DllCall("SetWinEventHook", "uint", 0x3, "uint", 0x3, "uint", 0, "uint", RegisterCallback("HookProc"), "uint", 0, "uint", 0, "uint", 0))
038: Return (1.28)
045: WinGetTitle,title,ahk_id %hwnd%
047: if (hwnd == myHwnd)
051: if (lastHwnd == myHwnd)
053: ToolTip,Lost focus (0.03)
054: }
056: lastHwnd := hwnd
057: } (0.05)
045: WinGetTitle,title,ahk_id %hwnd%
047: if (hwnd == myHwnd)
051: if (lastHwnd == myHwnd)
056: lastHwnd := hwnd
057: } (2.14)
Press [F5] to refresh.
I don't know if this is that you need.
I've used this code
#Persistent
SetTimer, testing,200
return
testing:
IfWinExist Calculadora
{
SetCapsLockState ,Off
}
else
{
SetCapsLockState ,On
}
return
When I open the Windows calc the CapsLock turns off and vice versa.
Greetings!
#Persistent
SetTitleMatchMode, 2 ; use RegEx for finer control
Loop
{
WinWaitActive, Notepad
{
WinGet, opVar, ID
CapsLockState := GetKeyState("CapsLock", "T")
SetCapsLockState, AlwaysOff ; or just "Off"
}
WinWaitNotActive, ahk_id %opVar%
SetCapsLockState, % CapsLockState ? "On" : "Off"
}