Clicks on the Notification Area of TaskBar

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Guill
Posts: 139
Joined: 09 Jun 2016, 22:00

Clicks on the Notification Area of TaskBar

12 Nov 2017, 10:06

How can I do correct clicks in the notification area accurate?
The problem I have is when I indicate an X and Y mouse position: it works well in other areas of the screen, but does not happen in the notification area.

This is the script that I use to get the position of the mouse

Code: Select all

MouseGetPos, xpos, ypos
MsgBox, Mouse is in X =% xpos% Y =% ypos%.
Return
And for example, if I want to click with the right button on the H of AHK that is in the notification area, tell me this

Mouse is in X = 931 Y = 758

But when I want to use this information in any script, it does not do so accurately

Code: Select all

^ Space ::
Click, Right, 931, 758
Send {Up 4}
I get another popup windows, as if I had clicked on the most extreme point (below - on the right):

"Show desktop"
"look at the desk"



What do you recommend?
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Clicks on the Notification Area of TaskBar

12 Nov 2017, 10:24

- Try MouseMove, prior to the click.
- Aim for the middle of the icon.
- Check the coord mode.

Code: Select all

MsgBox, % A_CoordModeMouse
CoordMode, Mouse, Screen
Some code:

Code: Select all

q::
CoordMode, Mouse, Screen
MouseGetPos, vCurX, vCurY
ToolTip, % A_CoordModeMouse " " vCurX " " vCurY
return

w::
CoordMode, Mouse, Screen
;MouseMove, % vCurX, % vCurY
Click, % Format("right, {}, {}", vCurX, vCurY)
ToolTip, % A_CoordModeMouse " " vCurX " " vCurY
return

e::
;resets each time based on the default that was set in the auto-execute section
MsgBox, % A_CoordModeMouse 
CoordMode, Mouse, Screen
MsgBox, % A_CoordModeMouse
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
teadrinker
Posts: 4333
Joined: 29 Mar 2015, 09:41
Contact:

Re: Clicks on the Notification Area of TaskBar

12 Nov 2017, 10:35

I think, you don't need to make the real click. It's enough to get icon coordinates and to post WM_RBUTTONDOWN and WM_RBUTTONUP.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Clicks on the Notification Area of TaskBar

12 Nov 2017, 11:14

Btw you can usually invoke menu items directly:
Get Info from Context Menu (x64/x32 compatible) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=31971

And if you see a context menu on the screen, you can usually invoke the nth item:
context menu window messages: focus/invoke item - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=39209
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
teadrinker
Posts: 4333
Joined: 29 Mar 2015, 09:41
Contact:

Re: Clicks on the Notification Area of TaskBar

12 Nov 2017, 11:30

Do those give an ability to invoke the tray icon context menu?
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Clicks on the Notification Area of TaskBar

12 Nov 2017, 12:03

The first directly invokes a menu item without showing a menu.
The second invokes the nth item in a visible menu.

This script right-clicks the AutoHotkey tray icon. The menu will appear wherever the cursor is.

Code: Select all

q::
DetectHiddenWindows, On
WinGet, hWnd, ID, %A_ScriptDir%\AutoHotkey.ahk ahk_class AutoHotkey
;WM_LBUTTONDBLCLK := 0x203
;PostMessage, 0x404,, 0x203,, % "ahk_id " hWnd ;AHK_NOTIFYICON := 0x404
;WM_RBUTTONUP := 0x205
PostMessage, 0x404,, 0x205,, % "ahk_id " hWnd ;AHK_NOTIFYICON := 0x404
return
It may be possible to do similar things for other programs. You could use the TrayIcon library, to find details about the window that handles the tray icon messages.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
teadrinker
Posts: 4333
Joined: 29 Mar 2015, 09:41
Contact:

Re: Clicks on the Notification Area of TaskBar

12 Nov 2017, 12:19

The first directly invokes a menu item without showing a menu.
The second invokes the nth item in a visible menu.
Very useful scripts, thanks!
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Clicks on the Notification Area of TaskBar

12 Nov 2017, 12:45

@teadrinker: Cheers.

- You made me wonder if I could get a simple script to invoke the right-click menu of a tray icon.
- It requires the Acc library. Other methods that I thought of to get the text of the toolbar buttons might require accessing the memory of a remote application, i.e. Explorer, which is slightly fiddly and can risk causing crashes.
- Normally with Acc, accDoDefaultAction does what you want, i.e. clicks an item, but in this, we want a right-click.
- I'm not sure if you actually have to make the item visible and hover over it, for the right-click to work, at least, it seemed that you might do.

Code: Select all

;[Acc functions]
;Acc library (MSAA) and AccViewer download links - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=26201

q:: ;right-click tray icon (tested on Windows 7)
vName := "AutoHotkey"
;vName := "Untitled - Notepad"

WinGet, hWnd, ID, ahk_class NotifyIconOverflowWindow
if !DllCall("user32\IsWindowVisible", Ptr,hWnd)
	ControlSend, Button1, {Enter}, ahk_class Shell_TrayWnd ;show systray
CoordMode, Mouse, Screen
DetectHiddenWindows, On
ControlGet, hCtl, Hwnd,, ToolbarWindow321, ahk_class NotifyIconOverflowWindow
;WinGetPos, vCtlX, vCtlY, vCtlW, vCtlH, % "ahk_id " hCtl
;MsgBox, % Format("x{} y{} w{} h{}", vCtlX, vCtlY, vCtlW, vCtlH)

oAcc := Acc_Get("Object", "4", 0, "ahk_id " hCtl)
oRect := Acc_Location(oAcc)
;MsgBox, % Format("x{} y{} w{} h{}", oRect.x, oRect.y, oRect.w, oRect.h)
vPosX := oRect.x, vPosY := oRect.y

Loop, % oAcc.accChildCount
	if (oAcc.accName(A_Index) = vName)
	{
		oRect := Acc_Location(oAcc, A_Index)
		;MsgBox, % Format("x{} y{} w{} h{}", oRect.x, oRect.y, oRect.w, oRect.h)
		vCoords := Format("X{} Y{}", oRect.x - vPosX + 16, vPosY := oRect.y - vPosY + 16)
		;MsgBox, % vCoords
		;ToolTip, % vCoords
		MouseMove, % oRect.x + 16, % oRect.y + 16
		ControlClick, % vCoords, % "ahk_id " hCtl,, R
		break
	}
oAcc := oRect := ""
return
Last edited by jeeswg on 12 Nov 2017, 13:14, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
teadrinker
Posts: 4333
Joined: 29 Mar 2015, 09:41
Contact:

Re: Clicks on the Notification Area of TaskBar

12 Nov 2017, 13:05

It seems to work.
Other methods that I thought of to get the text of the toolbar buttons might require accessing the memory of a remote application, i.e. Explorer, which is slightly fiddly and can risk causing crashes
I wrote the script wich posts messages to a tray icon by its index. It works with Shell_TrayWnd and NotifyIconOverflowWindow both (without NotifyIconOverflowWindow showing).
However, it doesn't work with system icons for some reason.

Code: Select all

#NoTrayIcon
idx := 3
PostMessage2TrayIconIndex(idx
   , "Shell_TrayWnd"   ; "Shell_TrayWnd" or "NotifyIconOverflowWindow"
   , WM_RBUTTONUP := 0x205)
Return

PostMessage2TrayIconIndex(idx, winClass, messages*)
{
/*
typedef TRAYDATA
{
IntPtr hwnd;
uint uID;
uint uCallbackMessage;
uint Reserved;
uint Reserved2;
IntPtr hIcon;
}
*/
   static WM_USER := 0x400, TB_BUTTONCOUNT := WM_USER + 24, TB_GETBUTTON := WM_USER + 23
        , PtrSize := A_Is64bitOS ? 8 : 4, szTBBUTTON := 8 + PtrSize*3, szTRAYDATA := 16 + PtrSize*2

   DHW_Prev := A_DetectHiddenWindows
   DetectHiddenWindows, On
   if (winClass = "NotifyIconOverflowWindow")
      ControlGet, hWnd, hwnd,, ToolbarWindow321, ahk_class NotifyIconOverflowWindow
   else  {
      for k, v in ["TrayNotifyWnd", "SysPager", "ToolbarWindow32"]
         hWnd := DllCall("FindWindowEx", Ptr, k = 1 ? WinExist("ahk_class Shell_TrayWnd") : hWnd, Ptr, 0, Str, v, UInt, 0, Ptr)
   }
   WinExist("ahk_id" hWnd)
   WinGet, PID, PID

   if !IsObject(RemoteBuff := New RemoteBuffer(PID, szTRAYDATA)) {
      DetectHiddenWindows, %DHW_Prev%
      Return, 0, DllCall("MessageBox", Ptr, 0, Str, "Failed to create the remote buffer`nError " A_LastError, Str, "", UInt, 0)
   }
 
   SendMessage, TB_GETBUTTON, idx - 1, RemoteBuff.ptr
   if ! ( pTBBUTTON := RemoteBuff.Read(szTBBUTTON) )
      || !pTRAYDATA := RemoteBuff.Read(szTRAYDATA, NumGet(pTBBUTTON + 8 + PtrSize) - RemoteBuff.ptr) {
      DetectHiddenWindows, %DHW_Prev%
      Return
   }

   WinExist("ahk_id" NumGet(pTRAYDATA+0))
   uID := NumGet(pTRAYDATA + PtrSize, "UInt")
   uCallbackMessage := NumGet(pTRAYDATA + PtrSize + 4, "UInt")

   for i, message in messages
      PostMessage, uCallbackMessage, uID, message
   
   DetectHiddenWindows, %DHW_Prev%
}

class RemoteBuffer
{
   __New(PID, size)  {
      static PROCESS_VM_OPERATION := 0x8, PROCESS_VM_WRITE := 0x20
           , PROCESS_VM_READ := 0x10, MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x4
         
      if !(this.hProc := DllCall("OpenProcess", UInt, PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, Int, 0, UInt, PID, Ptr))
         Return
      
      if !(this.ptr := DllCall("VirtualAllocEx", Ptr, this.hProc, Ptr, 0, Ptr, size, UInt, MEM_COMMIT, UInt, PAGE_READWRITE, Ptr))
         Return, "", DllCall("CloseHandle", Ptr, this.hProc)
      
      this.hHeap := DllCall("GetProcessHeap", Ptr)
   }
   
   __Delete()  {
      DllCall("VirtualFreeEx", Ptr, this.hProc, Ptr, this.ptr, UInt, 0, UInt, MEM_RELEASE := 0x8000)
      DllCall("CloseHandle", Ptr, this.hProc)
      DllCall("HeapFree", Ptr, this.hHeap, UInt, 0, Ptr, this.pHeap)
   }
   
   Read(size, offset = 0)  {
      (this.pHeap && DllCall("HeapFree", Ptr, this.hHeap, UInt, 0, Ptr, this.pHeap))
      this.pHeap := DllCall("HeapAlloc", Ptr, this.hHeap, UInt, HEAP_ZERO_MEMORY := 0x8, Ptr, size, Ptr)
      if !DllCall("ReadProcessMemory", Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, this.pHeap, Ptr, size, Int, 0)
         Return, 0, DllCall("MessageBox", Ptr, 0, Str, "Failed to read data`nError " A_LastError, Str, "", UInt, 0)
      Return this.pHeap
   }
   
   Write(pLocalBuff, size, offset = 0)  {
      if !res := DllCall("WriteProcessMemory", Ptr, this.hProc, Ptr, this.ptr + offset, Ptr, pLocalBuff, Ptr, size, PtrP, writtenBytes)
         DllCall("MessageBox", Ptr, 0, Str, "Failed to write data`nError " A_LastError, Str, "", UInt, 0)
      Return writtenBytes
   }
}
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Clicks on the Notification Area of TaskBar

12 Nov 2017, 13:43

You tried Admin mode?
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Clicks on the Notification Area of TaskBar

18 Dec 2017, 14:59

INTERACTING WITH TRAY ICONS

- Some simple techniques to avoid interacting with the systray icons:
- use Run and the process path (and possibly command line parameters/switches)
- get the menu item IDs and send WM_COMMAND messages to the main window
Get Info from Context Menu (x64/x32 compatible) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=31971

- If invoking the right-click menu, and selecting a menu item, must be done, then MN_DBLCLK (0x1F1) can be used, see the example here:
Selecting a context menu item by text value - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 71#p187771

- There are two scripts here. One retrieves information about the tray icons, using one of my functions, JEE_TBGetText, that has essentially the same functionality as the TrayIcon library. There is a link to the function in the script.
[LIB] TrayIcon - Sean's TrayIcon for Unicode and 64 bit - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=1229
- The other uses tray icon information for AutoHotkey (or uTorrent) to invoke clicking/right-clicking on a tray icon.

Code: Select all

;[JEE_TBGetText function]
;GUIs via DllCall: get/set internal/external control text - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=6&t=40514&p=184829#p184829

;with tray icons there is a window
;that receives information about clicks,
;this window can be the program's main window,
;Class/Title/PName/PPath are info that can be
;used to identify that window,
;the uMsg value, is the value you use
;to send a PostMessage to that window

q:: ;systray icons - get info
DetectHiddenWindows, On
ControlGet, hTB, Hwnd,, ToolbarWindow321, ahk_class NotifyIconOverflowWindow
oTrayInfo := JEE_TBGetText(hTB, -1, "`n", "t")
vOutput := ""
for vKey1 in oTrayInfo
{
	for vKey, vValue in oTrayInfo[vKey1]
		vOutput .= (A_Index=1?"":"|") vKey ": " vValue
	vOutput .= "`r`n"
}
MsgBox, % Clipboard := vOutput
return

;==================================================

;e.g. using WM_RBUTTONUP will invoke a tray icon's
;right-click menu, at the point where the cursor is

w:: ;invoke systray icon (send left/right clicks)
DetectHiddenWindows, On

;AutoHotkey tray icon
WinGet, hWnd, ID, %A_ScriptDir%\AutoHotkey.ahk ahk_class AutoHotkey
vMsg := 1028 ;0x404

;uTorrent tray icon
;WinGet, hWnd, ID, μTorrent
;vMsg := 32769 ;0x8001

;WM_LBUTTONDOWN := 0x201
;PostMessage, % vMsg,, 0x201,, % "ahk_id " hWnd
;WM_LBUTTONUP := 0x202
;PostMessage, % vMsg,, 0x202,, % "ahk_id " hWnd
;WM_LBUTTONDBLCLK := 0x203
;PostMessage, % vMsg,, 0x203,, % "ahk_id " hWnd
;WM_RBUTTONDOWN := 0x204
;PostMessage, % vMsg,, 0x204,, % "ahk_id " hWnd
;WM_RBUTTONUP := 0x205
PostMessage, % vMsg,, 0x205,, % "ahk_id " hWnd
return

;==================================================
Links:
Detect if PhonerLite is running - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=41340
[Solved] Clicking on the AHK icon in the System Tray? - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=38761
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: DataLife, ShatterCoder and 149 guests