Jump to content



Photo

Tray notifications redirector


  • Please log in to reply
23 replies to this topic

#1 Yashied

Yashied

    Happy in Moscow

  • MVPs
  • 2,512 posts

Posted 19 May 2012 - 11:05 AM

LAST VERSION - 1.0
19-May-12

I think many of you would like to perform some action (for example, to call the dialog box) when a user clicks on the tray tip. Here is a simple way to do it. Unfortunately, without .dll do not seem possible. Note, only AutoIt window can be registered as a source window, see example.


Posted Image



AITray.dll (x86 and x64) + Example

Attached File  AITray.zip   18.65K   285 downloads


Example

AutoIt         
#Include <WindowsConstants.au3> Opt('TrayAutoPause', 0) Opt('WinTitleMatchMode', 3) Opt('WinWaitDelay', 0) Global Const $NIN_BALLOONSHOW = $WM_USER + 2 Global Const $NIN_BALLOONHIDE = $WM_USER + 3 Global Const $NIN_BALLOONUSERCLICK = $WM_USER + 5 Global Const $NIN_BALLOONTIMEOUT = $WM_USER + 4 $hForm = GUICreate('') If @AutoItX64 Then     $hDll = DllOpen(@ScriptDir & 'AITray_x64.dll') Else     $hDll = DllOpen(@ScriptDir & 'AITray.dll') EndIf If $hDll <> -1 Then     $Ret = DllCall($hDll, 'int', 'AISetTrayRedirection', 'hwnd', WinGetHandle(AutoItWinGetTitle()), 'hwnd', $hForm)     If (@Error) Or (Not $Ret[0]) Then         DllClose($hDll)         Exit     EndIf Else     Exit EndIf GUIRegisterMsg($WM_USER + 1, 'WM_TRAYNOTIFY') TrayTip('Tip', 'This is a tray tip, click here.', 10, 1) While 1     Sleep(1000) WEnd DllCall($hDll, 'int', 'AIRemoveTrayRedirection') DllClose($hDll) Func WM_TRAYNOTIFY($hWnd, $iMsg, $wParam, $lParam)     Switch $hWnd         Case $hForm             Switch $lParam                 Case $NIN_BALLOONSHOW                     ConsoleWrite('Balloon tip show.' & @CR)                 Case $NIN_BALLOONHIDE                     ConsoleWrite('Balloon tip hide.' & @CR)                 Case $NIN_BALLOONUSERCLICK                     ConsoleWrite('Balloon tip click.' & @CR)                 Case $NIN_BALLOONTIMEOUT                     ConsoleWrite('Balloon tip close.' & @CR)             EndSwitch     EndSwitch EndFunc   ;==>WM_TRAYNOTIFY

Edited by Yashied, 19 May 2012 - 11:07 AM.

  • JScript and Venix like this





#2 JScript

JScript

    Goodbye everybody, I got tired of this system adopted here!

  • Active Members
  • PipPipPipPipPipPip
  • 1,062 posts

Posted 19 May 2012 - 11:43 AM

Wow, very niceee, I liked! ***** from me.
And about this DLL?

Regards,

João Carlos.
http://notebook.forumais.com (Forum Maintenance Notebooks and Desktop)http://autoitbrasil.com/ (AutoIt v3 Brazil!!!)
Spoiler

Posted Image Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere!       


#3 Yashied

Yashied

    Happy in Moscow

  • MVPs
  • 2,512 posts

Posted 19 May 2012 - 02:11 PM

And about this DLL?

Plain Text         
#WM_TRAYNOTIFY = #WM_USER + 1 Prototype.l SetWindowSubclass(*HWnd, *HProc, ID.i = 1000, IParam.i = 0) Prototype.l RemoveWindowSubclass(*HWnd, *HProc, ID.i = 1000) Global Comctl32.l = OpenLibrary(#PB_Any, "comctl32.dll") Global User32.l = OpenLibrary(#PB_Any, "user32.dll") Global AutoIt.i = 0 Global Target.i = 0 Procedure.i SubclassProc(*HWnd, Msg.l, *WParam, *LParam, *ID, *IParam)     Select Msg         Case #WM_TRAYNOTIFY             Select *LParam                 Case #NIN_BALLOONSHOW, #NIN_BALLOONHIDE, #NIN_BALLOONUSERCLICK, #NIN_BALLOONTIMEOUT                     If Target                         CallFunction(User32, "PostMessageW", Target, Msg, *WParam, *LParam)                     EndIf             EndSelect     EndSelect     ProcedureReturn CallFunction(Comctl32, "DefSubclassProc", *HWnd, Msg, *WParam, *LParam) EndProcedure ProcedureDLL.l AIRemoveTrayRedirection()     If Not AutoIt         ProcedureReturn 0     EndIf     RemoveWindowSubclass.RemoveWindowSubclass = GetFunction(Comctl32, "RemoveWindowSubclass")     If IsWindow(AutoIt)         If Not RemoveWindowSubclass(AutoIt, @SubclassProc())             ProcedureReturn 0         EndIf     EndIf     Target = 0     AutoIt = 0     ProcedureReturn 1 EndProcedure ProcedureDLL.l AISetTrayRedirection(*HAutoIt, *HTarget)     If (Not *HAutoIt) Or (Not *HTarget)         ProcedureReturn 0     EndIf     If AutoIt         If Not AIRemoveTrayRedirection()             ProcedureReturn 0         EndIf     EndIf     SetWindowSubclass.SetWindowSubclass = GetFunction(Comctl32, "SetWindowSubclass")     If Not SetWindowSubclass(*HAutoIt, @SubclassProc())         ProcedureReturn 0     EndIf     AutoIt = *HAutoIt     Target = *HTarget     ProcedureReturn 1 EndProcedure


#4 JScript

JScript

    Goodbye everybody, I got tired of this system adopted here!

  • Active Members
  • PipPipPipPipPipPip
  • 1,062 posts

Posted 20 May 2012 - 03:46 AM

Ok, Is there any chance of making entirely in Autoit?

Regards,

João Carlos.
http://notebook.forumais.com (Forum Maintenance Notebooks and Desktop)http://autoitbrasil.com/ (AutoIt v3 Brazil!!!)
Spoiler

Posted Image Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere!       


#5 Yashied

Yashied

    Happy in Moscow

  • MVPs
  • 2,512 posts

Posted 20 May 2012 - 08:21 AM

Is there any chance of making entirely in Autoit?


No, DllCallbackRegister() kill the script.

#6 wakillon

wakillon

    Tiny Tools Coder

  • Active Members
  • PipPipPipPipPipPip
  • 2,481 posts

Posted 20 May 2012 - 08:44 AM

Again a nice and new feature !
Thanks Yashield ! ;)

  AutoIt Version : 3.3.8.1/3.3.9.4 SciTE 3.3.0 Language:040C OS:WIN_7/ CPU:X64 OS:X64 

  Last updated Scripts and executables with full embedded files are available on : GoogleCode 


#7 Venix

Venix

    Adventurer

  • Active Members
  • PipPip
  • 131 posts

Posted 20 May 2012 - 12:54 PM

Love it ;), much better than having to set the coordinates.
Posted Image

#8 UEZ

UEZ

    Never say never

  • MVPs
  • 3,605 posts

Posted 20 May 2012 - 01:13 PM

What language is the code from the DLL?

Br,
UEZ

 
The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯


#9 Yashied

Yashied

    Happy in Moscow

  • MVPs
  • 2,512 posts

Posted 20 May 2012 - 06:54 PM

What language is the code from the DLL?


PureBasic 4.50

#10 JScript

JScript

    Goodbye everybody, I got tired of this system adopted here!

  • Active Members
  • PipPipPipPipPipPip
  • 1,062 posts

Posted 20 May 2012 - 08:24 PM

PureBasic!!!!

Wow, I will endeavor to eliminate this dll, leaving only in AutoIt... ;)

Regards,

João Carlos.

Edited by JScript, 20 May 2012 - 08:25 PM.

http://notebook.forumais.com (Forum Maintenance Notebooks and Desktop)http://autoitbrasil.com/ (AutoIt v3 Brazil!!!)
Spoiler

Posted Image Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere!       


#11 ProgAndy

ProgAndy

    You need AutoItObject

  • MVPs
  • 2,508 posts

Posted 20 May 2012 - 08:32 PM

No, DllCallbackRegister() kill the script.

We just need a small ASM-stub to hook the window procedure and forwards WM_TRAYNOTIFY when the TrayClick is registered.
Edit: Does this seem about right? Values not yet read from stack, only symbols:
use32 test uMsg, WM_TRAYNOTIFY jz skip_notify push lparam push wparam push uMsg push hWndRedirect call PostMessage skip_notify: push lparam push wparam push uMsg push hWnd call DefSubclassProc ret 24

Edited by ProgAndy, 20 May 2012 - 08:48 PM.

*GERMAN* Posted Image [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

#12 wraithdu

wraithdu

    I am less fun than a twisted ankle.

  • MVPs
  • 2,137 posts

Posted 21 May 2012 - 03:19 PM

Ok, Is there any chance of making entirely in Autoit?

No, DllCallbackRegister() kill the script.

Pure AutoIt works for me...

AutoIt         
#include <windowsconstants.au3> Opt('TrayAutoPause', 0) Opt('WinTitleMatchMode', 3) Opt('WinWaitDelay', 0) Opt('TrayMenuMode', 3) Global Const $WM_TRAYNOTIFY = $WM_USER + 1 Global Const $NIN_BALLOONSHOW = $WM_USER + 2 Global Const $NIN_BALLOONHIDE = $WM_USER + 3 Global Const $NIN_BALLOONUSERCLICK = $WM_USER + 5 Global Const $NIN_BALLOONTIMEOUT = $WM_USER + 4 Global Const $subID = 1234 Global $iTip = 2 Global $psub = DllCallbackRegister("_subclass", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Global $hForm = GUICreate('') DllCall("comctl32.dll", "bool", "SetWindowSubclass", "hwnd", WinGetHandle(AutoItWinGetTitle()), "ptr", DllCallbackGetPtr($psub), "uint_ptr", $subID, "dword_ptr", 0) GUIRegisterMsg($WM_TRAYNOTIFY, 'WM_TRAYNOTIFY') Global $iShow = TrayCreateItem("Show New Tip") TrayCreateItem("") Global $iExit = TrayCreateItem("Exit") TrayTip('Tip', 'This is a tray tip, click here.', 10, 1) While 1     Switch TrayGetMsg()         Case $iShow             TrayTip('Tip', 'This is a tray tip, click here. [ ' & $iTip & ' ]', 10, 1)             $iTip += 1         Case $iExit             ExitLoop     EndSwitch WEnd DllCall("comctl32.dll", "bool", "RemoveWindowSubclass", "hwnd", WinGetHandle(AutoItWinGetTitle()), "ptr", DllCallbackGetPtr($psub), "uint_ptr", $subID) DllCallbackFree($psub) Func WM_TRAYNOTIFY($hWnd, $iMsg, $wParam, $lParam)     Switch $hWnd         Case $hForm             Switch $lParam                 Case $NIN_BALLOONSHOW                     ConsoleWrite('Balloon tip show.' & @CR)                 Case $NIN_BALLOONHIDE                     ConsoleWrite('Balloon tip hide.' & @CR)                 Case $NIN_BALLOONUSERCLICK                     ConsoleWrite('Balloon tip click.' & @CR)                 Case $NIN_BALLOONTIMEOUT                     ConsoleWrite('Balloon tip close.' & @CR)             EndSwitch     EndSwitch EndFunc   ;==>WM_TRAYNOTIFY Func _subclass($hwnd, $uMsg, $wParam, $lParam, $uIdSubclass, $dwRefData)     #forceref $hwnd, $uMsg, $wParam, $lParam, $uIdSubclass, $dwRefData     Switch $uMsg         Case $WM_TRAYNOTIFY             Switch $uIdSubclass                 Case $subID                     Switch $lParam                         Case $NIN_BALLOONSHOW, $NIN_BALLOONHIDE, $NIN_BALLOONUSERCLICK, $NIN_BALLOONTIMEOUT                             If $hForm Then                                 DllCall("user32.dll", "bool", "PostMessageW", "hwnd", $hForm, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam)                             EndIf                     EndSwitch             EndSwitch     EndSwitch     Local $ret = DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hwnd, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam)     Return $ret[0] EndFunc

However as noted in MSDN in the comments, there is no differentiation between a timeout and a close event. Seems like a Windows bug.

Edited by wraithdu, 21 May 2012 - 04:03 PM.

  • JScript likes this

#13 JScript

JScript

    Goodbye everybody, I got tired of this system adopted here!

  • Active Members
  • PipPipPipPipPipPip
  • 1,062 posts

Posted 21 May 2012 - 03:45 PM

Yeah, I know it could be done in AutoIt! ;)

Regards,

João Carlos.
http://notebook.forumais.com (Forum Maintenance Notebooks and Desktop)http://autoitbrasil.com/ (AutoIt v3 Brazil!!!)
Spoiler

Posted Image Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere!       


#14 Yashied

Yashied

    Happy in Moscow

  • MVPs
  • 2,512 posts

Posted 21 May 2012 - 07:01 PM

That's why I did not use DllCallbackRegister().

#15 Yashied

Yashied

    Happy in Moscow

  • MVPs
  • 2,512 posts

Posted 21 May 2012 - 07:05 PM

The problem in the default AutoIt tray menu... but with .dll everything works fine anywhere. What's the catch?

Edited by Yashied, 21 May 2012 - 07:10 PM.


#16 wraithdu

wraithdu

    I am less fun than a twisted ankle.

  • MVPs
  • 2,137 posts

Posted 21 May 2012 - 07:30 PM

I did it with a custom menu to exit the loop and gracefully unsubclass the window and free the callback before exiting. Works fine every time. Did you try my version?

#17 Yashied

Yashied

    Happy in Moscow

  • MVPs
  • 2,512 posts

Posted 21 May 2012 - 07:35 PM

wraithdu, please comment the following lines and try to close the script from the tray.

;Opt('TrayAutoPause', 0) Opt('WinTitleMatchMode', 3) Opt('WinWaitDelay', 0) ;Opt('TrayMenuMode', 3)

Edited by Yashied, 21 May 2012 - 07:35 PM.


#18 UEZ

UEZ

    Never say never

  • MVPs
  • 3,605 posts

Posted 21 May 2012 - 07:36 PM

Can confirm that wraithdu's code works properly on my machine (Win7 x64 running it at x86 & x64 mode)!

Br,
UEZ

 
The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯


#19 wraithdu

wraithdu

    I am less fun than a twisted ankle.

  • MVPs
  • 2,137 posts

Posted 21 May 2012 - 08:08 PM

wraithdu, please comment the following lines and try to close the script from the tray.

;Opt('TrayAutoPause', 0) Opt('WinTitleMatchMode', 3) Opt('WinWaitDelay', 0) ;Opt('TrayMenuMode', 3)

Why would I purposely break it? If it is required to change the menu mode so you can exit properly, then do it! You must unsubclass and unregister the callback. You can't do that from the default tray menu, unless you want to add a function with OnAutoItExitRegister (didn't try, but would probably also work).

Edited by wraithdu, 21 May 2012 - 08:11 PM.


#20 wraithdu

wraithdu

    I am less fun than a twisted ankle.

  • MVPs
  • 2,137 posts

Posted 21 May 2012 - 08:13 PM

So do it this way:
AutoIt         
#include <windowsconstants.au3> Opt('TrayAutoPause', 0) Opt('WinTitleMatchMode', 3) Opt('WinWaitDelay', 0) Opt('TrayMenuMode', 2) Global Const $WM_TRAYNOTIFY = $WM_USER + 1 Global Const $NIN_BALLOONSHOW = $WM_USER + 2 Global Const $NIN_BALLOONHIDE = $WM_USER + 3 Global Const $NIN_BALLOONUSERCLICK = $WM_USER + 5 Global Const $NIN_BALLOONTIMEOUT = $WM_USER + 4 Global Const $subID = 1234 Global $iTip = 2 Global $psub = DllCallbackRegister("_subclass", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr") Global $hForm = GUICreate('') DllCall("comctl32.dll", "bool", "SetWindowSubclass", "hwnd", WinGetHandle(AutoItWinGetTitle()), "ptr", DllCallbackGetPtr($psub), "uint_ptr", $subID, "dword_ptr", 0) GUIRegisterMsg($WM_TRAYNOTIFY, 'WM_TRAYNOTIFY') OnAutoItExitRegister("SafeExit") Global $iShow = TrayCreateItem("Show New Tip") ;~ TrayCreateItem("") ;~ Global $iExit = TrayCreateItem("Exit") TrayTip('Tip', 'This is a tray tip, click here.', 10, 1) While 1     Switch TrayGetMsg()         Case $iShow             TrayTip('Tip', 'This is a tray tip, click here. [ ' & $iTip & ' ]', 10, 1)             $iTip += 1 ;~         Case $iExit ;~             ExitLoop     EndSwitch ;~  Sleep(1000) WEnd ;~ DllCall("comctl32.dll", "bool", "RemoveWindowSubclass", "hwnd", WinGetHandle(AutoItWinGetTitle()), "ptr", DllCallbackGetPtr($psub), "uint_ptr", $subID) ;~ DllCallbackFree($psub) Func SafeExit()     ConsoleWrite("exiting..." & @CRLF)     DllCall("comctl32.dll", "bool", "RemoveWindowSubclass", "hwnd", WinGetHandle(AutoItWinGetTitle()), "ptr", DllCallbackGetPtr($psub), "uint_ptr", $subID)     DllCallbackFree($psub) EndFunc Func WM_TRAYNOTIFY($hWnd, $iMsg, $wParam, $lParam)     Switch $hWnd         Case $hForm             Switch $lParam                 Case $NIN_BALLOONSHOW                     ConsoleWrite('Balloon tip show.' & @CR)                 Case $NIN_BALLOONHIDE                     ConsoleWrite('Balloon tip hide.' & @CR)                 Case $NIN_BALLOONUSERCLICK                     ConsoleWrite('Balloon tip click.' & @CR)                 Case $NIN_BALLOONTIMEOUT                     ConsoleWrite('Balloon tip close.' & @CR)             EndSwitch     EndSwitch EndFunc   ;==>WM_TRAYNOTIFY Func _subclass($hwnd, $uMsg, $wParam, $lParam, $uIdSubclass, $dwRefData)     #forceref $hwnd, $uMsg, $wParam, $lParam, $uIdSubclass, $dwRefData     Switch $uMsg         Case $WM_TRAYNOTIFY             Switch $uIdSubclass                 Case $subID                     Switch $lParam                         Case $NIN_BALLOONSHOW, $NIN_BALLOONHIDE, $NIN_BALLOONUSERCLICK, $NIN_BALLOONTIMEOUT                             If $hForm Then                                 DllCall("user32.dll", "bool", "PostMessageW", "hwnd", $hForm, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam)                             EndIf                     EndSwitch             EndSwitch     EndSwitch     Local $ret = DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hwnd, "uint", $uMsg, "wparam", $wParam, "lparam", $lParam)     Return $ret[0] EndFunc

Edited by wraithdu, 21 May 2012 - 08:16 PM.





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users