Jump to content
kosamja

How to block click on systray icon?

Recommended Posts

kosamja

I am trying to block click on systray icon so that I can show custom window instead of window that appears when systray icon is clicked, but systray icon stays stuck in pressed state. How to make systray icon to forget that it was clicked?

SnapCrab_NoName_2017-11-22_12-46-5_No-00.png

#NoTrayIcon
#RequireAdmin
#include <Constants.au3>
#include <GUIConstants.au3>
#include <WinAPI.au3>
#include <GuiToolbar.au3>
#include <SendMessage.au3>
#include <Process.au3>

Opt('WinWaitDelay', 0)
Opt('MouseClickDelay', 0)
Opt('MouseClickDownDelay', 0)
Opt('MouseClickDragDelay', 0)
Opt('SendKeyDelay', 0)
Opt('SendKeyDownDelay', 0)
Opt('WinTitleMatchMode', 3)

_RegisterInputDeviceHook('mouse')
While 1
   Sleep(1000)
WEnd

Func _RegisterInputDeviceHook($sMode = 'mouse', $sCallbackFunc = '', $sExitOnError = True)
   ;$sMode values: mouse or keyboard
   Switch $sMode
   Case 'mouse'
      $sHookType = $WH_MOUSE_LL
      If $sCallbackFunc = '' Then $sCallbackFunc = '_MouseHookProc'
   Case 'keyboard'
      $sHookType = $WH_KEYBOARD_LL
      If $sCallbackFunc = '' Then $sCallbackFunc = '_KeyboardHookProc'
   Case Else
      $sHookType = ''
   EndSwitch
   If $sCallbackFunc <> '' and $sHookType <> '' Then
      $sInputDeviceProc = DllCallbackRegister($sCallbackFunc, 'long', 'int;wparam;lparam')
      $sInputDeviceHook = _WinAPI_SetWindowsHookEx($sHookType, DllCallbackGetPtr($sInputDeviceProc), _WinAPI_GetModuleHandle(0))
   Else
      $sInputDeviceProc = 0
      $sInputDeviceHook = 0
   EndIf
   Switch $sInputDeviceHook
   Case 0
      If $sExitOnError = True Then
         MsgBox($MB_OK, 'Error', 'Failed to register ' & $sMode & ' hook.')
         Exit
      Else
         Return SetError(1, 0, 0)
      EndIf
   Case Else
      Return SetError(0, $sInputDeviceProc, $sInputDeviceHook)
   EndSwitch
EndFunc

Func _MouseHookProc($nCode, $wParam, $lParam)
   If $wParam = $WM_LBUTTONUP and $nCode >= 0 Then
      $tPointScreen = _WinAPI_GetMousePos()
      $sMousePosX = DllStructGetData($tPointScreen, 'X')
      $sMousePosY = DllStructGetData($tPointScreen, 'Y')
      $sControlHandle = _WinAPI_WindowFromPoint($tPointScreen)
      $sControlClass = _WinAPI_GetClassName($sControlHandle)
      $sWndHandle = _WinAPI_GetAncestor($sControlHandle, $GA_ROOT)
      $sWndClass = _WinAPI_GetClassName($sWndHandle)
      If not WinExists('[CLASS:ImageDrag]') and $sControlClass = 'ToolbarWindow32' and ($sWndClass = 'Shell_TrayWnd' or $sWndClass = 'NotifyIconOverflowWindow') Then
         $sSystrayIconInfo = _GetSystrayIconUnderMouseInfo($sControlHandle)
         If IsArray($sSystrayIconInfo) Then
            _SendMessage($sControlHandle, $WM_CANCELMODE, 0, 0)
            If _ProcessGetName(WinGetProcess($sSystrayIconInfo[3])) = 'explorer.exe' and $sSystrayIconInfo[4] = 1226 Then
               ;ignore
            Else
               _SendMessage($sSystrayIconInfo[3], $sSystrayIconInfo[5], _WinAPI_MakeLong($sMousePosX, $sMousePosY), _WinAPI_MakeLong($WM_LBUTTONDOWN, $sSystrayIconInfo[5]))
            EndIf
         EndIf
      EndIf
   EndIf
   Return _WinAPI_CallNextHookEx('', $nCode, $wParam, $lParam)
EndFunc

Func _GetSystrayIconUnderMouseInfo($sSystrayHandle)
   Local $sReadBytes
   Local $sIconInfo[6]
   $tTrayData = DllStructCreate('hwnd hWnd;uint uID;uint uCallbackMessage;dword Reserved[2];ptr hIcon')
   $tPointWnd = _WinAPI_GetMousePos(True, $sSystrayHandle)
   $sIconIndex = _GUICtrlToolbar_HitTest($sSystrayHandle, DllStructGetData($tPointWnd, 'X'), DllStructGetData($tPointWnd, 'Y'))
   If $sIconIndex < 0 Then Return SetError(1, 0, '')
   $sProcessHandle = _WinAPI_OpenProcess(BitOR($PROCESS_VM_OPERATION, $PROCESS_VM_READ), False, WinGetProcess(WinGetHandle('[CLASS:Shell_TrayWnd]')), True)
   If $sProcessHandle = 0 Then Return SetError(2, 0, '')
   $sIconCommandId = _GUICtrlToolbar_IndexToCommand($sSystrayHandle, $sIconIndex)
   $sIconParam = _GUICtrlToolbar_GetButtonParam($sSystrayHandle, $sIconCommandId)
   _WinAPI_ReadProcessMemory($sProcessHandle, $sIconParam, DllStructGetPtr($tTrayData), DllStructGetSize($tTrayData), $sReadBytes)
   _WinAPI_CloseHandle($sProcessHandle)
   $sIconInfo[0] = $sIconIndex
   $sIconInfo[1] = $sIconCommandId
   $sIconInfo[2] = _GUICtrlToolbar_GetButtonText($sSystrayHandle, $sIconCommandId)
   $sIconInfo[3] = DllStructGetData($tTrayData, 'hWnd')
   $sIconInfo[4] = DllStructGetData($tTrayData, 'uID')
   $sIconInfo[5] = DllStructGetData($tTrayData, 'uCallbackMessage')
   Return $sIconInfo
EndFunc

 

Share this post


Link to post
Share on other sites
Danyfirex

Hello. I would do this:

 

Create the Mouse Hook.

Handle handle Mouse Down inputs.

Get the Mouse Position to check the systray item clicked.

Return 1 for block the mouse down event (This should avoid the pressed stated)

then check the  Mouse Up. (check position of last mouse Down and maybe time for correct pressed time)

Block the event returning 1. then show show custom window.

 

Saludos

 

 

Share this post


Link to post
Share on other sites
kosamja
30 minutes ago, Danyfirex said:

Handle handle Mouse Down inputs.

Get the Mouse Position to check the systray item clicked.

Return 1 for block the mouse down event (This should avoid the pressed stated)

I first tried that, but blocking mouse down prevents icon dragging

Share this post


Link to post
Share on other sites
Danyfirex

Maybe trying repainting or blocking the paint event. 

 

Saludos

Share this post


Link to post
Share on other sites
kosamja

Its not related to repainting, problem is that icon stays pressed and when another icon gets pressed, gui of previously pressed icon also appears

Share this post


Link to post
Share on other sites
KaFu

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.