Jump to content

How to block click on systray icon?


kosamja
 Share

Recommended Posts

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

 

Link to comment
Share on other sites

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

 

 

Link to comment
Share on other sites

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

Link to comment
Share on other sites

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...