Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Actions on taskbar's tray-icon via AHK possible?


  • Please log in to reply
51 replies to this topic
pajenn
  • Members
  • 391 posts
  • Last active: Feb 06 2015 07:57 AM
  • Joined: 07 Feb 2009
Hello SKAN, I did more testing with your USB flash drive ejector (also fixed bugs & updated my posted code for the tray app so it uses the USBD_SafelyRemove properly), and recorded several logs from devcon for reference.

Comments on USBD_SafelyRemove:

1. Faster and generally* (see below) more reliable than the automated clicks on Safely Remove Hardware.

*2. failed to eject my mobile phone (classified as a Removable by AHK - and presumably uses flash memory) - I tried 4 times but got error message each time (see pic). Safely Remove Hardware ejected it on the first try.

3. Ejected my digital camera fine, and also flash drives that were connected to a USB 4-1 extension hub.

4. Presence of other USB devices (Bluetooth transmitter for wireless headphones and a USB-USB link cable between two computers) did not interfere.

[Edit]

General notes and devcon:

1. My external hard drive did not show up in devcon log when connected with a Firewire cable (with USB it was fine). Safely Remove Hardware is happy to eject it regardless of the connection cable type.

2. The USB-to-USB connection cable shows up in Safely Remove Hardware, but it's neither a Removable nor Fixed device (drive) by AHK classification, so it doesn't show up in the tray ejection menu. In my case that's okay because ejecting the cable from the tray menu has been problematic in the past (it's a cheapo $5 or 10 cable I got off eBay that was a PITA to set up and prone to problems), but I suppose such devices should be accounted for by any Safely Remove Hardware alternatives.

3. Pic below displays the open tray menus corresponding to the devcon logs that follow. Also included is the error message for the mobile phone.

Posted Image

Devcon log for first (top-left) pic:
[Attached]
USB\ROOT_HUB\4&1CFE90D3&0                                   : USB Root Hub
USB\ROOT_HUB\4&21C01574&0                                   : USB Root Hub
USB\ROOT_HUB\4&23B48FB8&0                                   : USB Root Hub
USB\ROOT_HUB\4&265735F3&0                                   : USB Root Hub
USB\ROOT_HUB\4&2F119A28&0                                   : USB Root Hub
USB\ROOT_HUB20\4&3064E25D&1                                 : USB Root Hub
USB\ROOT_HUB20\4&DEF2E52&1                                  : USB Root Hub
USB\VID_08FF&PID_2580\5&B701C9D&0&2                         :  AuthenTec Inc. AES2501A
USB\VID_0951&PID_1607\0019E02CB6E45B8C0C15017C              : USB Mass Storage Device
USB\VID_0D62&PID_0530\5&1D3171BF&0&1                        : USB Human Interface Device
USB\VID_0DD8&PID_E20B\65B975E7622BA479                      : USB Mass Storage Device
USB\VID_1307&PID_0165\080507516F87C8                        : USB Mass Storage Device
12 matching device(s) found.

Log for 2nd (top-right) pic:
[Attached]
USB\ROOT_HUB\4&1CFE90D3&0                                   : USB Root Hub
USB\ROOT_HUB\4&21C01574&0                                   : USB Root Hub
USB\ROOT_HUB\4&23B48FB8&0                                   : USB Root Hub
USB\ROOT_HUB\4&265735F3&0                                   : USB Root Hub
USB\ROOT_HUB\4&2F119A28&0                                   : USB Root Hub
USB\ROOT_HUB20\4&3064E25D&1                                 : USB Root Hub
USB\ROOT_HUB20\4&DEF2E52&1                                  : USB Root Hub
USB\VID_05E3&PID_0608\5&29CFC909&0&1                        : Generic USB Hub
USB\VID_08FF&PID_2580\5&B701C9D&0&2                         :  AuthenTec Inc. AES2501A
USB\VID_0951&PID_1607\0019E02CB6E45B8C0C15017C              : USB Mass Storage Device
USB\VID_0A5C&PID_2120\6&1F806AFB&0&1                        : Broadcom 2045 Bluetooth 2.0 USB-UHE Device
USB\VID_0A5C&PID_4500\5&1D3171BF&0&2                        : Generic USB Hub
USB\VID_0A5C&PID_4502\6&1F806AFB&0&2                        : USB Human Interface Device
USB\VID_0A5C&PID_4503\6&1F806AFB&0&3                        : USB Human Interface Device
USB\VID_0C0B&PID_2BCF\200509171993                          : USB Mass Storage Device
USB\VID_0D62&PID_0530\5&1D3171BF&0&1                        : USB Human Interface Device
USB\VID_0DD8&PID_E20B\65B975E7622BA479                      : USB Mass Storage Device
USB\VID_1307&PID_0165\080507516F87C8                        : USB Mass Storage Device
18 matching device(s) found.

Log for last (bottom) pics:
[Attached]
USB\ROOT_HUB\4&1CFE90D3&0                                   : USB Root Hub
USB\ROOT_HUB\4&21C01574&0                                   : USB Root Hub
USB\ROOT_HUB\4&23B48FB8&0                                   : USB Root Hub
USB\ROOT_HUB\4&265735F3&0                                   : USB Root Hub
USB\ROOT_HUB\4&2F119A28&0                                   : USB Root Hub
USB\ROOT_HUB20\4&3064E25D&1                                 : USB Root Hub
USB\ROOT_HUB20\4&DEF2E52&1                                  : USB Root Hub
USB\VID_0421&PID_003B\357683015264379                       : USB Mass Storage Device
USB\VID_04CB&PID_0126\Y-511^^^^^031122XFPX0009036972        : USB Mass Storage Device
USB\VID_05E3&PID_0608\5&29CFC909&0&1                        : Generic USB Hub
USB\VID_067B&PID_0001\1                                     : Hi-Speed USB-USB Network Adapter
USB\VID_08FF&PID_2580\5&B701C9D&0&2                         :  AuthenTec Inc. AES2501A
USB\VID_0951&PID_1602\5B7B1160094D                          : USB Mass Storage Device
USB\VID_0A5C&PID_2120\6&1F806AFB&0&1                        : Broadcom 2045 Bluetooth 2.0 USB-UHE Device
USB\VID_0A5C&PID_4500\5&1D3171BF&0&2                        : Generic USB Hub
USB\VID_0A5C&PID_4502\6&1F806AFB&0&2                        : USB Human Interface Device
USB\VID_0A5C&PID_4503\6&1F806AFB&0&3                        : USB Human Interface Device
USB\VID_0D62&PID_0530\5&1D3171BF&0&1                        : USB Human Interface Device
18 matching device(s) found.

Hardware: fast laptop with SSD
Software: Win 7 Home Premium 64-bit, android for phone and tablet


pt
  • Guests
  • Last active:
  • Joined: --
Hi Skan & pajenn

Pls could you help me with a little problem I have? I found (most of) the solution to my need in your posts above, and Sean's Trayicons routines. For all of which - THANK YOU!! (I gues you can see by now I am a rank newbie at this)

I am trying to automate start and stop of Hamachi network shares.

I get the Hamachi context menu up from the system tray with the code below, then select the first item in the context menu by mousemove 10, 10, r, Send {enter}

My problem is that the first item in the context menu is effectively a toggle. It changes between "restore" and "minimize" according to if the main window is open or not. So my routine at the moment just toggles the window on and off.

I want to click the item in the context menu if it says "restore", and to ignore it if it says "minimize". (ie this is to make sure the window is displayed).

Please could you give me a pointer in the right direction? I have seen the "get contect menu info" code, but to be honest I have no hope of understanding it.

Many thanx

Pt


TI := TrayIcons( "hamachi.exe" )
StringSplit,TIV, TI, |
uID  := RegExReplace( TIV4, "uID: " )
Msg  := RegExReplace( TIV5, "MessageID: " )
hWnd := RegExReplace( TIV6, "hWnd: " )

SendMessage, Msg, uID,0x204,, ahk_id %hWnd% ; Right Click down
SendMessage, Msg, uID,0x205,, ahk_id %hWnd% ; Right Click Up

MouseMove, 10, 10, , r
Send {enter}

BlockInput off
ExitApp


pajenn
  • Members
  • 391 posts
  • Last active: Feb 06 2015 07:57 AM
  • Joined: 07 Feb 2009
pt, it might be easier to use regular windowing commands.

WinShow, [title, class or ahk_id of hamachi]

or

WinActivate, [title, class or ahk_id of hamachi]
WinWaitActive, [title, class or ahk_id of hamachi]

if the window is already showing or active, those commands will be redundant but they won't hurt.

if you need a direct method to read tray menus, then i can't help you. the code I'm using to pick a drive to eject from the 'Safely Remove Hardware' menu is from SKAN's post, and I haven't learned to DllCall yet, which is a main ingredient in the method he uses... ( DllCall( "GetMenuItemID", UInt,hMenu, Int,idx ), DllCall( "GetMenuString", UInt,hMenu, Int,idx, Int,0, Int,0, UInt,0x400 ), ... )

Hardware: fast laptop with SSD
Software: Win 7 Home Premium 64-bit, android for phone and tablet


ImprisonedPride
  • Members
  • 70 posts
  • Last active: Aug 03 2009 06:44 PM
  • Joined: 30 Apr 2008
I'm not sure I'm still in the current direction of this thread, but I compiled a "custom" system tray in a transparent gui next to my RK Launcher. The code auto-detects all system tray icons except explorer.exe. I intended to continue it to allow to auto-detect unknown icons and ask you to specify an icon to use for display, but never gave it the extra TLC. What I wound up doing is creating an images/ directory where the script runs from. I only took the 5-6 common exes that are reported from the TrayIcon.ahk script below and created custom 24x24px icons in the directory. I used the same name as the exe reported for the png icon I use for display to create a dynamic system tray. Hope it helps (someone).

TrayIcon.ahk:
#NoTrayIcon
DetectHiddenWindows, On

MsgBox % TrayIcons()
Return

/*
WM_MOUSEMOVE	= 0x0200
WM_LBUTTONDOWN	= 0x0201
WM_LBUTTONUP	= 0x0202
WM_LBUTTONDBLCLK= 0x0203
WM_RBUTTONDOWN	= 0x0204
WM_RBUTTONUP	= 0x0205
WM_RBUTTONDBLCLK= 0x0206
WM_MBUTTONDOWN	= 0x0207
WM_MBUTTONUP	= 0x0208
WM_MBUTTONDBLCLK= 0x0209

PostMessage, nMsg, uID, WM_RBUTTONDOWN, , ahk_id %hWnd%
PostMessage, nMsg, uID, WM_RBUTTONUP  , , ahk_id %hWnd%
*/


TrayIcons(sExeName = "")
{
	WinGet,	pidTaskbar, PID, ahk_class Shell_TrayWnd
	hProc:=	DllCall("OpenProcess", "Uint", 0x38, "int", 0, "Uint", pidTaskbar)
	pProc:=	DllCall("VirtualAllocEx", "Uint", hProc, "Uint", 0, "Uint", 32, "Uint", 0x1000, "Uint", 0x4)
	idxTB:=	GetTrayBar()
		SendMessage, 0x418, 0, 0, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd   ; TB_BUTTONCOUNT
	Loop,	%ErrorLevel%
	{
		SendMessage, 0x417, A_Index-1, pProc, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd   ; TB_GETBUTTON
		VarSetCapacity(btn,32,0), VarSetCapacity(nfo,32,0)
		DllCall("ReadProcessMemory", "Uint", hProc, "Uint", pProc, "Uint", &btn, "Uint", 32, "Uint", 0)
			iBitmap	:= NumGet(btn, 0)
			idn	:= NumGet(btn, 4)
			Statyle := NumGet(btn, 8)
		If	dwData	:= NumGet(btn,12)
			iString	:= NumGet(btn,16)
		Else	dwData	:= NumGet(btn,16,"int64"), iString:=NumGet(btn,24,"int64")
		DllCall("ReadProcessMemory", "Uint", hProc, "Uint", dwData, "Uint", &nfo, "Uint", 32, "Uint", 0)
		If	NumGet(btn,12)
			hWnd	:= NumGet(nfo, 0)
		,	uID	:= NumGet(nfo, 4)
		,	nMsg	:= NumGet(nfo, 8)
		,	hIcon	:= NumGet(nfo,20)
		Else	hWnd	:= NumGet(nfo, 0,"int64"), uID:=NumGet(nfo, 8), nMsg:=NumGet(nfo,12)
		WinGet, pid, PID,              ahk_id %hWnd%
		WinGet, sProcess, ProcessName, ahk_id %hWnd%
		WinGetClass, sClass,           ahk_id %hWnd%
		If !sExeName || (sExeName = sProcess) || (sExeName = pid)
			VarSetCapacity(sTooltip,128), VarSetCapacity(wTooltip,128*2)
		,	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 .= "idx: " . A_Index-1 . " | idn: " . idn . " | Pid: " . pid . " | uID: " . uID . " | MessageID: " . nMsg . " | hWnd: " . hWnd . " | Class: " . sClass . " | Process: " . sProcess . "`n" . "   | Tooltip: " . sTooltip . "`n"
	}
	DllCall("VirtualFreeEx", "Uint", hProc, "Uint", pProc, "Uint", 0, "Uint", 0x8000)
	DllCall("CloseHandle", "Uint", hProc)
	Return	sTrayIcons
}

RemoveTrayIcon(hWnd, uID, nMsg = 0, hIcon = 0, nRemove = 2)
{
	NumPut(VarSetCapacity(ni,444,0), ni)
	NumPut(hWnd , ni, 4)
	NumPut(uID  , ni, 8)
	NumPut(1|2|4, ni,12)
	NumPut(nMsg , ni,16)
	NumPut(hIcon, ni,20)
	Return	DllCall("shell32\Shell_NotifyIconA", "Uint", nRemove, "Uint", &ni)
}

HideTrayIcon(idn, bHide = True)
{
	idxTB := GetTrayBar()
	SendMessage, 0x404, idn, bHide, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd   ; TB_HIDEBUTTON
	SendMessage, 0x1A, 0, 0, , ahk_class Shell_TrayWnd
}

DeleteTrayIcon(idx)
{
	idxTB := GetTrayBar()
	SendMessage, 0x416, idx - 1, 0, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd   ; TB_DELETEBUTTON
	SendMessage, 0x1A, 0, 0, , ahk_class Shell_TrayWnd
}

MoveTrayIcon(idxOld, idxNew)
{
	idxTB := GetTrayBar()
	SendMessage, 0x452, idxOld - 1, idxNew - 1, ToolbarWindow32%idxTB%, ahk_class Shell_TrayWnd ; TB_MOVEBUTTON
}

GetTrayBar()
{
	ControlGet, hParent, hWnd,, TrayNotifyWnd1  , ahk_class Shell_TrayWnd
	ControlGet, hChild , hWnd,, ToolbarWindow321, ahk_id %hParent%
	Loop
	{
		ControlGet, hWnd, hWnd,, ToolbarWindow32%A_Index%, ahk_class Shell_TrayWnd
		If  Not	hWnd
			Break
		Else If	hWnd = %hChild%
		{
			idxTB := A_Index
			Break
		}
	}
	Return	idxTB
}
Menu, Tray, Click, 1 

System Tray.ahk:
DetectHiddenWindows, On

WinGetPos, rkx, rky, rkw, rkh, RK Launcher

fxp := rkw + rkx - 21

Gui, +ToolWindow +AlwaysOnTop -sysmenu -Caption
Gui, Color, 4d4d4d
Gui +LastFound
;WinSet, TransColor, EEAA99   ;use to make it transparent


TI := TrayIcons()
xp := 0
Loop, Parse, TI, `n, `r
{
	FoundPos := RegExMatch(A_LoopField, "[a-zA-Z0-9]+.exe", match)
	if (FoundPos > 0 && match <> "explorer.exe") {
		StringReplace, match, match, exe, png
		Gui, Add, Picture, x%xp% y0 w24 h24 gDoIt, C:/Programming/AutoHotKey/System Tray/images/%match%
		xp += 25
	} 
}
Gui, Add, Picture, x%xp% y0 w24 h24 gCloseIt, C:/Programming/AutoHotKey/System Tray/images/exit.png

xp += 30
Gui, show, x%fxp% y8 h29 w%xp%,

Return 

CloseIt:
	ExitApp

DoIt:
FoundPos := RegExMatch(A_GuiControl, "[a-zA-Z0-9]+.png", match)
if (FoundPos > 0) {
	StringReplace, match, match, .png, .exe
	RightClick(match)
}
Return

RightClick(appName="")
{
	TI := TrayIcons( appName )
	StringSplit,TIV, TI, |
	uID  := RegExReplace( TIV4, "uID: " )
	Msg  := RegExReplace( TIV5, "MessageID: " )
	hWnd := RegExReplace( TIV6, "hWnd: " )

	PostMessage, Msg, uID,0x204,, ahk_id %hWnd% ; Right Click down
	PostMessage, Msg, uID,0x205,, ahk_id %hWnd% ; Right Click Up
}


#Include C:/Programming/AutoHotKey/Libraries/TrayIcon.ahk

EDIT: I failed to mention that I wrote this for usage with RK Launcher which I used to remove my Windows taskbar from the screen so I needed an alternate to get at the system tray icons.
Call me IP.

a_h_k
  • Members
  • 685 posts
  • Last active: Sep 28 2015 12:32 AM
  • Joined: 02 Feb 2008
Here's a summary of the complete package...



PUT IN SCRIPT...
(Call it USBSafelyRemove.ahk or whatever)

Pajenn's Safely-Remove-USB-Device script/code >>> HERE ---> Search for "Dependencies"

Includes
. #Include ...USBD_SafelyRemove.ahk
. #Include ...TaskButton.ahk
. #Include ...TrayIcon.ahk
. #Include ...getTrayIconIdn.ahk
. #Include ...AutoPopCloser.ahk




PUT IN SCRIPT FOLDER...

SKAN's USBD_SafelyRemove (USBD_SafelyRemove.ahk) >>> HERE

Sean's trayicons functions (TaskButton.ahk & TrayIcon.ahk) >>> HERE

Pajenn's getTrayIconIdn (getTrayIconIdn.ahk) >>> HERE ---> Search for "Dependencies"

Pajenn's AutoPopCloser (AutoPopCloser.ahk) >>> HERE ---> Search for "Dependencies"



REQUIRED TO BE INSTALLED...

Unlocker (or similar) (Unlocker.exe) >>> HERE



* I would put all these files in the script's folder, & not in library, as probably won't use them other than for this application

  • Guests
  • Last active:
  • Joined: --
Any idea how bring up the menu from a leftclick on "Safely Remove Hardware and Eject Media" trayicon ..without clicking? I mean is there something similar to: control.exe hotplug.dll ..any ideas? And that tray icon Isnt always visible by default.

I do this before unpluging..

ExitAllRunningScripts(-the one in use)
  Lock / unmount encrypted volume (with AutoHotkey macro)
    Bring up Systems "Safely remove dialoag"
      Exit the last(current) script

DevEject would be even faster as the last step but requires leaving files on the system..(?) control.exe hotplug.dll works but I would prefer the "Safely Remove Hardware and Eject Media" leftclick menu

Ekkehart
  • Members
  • 2 posts
  • Last active: Dec 31 2014 04:49 PM
  • Joined: 07 Jan 2014

Toggling Bluetooth Süpeakers

 

I followed this suggestion from the first page

 

Tested and works
 

DetectHiddenWindows, On
TI := [color=red]TrayIcons( "cfp.exe" )[/color]
StringSplit,TIV, TI, |
uID  := RegExReplace( TIV4, "uID: " )
Msg  := RegExReplace( TIV5, "MessageID: " )
hWnd := RegExReplace( TIV6, "hWnd: " )

PostMessage, Msg, uID,0x204,, ahk_id %hWnd% ; Right Click down
PostMessage, Msg, uID,0x205,, ahk_id %hWnd% ; Right Click Up
Dependency: You need Sean's TrayIcons()

 

 

 

and created a script to toggle Bluetooth Speakers by pressing Alt_F5. This simulates moderately involved mouse actions starting from the Bluetooth tray icon. May be of interest to some for a similar purpose.

DetectHiddenWindows, On
!F5::
TI := TrayIcon_GetInfo( "BTtray.exe" )
StringSplit,TIV, TI, |
uID  := RegExReplace( TIV4, "uID: " )
Msg  := RegExReplace( TIV5, "MessageID: " )
hWnd := RegExReplace( TIV6, "hWnd: " )

PostMessage, Msg, uID,0x204,, ahk_id %hWnd% ; Right Click down
PostMessage, Msg, uID,0x205,, ahk_id %hWnd% ; Right Click Up
Sleep, 100
Send, {down 4}
sleep 100
Send,{right}
sleep, 100
Send,{down 8}
sleep, 100
Send, {right}{Enter 2}
Sleep, 15000
Send, {Enter}

Thank you

 

Ekkehart