 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
gwarble
Joined: 23 May 2009 Posts: 126 Location: north bay, california
|
Posted: Thu Sep 10, 2009 5:33 am Post subject: Notify() v0.44 - multiple tray area notifications |
|
|
i wrote this function to create and position multiple simultaneous tray area notifications, from any number of different scripts... Notify() can display fully-customizable, timed (or not) notification windows that can display any type of information quickly and easily (i like using it for debugging; Notify("var",var) works well), each of which can perform actions when clicked or time out, etc... try it out and let me know what you think!
stdlib compliant, just drop in your Lib folder and call Notify() to see it in action
no globals, no dependencies, _Notify_***: labels only
Notify() v0.44 - Download Notify.ahk or read the incomplete Documentation
| Code: | ;;;;;;;
;;;;; Notify() 0.44 made by gwarble - sept 09
;;; multiple tray area notifications
; thanks to Rhys/engunneer/HugoV/Forum Posters
;
; Notify([Title,Message,Duration,Options,Image])
;
; Title [!!!] "" to omit title line
; Message [] "" to omit message line
; Duration [15] seconds to show notification
; 0 to flash until clicked
; <0 to ExitApp on click/timeout
; -0 not yet implemented (perm/exit)
; Options string of options... see function
; [SI=999 GC=Blue...] most options are remembered (static)
; "Reset" to restore default options
; if you want to show as well, use NO=Reset
; "Wait" to wait for a notification ***
; Image [] Image file name/library or
; number of icon in shell32.dll
; Gui Number to "Wait" for ***
;
; Return Gui Number used ***
; 0 if failed (too many)
;
Notify(Title="!!!",Message="",Duration=30,Options="",Image="")
{
Static ;Options string: "TS=12 GC=Blue..."
static GF := 50 ; Gui First Number ;= override Gui: # used
static GL := 74 ; Gui Last Number ;= between GF and GL
static GC := "FFFFAA" ; Gui Color ; ie: don't use GF<=Gui#<=GL
static GR := 9 ; Gui Radius ; elsewhere in your script
static GT := "Off" ; Gui Transparency
static TS := 8 ; Title Font Size
static TW := 625 ; Title Font Weight
static TC := "Black" ; Title Font Color
static TF := "Arial" ; Title Font Face
static MS := 8 ;Message Font Size
static MW := 550 ;Message Font Weight
static MC := "Black" ;Message Font Color
static MF := "Arial" ;Message Font Face
static BC := "Black" ; Border Colors
static BW := 2 ; Border Width/Thickness
static BR := 13 ; Border Radius
static BT := 105 ; Border Transpacency
static BF := 150 ; Border Flash Speed
static SI := 350 ; Speed In (AnimateWindow)
static SC := 100 ; Speed Clicked (AnimateWindow)
static ST := 450 ; Speed TimeOut (AnimateWindow)
static IW := 32 ; Image Width
static IH := 32 ; Image Height
static IN := 0 ; Image Icon Number (from Image)
local AC, AT ;Actions Clicked/Timeout
local _Notify_Action, ImageOptions, GY, OtherY
_Notify_:
local NO := 0 ;NO is Notify Option [NO=Reset] ;local
If (Options)
{
IfInString, Options, =
{
Loop,Parse,Options,%A_Space%
If (Option:= SubStr(A_LoopField,1,2))
%Option%:= SubStr(A_LoopField,4)
If NO = Reset
{
Options := "GF=50 GL=74 GC=FFFFAA GR=9 GT=Off TS=8 TW=625 TC=Black TF=Arial MS=8 MW=550 MC=Black MF=Arial BC=Black BW=2 BR=9 BT=105 BF=150 SC=300 SI=250 ST=100 IW=32 IH=32 IN=0"
Goto, _Notify_
}
}
Else If Options = Wait
Goto, _Notify_Wait_
}
GN := GF
Loop
IfNotInString, NotifyList, % "|" GN
Break
Else
If (++GN > GL)
Return 0 ;=== too many notifications open!
NotifyList .= "|" GN
GN2 := GN + GL - GF + 1
If AC <>
ActionList .= "|" GN "=" AC
Prev_DetectHiddenWindows := A_DetectHiddenWindows
Prev_TitleMatchMode := A_TitleMatchMode
DetectHiddenWindows On
SetTitleMatchMode 1
If (WinExist("NotifyGui")) ;=== find all Notifications from ALL scripts, for placement
WinGetPos, OtherX, OtherY ;=== change this to a loop for all open notifications?
DetectHiddenWindows %Prev_DetectHiddenWindows%
SetTitleMatchMode %Prev_TitleMatchMode%
Gui, %GN%:-Caption +ToolWindow +AlwaysOnTop -Border
Gui, %GN%:Color, %GC%
Gui, %GN%:Font, w%TW% s%TS% c%TC%, %TF%
If (Image)
{
If FileExist(Image)
Gui, %GN%:Add, Picture, w%IW% h%IH% Icon%IN%, % Image
Else
Gui, %GN%:Add, Picture, w%IW% h%IH% Icon%Image%, c:\windows\system32\shell32.dll
ImageOptions = x+10
}
If Title <>
Gui, %GN%:Add, Text, % ImageOptions, % Title
Gui, %GN%:Font, w%MW% s%MS% c%MC%, %MF%
If ((Title) && (Message))
Gui, %GN%:Margin, , -5
If Message <>
Gui, %GN%:Add, Text,, % Message
If ((Title) && (Message))
Gui, %GN%:Margin, , 8
Gui, %GN%:Show, Hide, NotifyGui
Gui %GN%:+LastFound
WinGetPos, GX, GY, GW, GH
Gui, %GN%:Add, Text, x0 y0 w%GW% h%GH% g_Notify_Action BackgroundTrans
If (GR)
WinSet, Region, % "0-0 w" GW " h" GH " R" GR "-" GR
If (GT)
WinSet, Transparent, % GT
SysGet, Workspace, MonitorWorkArea
NewX := WorkSpaceRight-GW-5
If (OtherY)
NewY := OtherY-GH-5
Else
NewY := WorkspaceBottom-GH-5
If NewY < % WorkspaceTop
NewY := WorkspaceBottom-GH-5
Gui, %GN2%:-Caption +ToolWindow +AlwaysOnTop -Border +E0x20
Gui, %GN2%:Color, %BC%
Gui %GN2%:+LastFound
If (BR)
WinSet, Region, % "0-0 w" GW+(BW*2) " h" GH+(BW*2) " R" BR "-" BR
If (BT)
WinSet, Transparent, % BT
Gui, %GN2%:Show, % "Hide x" NewX-BW " y" NewY-BW " w" GW+(BW*2) " h" GH+(BW*2)
Gui, %GN%:Show, % "Hide x" NewX " y" NewY, NotifyGui
Gui %GN%:+LastFound
If SI
DllCall("AnimateWindow","UInt",WinExist(),"Int",SI,"UInt","0x00040008")
Else
Gui, %GN%:Show, NA, NotifyGui
Gui, %GN2%:Show, NA
WinSet, AlwaysOnTop, On
If Duration < 0
Exit := GN
If (Duration)
SetTimer, % "_Notify_Kill_" GN - GF + 1, % - Abs(Duration) * 1000
Else
SetTimer, % "_Notify_Flash_" GN - GF + 1, % BF
Return % GN
;==========================================================================
;========================================== when a notification is clicked:
_Notify_Action:
;Critical
SetTimer, % "_Notify_Kill_" A_Gui - GF + 1, Off
Gui, % A_Gui + GL - GF + 1 ":Destroy"
Gui %A_Gui%:+LastFound
If SC
DllCall("AnimateWindow","UInt",WinExist(),"Int",SC,"UInt", "0x00050001")
Gui, %A_Gui%:Destroy
If (ActionList)
Loop,Parse,ActionList,|
If ((Action := SubStr(A_LoopField,1,2)) = A_Gui)
{
Temp_Notify_Action:= SubStr(A_LoopField,4)
StringReplace, ActionList, ActionList, % "|" A_Gui "=" Temp_Notify_Action, , All
If IsLabel(_Notify_Action := Temp_Notify_Action)
Gosub, %_Notify_Action%
_Notify_Action =
Break
}
StringReplace, NotifyList, NotifyList, % "|" GN, , All
SetTimer, % "_Notify_Flash_" A_Gui - GF + 1, Off
If (Exit = A_Gui)
ExitApp
Return
;==========================================================================
;=========================================== when a notification times out:
_Notify_Kill_1:
_Notify_Kill_2:
_Notify_Kill_3:
_Notify_Kill_4:
_Notify_Kill_5:
_Notify_Kill_6:
_Notify_Kill_7:
_Notify_Kill_8:
_Notify_Kill_9:
_Notify_Kill_10:
_Notify_Kill_11:
_Notify_Kill_12:
_Notify_Kill_13:
_Notify_Kill_14:
_Notify_Kill_15:
_Notify_Kill_16:
_Notify_Kill_17:
_Notify_Kill_18:
_Notify_Kill_19:
_Notify_Kill_20:
_Notify_Kill_21:
_Notify_Kill_22:
_Notify_Kill_23:
_Notify_Kill_24:
_Notify_Kill_25:
;Critical
StringReplace, GK, A_ThisLabel, _Notify_Kill_
SetTimer, _Notify_Flash_%GK%, Off
GK += GF - 1
Gui, % GK + GL - GF + 1 ":Destroy"
Gui %GK%:+LastFound
If ST
DllCall("AnimateWindow","UInt",WinExist(),"Int",ST,"UInt", "0x00050001")
Gui, %GK%:Destroy
StringReplace, NotifyList, NotifyList, % "|" GK
If (Exit = GK)
ExitApp
Return
;==========================================================================
;======================================== flashes a permanent notification:
_Notify_Flash_1:
_Notify_Flash_2:
_Notify_Flash_3:
_Notify_Flash_4:
_Notify_Flash_5:
_Notify_Flash_6:
_Notify_Flash_7:
_Notify_Flash_8:
_Notify_Flash_9:
_Notify_Flash_10:
_Notify_Flash_11:
_Notify_Flash_12:
_Notify_Flash_13:
_Notify_Flash_14:
_Notify_Flash_15:
_Notify_Flash_16:
_Notify_Flash_17:
_Notify_Flash_18:
_Notify_Flash_19:
_Notify_Flash_20:
_Notify_Flash_21:
_Notify_Flash_22:
_Notify_Flash_23:
_Notify_Flash_24:
_Notify_Flash_25:
StringReplace, FlashGN, A_ThisLabel, _Notify_Flash_
FlashGN += GF - 1
FlashGN2 := FlashGN + GL - GF + 1
If Flashed%FlashGN2% := !Flashed%FlashGN2%
Gui, %FlashGN2%:Color, Silver
Else
Gui, %FlashGN2%:Color, Black
Return
;==========================================================================
;============================= wait (or force) for a notification to close:
_Notify_Wait_:
;Critical
If (Image)
{
Gui %Image%:+LastFound
If NotifyGuiID := WinExist()
{
WinWaitClose, , , % Abs(Duration)
If (ErrorLevel && Duration < 1)
{
Gui, % Image + GL - GF + 1 ":Destroy"
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",ST,"UInt", "0x00050001")
Gui, %Image%:Destroy
}
}
}
Else
Notify("No Notification specified to wait for!","waiting for all notifications is not yet implemented",10,"IN=8",A_WinDir "\explorer.exe")
Return
} |
Screenshots:
 
Examples:
| Code: | Title= Hello
Message= World
Duration=0
Options:="GC=bbffbb TC=White MC=White"
Image=14
Notify(Title,Message,Duration,Options,Image) |
| Code: | Notify("Title","Message",10) ;=== typical call
Notify() ;=== creates a default notification
Loop 10 ;=== creates 10 notifications with varying options
Notify("Notify " A_Index, "Duration=" Abs(20-A_Index-Mod(A_Index,3)*A_Index) " Corners=" Round((A_Index*A_Index-1)/3) " Icon=" A_Index+35,Abs(20-A_Index-Mod(A_Index,3)*A_Index),"GR=" (A_Index*A_Index-1)/3 " BR=" (A_Index*A_Index-1)/3,A_Index+35) | Action/Wait Demo: | Code: | Notify("Welcome to Notify()","Click this notification to open a new one using AC=...",0,"AC=ActionDemo IN=8 IW=48 IH=48", A_WinDir "\explorer.exe")
Return
ActionDemo:
HotKey, ^F12, WaitDemo
NotifyID := Notify("","this one is permanent, press ctrl-F12 to force kill after 3 seconds",0)
Return
WaitDemo:
Notify("","",-3,"Wait",NotifyID)
Notify("Waiting done!","It was killed after 3 seconds, even though it had 0 duration!`n`nthis notification will exitapp if clicked or waits 15 seconds",-15)
Return
#Include Notify.ahk
|
Notify() 0.43
by gwarble
september 2009
thanks to Rhys/engunneer [Toaster Popups] and HugoV [help/recommendations]
i'm new to releasing my code and would greatly appreciate any feedback/suggestions/ideas/criticism/etc... on this function, which is similar to/can replace: TP Toaster Popup, TrayTip and Menu Tray Tip, some ToolTips, and has similar functionality to snarl and growl for tray notifications
Last edited by gwarble on Mon Dec 07, 2009 7:16 am; edited 31 times in total |
|
| Back to top |
|
 |
hugov
Joined: 27 May 2007 Posts: 2428
|
Posted: Thu Sep 10, 2009 8:45 am Post subject: |
|
|
Nice and easy to use. In NotifyWait there is a reference to an icon in notifier.exe you may wish to comment out for people just downloading notify.ahk _________________ Tut 4 Newbies
TF : Text file & string lib, TF Forum |
|
| Back to top |
|
 |
gwarble
Joined: 23 May 2009 Posts: 126 Location: north bay, california
|
Posted: Thu Sep 10, 2009 8:57 am Post subject: fixed |
|
|
thanks, fixed
also made the function file alone able to run for testing, so you can just download Notify.ahk and run it without Notifier or including:
^+F12 for test notifications, doesnt show all options but lets you see the multiple window detection (also, run 2 copies of it to see how it handles two scripts using notify() )
Edit: code updated in initial post
Download:
http://arcadefanatic.com/notifier/Downloads/Notify.ahk
thanks for trying it out
- gwarble
=====================================
anyone know a better way to have seperate timers/timer lengths (dynamically) than this cob solution:
| Code: |
SetTimer, NotifyKill%GuiNumber%, % "-" Duration * 1000 ;in function call
...
NotifyKill11: ;function subs
NotifyKill12:
NotifyKill13:
NotifyKill14:
NotifyKill15:
NotifyKill16:
NotifyKill17:
NotifyKill18:
NotifyKill19:
NotifyKill20:
NotifyKill:
StringReplace, GuiNumber, A_ThisLabel, NotifyKill ;crappy dynamic timer solution
GuiNumber2 := GuiNumber + 20
Gui, %GuiNumber2%:Destroy
Gui %GuiNumber%:+LastFound
NotifyGuiID := WinExist()
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",600,"UInt", "0x00050001") ;=== slide right SLOW timed-out notifications
Gui, %GuiNumber%:Destroy
NotifyCount--
SetTimer, NotifyFlash, Off
If (Exit)
ExitApp
Return
|
there's gotta be a better way
Last edited by gwarble on Sun Sep 13, 2009 6:30 pm; edited 1 time in total |
|
| Back to top |
|
 |
gwarble
Joined: 23 May 2009 Posts: 126 Location: north bay, california
|
Posted: Sun Sep 13, 2009 6:09 am Post subject: |
|
|
worked out all the kinks for multiple guis, now need to clean up the code a bit, but now multiple can show, while each retaining its own timer
here's some screenshots of it in use in my other app:
i'd love to see it in use in your scripts
- gwarble

Last edited by gwarble on Sun Dec 06, 2009 8:43 pm; edited 2 times in total |
|
| Back to top |
|
 |
hugov
Joined: 27 May 2007 Posts: 2428
|
Posted: Sun Sep 13, 2009 6:19 am Post subject: |
|
|
Some ideas:
- I prefer rectangular notifications vs rounded, perhaps you could introduce a style or rounding parameter for the winset
- I also use ToasterPopups which I modified to be able to include images in the TP
- The border is drawn with transparency perhaps allow colours so you can have a red border for example
Edit: re timer question, for some ideas see http://www.autohotkey.com/forum/viewtopic.php?t=48670, lexikos post _________________ Tut 4 Newbies
TF : Text file & string lib, TF Forum |
|
| Back to top |
|
 |
gwarble
Joined: 23 May 2009 Posts: 126 Location: north bay, california
|
Posted: Sun Sep 13, 2009 6:21 pm Post subject: |
|
|
for now its easy to comment out the lines for winset,region (rounded corners) and manually change the background guis color (or if you want it to look like a tooltip you could drop the second gui altogether)
to make it parameter based, would you prefer
Notify(title,msg,dur,......,colorthis,colorthat,thicknessthis,thicknessthat)
with tons of parameters, or:
Notify(title,msg,dur,action, "FClrRed GClrBlue BClrGreen FSize12 FWght500")
letting notify parse a single parameter for all these options
i'm thinking the latter, which could have lots easily including:
font size,color,titlesize,messagesize,font face,weight,modifiers(italic etc)
gui color,size,flashcolor, backgroundcolor, opacity, clickthru or not, clickaction and timeoutaction, background border thickness, lots more, gui numbers, etc
let me know what approach to go which is most appreciated
-gwarble
EDIT:
oh yeah, and i'm adding images at the moment, the whole reason i made this function is for that last screenshot, to replace the bottom gui with this dynamically positioning Notify() gui, so images are being implemented now, but again i'd love to know the way you would prefer to call the function |
|
| Back to top |
|
 |
hugov
Joined: 27 May 2007 Posts: 2428
|
|
| Back to top |
|
 |
gwarble
Joined: 23 May 2009 Posts: 126 Location: north bay, california
|
Posted: Sun Sep 13, 2009 9:05 pm Post subject: |
|
|
i like the init function idea, but i don't like having globals
how about using either:
Notify("Notify_Configure",blah,blah.....blah,blah)
which would prevent a notification called Notify_Configure or something, and set static variables this way...
or i think the best is the options parameter, which set statics if used, but statics are default if they are never used, therefore not needing to be specified each call unless you want it to change... so:
| Code: |
Options := "TS10 TW600 TCBlack MS8 MW400 MCBlue GN11 GCFF44FF GT200" ;...
Notify(Title,Message,Duration,Action,Options)
;TS is Title Font Size
;TW is Title Font Weight
;TF is Title Font
;TC is Title Font Color
;
;MS is Message Font Size
;MW is Message Font Weight
;MF is Message Font
;MC is Message Font Color
;
;GF is First Gui Number available
;GL is Last Gui Number available ;difference is max #
;GC is Gui Color
;GR is Gui Rounded Corners (in pixels)
;
;BC is Border (Background Gui) Color
;BT is Border (Background Gui) Border Thickness
;BF is Border (Background gui) flash speed
;
;there's more that could be added, and they could be added later without changing any parameters/break functionality
|
also, would you want a title, message, and an image? or IfFileExist, title then show the image and now have a title
- gwarble
edit: if the first option is used Notify("Notify_Configure") then i could also use Notify("Notify_Wait") and loose the second function |
|
| Back to top |
|
 |
hugov
Joined: 27 May 2007 Posts: 2428
|
Posted: Sun Sep 13, 2009 9:16 pm Post subject: |
|
|
I would prefer TS=10 over TS10 as you can see from the examples above it is easier for the user to understand and parse. I don't mind much how you do it either with init or options, currently I use Notify(A_ScriptName, "Done", -3) a lot so that is nice and short, images, colours & styles are just a bonus  _________________ Tut 4 Newbies
TF : Text file & string lib, TF Forum |
|
| Back to top |
|
 |
Guest
|
Posted: Sun Sep 13, 2009 9:19 pm Post subject: |
|
|
oh crap are you using -3 to exitapp after the three seconds? cuz i removed that functionality, thinking you could use Notify(title,msg,3,"ExitSub") as an action...
but if yo ulike it i kind of do too, and its easy to have in there
-gwarble |
|
| Back to top |
|
 |
gwarble
Joined: 23 May 2009 Posts: 126 Location: north bay, california
|
Posted: Sun Sep 13, 2009 9:23 pm Post subject: |
|
|
or if it saves all variables as static,
You could call:
Notify(A_ScriptName, "Done", -3)
once
and then call
Notify()
every other time for the same notification
also, personally i don't like the "=" in the options since it isnt consistent with other uses of =, of which there are already 2... but i'm not opposed and will start that way... if its there the option names could be long and descriptive, but i kind of like the two letter approach...
??
- gwarble
edit: do we want:
Notify(Title,Msg,Image,Dur...
or image file in with the options
different uses would make either one more convenient... although my use would call for a different image being used on each notification (having a dedicated parameter being easier), i think most people would set the image to an image for the script and use it for all notifications... especially with two scripts using notify()
- gwarble |
|
| Back to top |
|
 |
hugov
Joined: 27 May 2007 Posts: 2428
|
Posted: Sun Sep 13, 2009 9:27 pm Post subject: |
|
|
Edit: you types while I was typing. So this refers to -3
I like it yes, the Notify is so much nicer to have then the regular MsgBox Done to indicate when a lenghty script is, well, done
Currently I use costum (per script) toasterpopups to either use with windows taskschedular to remind me of stuff or give feedback while a script is running, in all of these cases I like the script to close after the last notify (its done), so by using -3 it saves me a line in the script and it is easier to type then an another notify command/line.
Re: images mmm not sure what would be best, perhaps per notify so you can use different images for start/working/paused/ready/exit type of messages?
Perhaps also introduce some basic system icons as with MsgBox? That way you don't have to include an image with a script that uses Notify. _________________ Tut 4 Newbies
TF : Text file & string lib, TF Forum
Last edited by hugov on Sun Sep 13, 2009 9:31 pm; edited 1 time in total |
|
| Back to top |
|
 |
gwarble
Joined: 23 May 2009 Posts: 126 Location: north bay, california
|
Posted: Sun Sep 13, 2009 9:28 pm Post subject: |
|
|
| great feedback, thanks, back in it goes |
|
| Back to top |
|
 |
hugov
Joined: 27 May 2007 Posts: 2428
|
|
| Back to top |
|
 |
gwarble
Joined: 23 May 2009 Posts: 126 Location: north bay, california
|
Posted: Sun Sep 13, 2009 11:39 pm Post subject: |
|
|
sounds good man, thanks for the feedback
i'm putting back in -duration, adding images, and converting to an options parameter now, i'll get a new version up shortly
- gwarble
edit:
HugoV:
got back to it, no images yet but try this for no corner rounding, option testing, color control, let me know what oyu think about the usage syntax for your script
| Code: | ;
; Notify() Version 0.2
; made by gwarble - sept 09
;
; for displaying multiple tray area notifications
;
; Notify([Message,Title,Duration,Action,FontColor,FontSize,GuiColor,StartGN,MaxGuiCount])
;
; thanks to Rhys and engunneer [Toaster Popups]
; test with [Ctrl-Shift-1] [^+1] if Notify.ahk is run
;
;=== To Fix:
;=== fill gaps from removed notifications if fit (might not be worth the wingetpos processing...?, and may not be desireable)
;=== or shift left a "column" width for more than monitor height allows
;=== or collapse open not's on new not or on close not (with delay)
;=== one last global to remove for label name... don't know if its possible
;=== flashing could be improved with options
;=== position could be controlable, could be moveable once open (stickies, reminders, etc)
;=== GN/maxcount need to be made parametric (for now it starts at 11: and allows 40)
;=== flash only works with odd number of flashing not's (easy to fix but may change functionality instead)
;=== have an Options parameter, for color/size/font stuff, position/size stuff, time action, click action, instead of so many parameters, parse internally...
;===
;====================================================================================
;====================================================================================
Notify_Demo1: ;=== in case Notify.ahk is run instead of #include-d
; Notify("Notify()","This is a sample notification.`nIt will last for 15 seconds unless clicked.`nNotify.ahk is meant to be #Include-d.`nDownload Notifier for a working example.`n`nCtrl-Shift-F12 for more...`n`nThanks for trying!",15)
Notify("f","f",13,"TC=Red GR=2 BT=2")
Notify("f","f",13,"TC=Red GR=4 BT=2")
Notify("f","f",13,"TC=Red GR=6 BT=2")
Notify("f","f",13,"TC=Red GR=9 BT=2 BC=Red")
Notify()
Notify()
Notify()
Hotkey, ^+F12, Notify_Demo2
Return
Notify_Demo2:
Notify()
Notify("Notification:","This one won't go away unless clicked",0)
Hotkey, ^+F12, Notify_Demo3
Return
Notify_Demo3:
; NotifyID := Notify("Test Notify","This notification will close in 2 seconds...", 2, "","Red", 8, "Black")
NotifyID := Notify()
Hotkey, ^+F12, Notify_Demo1
Return
;====================================================================================
;====================================================================================
Notify(Title="Notification!!!",Message="",Duration=15,Options="")
{
Static ;=== assume-static mode for arrays of options
Critical ;=== don't allow interruption
;Global Notify_Action := Action ;=== global Action label name, i don't know a way to keep actions but not have a global
static GF := 11 ;GF is Initial GN ;=== defaults if no options
static GL := 30 ;GM is Last GN ;=== options are saved between calls (ie only set once)
static GC := "FFFFAA" ;GC is Gui Color
static GR := 9 ;GR is Gui Radius
static TS := 8 ;TS is Title Font Size
static TW := 625 ;TW is Title Font Weight
static TC := "Black" ;TC is Title Font Color
static TF := "Arial" ;TF is Title Font
static MS := 8 ;MS is Message Font Size
static MW := 550 ;MW is Message Font Weight
static MC := "Black" ;MC is Message Font Color
static MF := "Arial" ;MF is Message Font
static BC := "Black" ;BC is Border Color
static BT := 2 ;BT is Border Thickness
static BF := 150 ;BF is Border Flash Speed
static AC := "" ;AC is Clicked Action (gosub label when clicked)
static AT := "" ;AT is Action Timeout (gosub label when timeout)
static AI := "" ;AI is Action In (not really useful, is it? an action upon creation)
static SC := 300 ;SC is Speed Clicked (AnimateWindow time)
static SI := 250 ;SI is Speed In (AnimateWindow time)
static ST := 100 ;SO is Speed TimeOut (AnimateWindow time)
If (Options) ;=== parse Options parameter
Loop,Parse,Options,%A_Space%
If (Option:= SubStr(A_LoopField,1,2))
%Option%:= SubStr(A_LoopField,4) ;=== two letter option and = (GF=1) means value starts at 4 (needs to strip quotes if used)
GN := GF
Loop ;=== max notifications, Notify() uses twice the max (for background) so 5 notifications use 10 gui numbers
IfNotInString, NotifyList, % "|" GN ;=== check if this notification exists
Break ;=== if not, make it
Else ;=== if so
If (++GN > GL) ;=== increment GN, check if under maxcount
GN := GF ;Return 0 ;=== If so, recheck, if not, return 0 ERROR (process by your script, if succedes returns guiID) (should save somehow and show when possible)
NotifyList .= "|" GN ;=== add GN to list of open guis, | delimeted
GN2 := GN + GL - GF + 1 ;=== gui number for background gui
Prev_DetectHiddenWindows := A_DetectHiddenWindows ;=== save current DetectHiddenWindows settings
Prev_TitleMatchMode := A_TitleMatchMode ;=== save current TitleMatchMode settings
DetectHiddenWindows On ;=== needed for winexist()
SetTitleMatchMode 1 ;=== needed for winexist()
If (WinExist("NotifyGui")) ;=== find all Notify() gui's from any scripts for placement
WinGetPos, OtherX, OtherY ;=== change this to a loop for all windows, not just first found by winexist()
DetectHiddenWindows %Prev_DetectHiddenWindows% ;=== restore script settings
SetTitleMatchMode %Prev_TitleMatchMode% ;=== restore script settings
Gui, %GN2%:Destroy ; - remove these once unnecessary
Gui, %GN%:Destroy ; - remove these once unnecessary
Gui, %GN%:-Caption +ToolWindow +AlwaysOnTop -Border ;=== notification gui creation
Gui, %GN%:Color, %GC%
Gui, %GN%:Font, w%TW% s%TS% c%TC%
If (Title)
Gui, %GN%:Add, Text, gNotify_Action, % Title
Gui, %GN%:Font, w%MW% s%MS% c%MC%
If ((Title) && (Message))
Gui, %GN%:Margin, , -5
If (Message)
Gui, %GN%:Add, Text, gNotify_Action, % Message
If ((Title) && (Message))
Gui, %GN%:Margin, , 8
Gui, %GN%:Show, Hide, NotifyGui
Gui %GN%:+LastFound
WinGetPos, GUIX, GUIY, GW, GH
Gui, %GN%:Add, Text, x0 y0 w%GW% h%GH% gNotify_Action BackgroundTrans ;=== for clicking anywhere on the notification instead of just the text
WinSet, Region, % "0-0 w" GW " h" GH " R" GR "-" GR ;=== round corners of notification, notification gui creation END
SysGet, Workspace, MonitorWorkArea ;=== initial placement
NewX := WorkSpaceRight-GW-5
If (OtherY)
NewY := OtherY-GH-5
Else
NewY := WorkspaceBottom-GH-5
If NewY < % WorkspaceTop
NewY := WorkspaceBottom-GH-5 ;=== initial placement END
Gui, %GN2%:-Caption +ToolWindow +AlwaysOnTop -Border +E0x20 ;=== background gui
Gui, %GN2%:Color, %BC%
Gui %GN2%:+LastFound
WinSet, Region, % "0-0 w" GW+(BT*2) " h" GH+(BT*2) " R" GR "-" GR
WinSet, Transparent, 105 ;=== background gui END
Gui, %GN2%:Show, % "Hide x" NewX-BT " y" NewY-BT " w" GW+3 " h" GH+3
Gui, %GN%:Show, % "Hide x" NewX " y" NewY, NotifyGui
Gui %GN%:+LastFound
NotifyGuiID := WinExist()
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",250,"UInt","0x00040008") ;=== slide up new notifications
Gui, %GN2%:Show, NA ;=== show background gui
WinSet, AlwaysOnTop, On
If Duration < 0
Notify_Exit%GN% = 1
If (Duration) ;=== set timeout for notification
SetTimer, NotifyKill%GN%, % - Abs(Duration) * 1000
Else
SetTimer, NotifyFlash%GN%, 150 ;=== flash border/icon for permanent notification (add option for flash/noflash)
Return NotifyGuiID ;=== change to return gui number
;====================================================================================
;====================================================================================
;=== when a notification is clicked:
Notify_Action:
SetTimer, NotifyKill%A_Gui%, Off
Gui, % A_Gui + 20 ":Destroy"
Gui %A_Gui%:+LastFound
NotifyGuiID := WinExist()
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",100,"UInt", "0x00050001") ;=== slide right FAST clicked notifications
Gui, %A_Gui%:Destroy
If IsLabel(Notify_Action)
Gosub, %Notify_Action%
StringReplace, NotifyList, NotifyList, % "|" GN, , All
SetTimer, % "NotifyFlash" A_Gui, Off
Return
;=== when a notification times out:
NotifyKill:
NotifyKill11:
NotifyKill12:
NotifyKill13:
NotifyKill14:
NotifyKill15:
NotifyKill16:
NotifyKill17:
NotifyKill18:
NotifyKill19: ;=== there's gotta be a better way to do this, bueller?, bueller?
NotifyKill20:
NotifyKill21:
NotifyKill22:
NotifyKill23:
NotifyKill24:
NotifyKill25:
NotifyKill26:
NotifyKill27:
NotifyKill28:
NotifyKill29:
NotifyKill30:
StringReplace, GN, A_ThisLabel, NotifyKill
SetTimer, NotifyFlash%GN%, Off
Gui, % GN + 20 ":Destroy"
Gui %GN%:+LastFound
NotifyGuiID := WinExist()
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",300,"UInt", "0x00050001") ;=== slide right SLOW timed-out notifications
Gui, %GN%:Destroy
StringReplace, NotifyList, NotifyList, % "|" GN
Return
;=== flashes a permanent notification [buggy]
NotifyFlash11:
NotifyFlash12:
NotifyFlash13:
NotifyFlash14:
NotifyFlash15:
NotifyFlash16:
NotifyFlash17:
NotifyFlash18:
NotifyFlash19:
NotifyFlash20: ;=== maybe instead use one timer and a FlashList like notifylist
NotifyFlash21: ;=== maybe they should just all flash
NotifyFlash22:
NotifyFlash23:
NotifyFlash24:
NotifyFlash25:
NotifyFlash26:
NotifyFlash27:
NotifyFlash28:
NotifyFlash29:
NotifyFlash30:
NotifyFlash:
StringReplace, FlashGN, A_ThisLabel, NotifyFlash
FlashGN2 := FlashGN + 20
If Flashed := !Flashed
Gui, %FlashGN2%:Color, Silver
Else
Gui, %FlashGN2%:Color, Black
Return
} ;=== end of Notify() ===
;=== use in OnExit (or elsewhere) to wait for notifications to close before doing something [buggy]
;=== fix: Reference GN instead of GuiID, use negative forcetime to kill all open notifications (not yet implemented)
Notify_Wait(ForceTime="", GN=11, MaxNotifications=20)
{
Loop % MaxNotifications
{
Gui %GN%:+LastFound
If NotifyGuiID := WinExist()
{
WinWaitClose, , , % ForceTime
If ErrorLevel
{
Gui, % GN + 20 ":Destroy"
DllCall("AnimateWindow","UInt",NotifyGuiID,"Int",200,"UInt", "0x00050001") ;=== slide right FAST clicked notifications
Gui, %GN%:Destroy
}
Break
}
GN++
}
Return 1
} |
edit: oops, i guess yo uneed all those statics so they dont get reinitialized
edit: ok version 0.3 is updated in first post
Last edited by gwarble on Mon Sep 14, 2009 6:26 am; edited 1 time in total |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|