# VBForums CodeBank > CodeBank - Visual Basic .NET >  Animated Window Effects with "Toast" popup demo

## jmcilhinney

C# version here.

*FormAnimator class* - A helper class that you can add an instance of to a form to provide animation when the form is shown, hidden or closed.  Supported animations are Roll (form is unrolled and rolled up from one edge to the opposite), Centre (form unrolls from the centre out and rolls up from all edges in), Slide (form slides in and out from one edge to the opposite) and Blend (form fades in and out).  Roll and Slide animations can be up, down, left, right or diagonal.  To use this class just add a single line of code similar to this to your form:
VB Code:
Private myAnimator As New FormAnimator(Me, FormAnimator.AnimationMethod.Slide, FormAnimator.AnimationDirection.Up, 400)

*ToastForm class* - An inherited Form class that uses the FormAnimator class to produce the same "toast" effect used by MSN Messenger and other apps, where the form slides up from the system tray and then slides back again after a period of time.  To use this class just add code like this:
VB Code:
Dim myToastForm As New ToastForm(5000, "This is a ""toast"" popup demo.")
 myToastForm.Show()

Edit: 30/09/2005
I've updated the ToastForm class so that it now will not receive focus when it is displayed.  It will still receive focus if you click on it though.

Edit: 30/09/2005
I've updated the ToastForm class so that existing windows will move up the screen to make way for new ones so that they are not covered.

Edit: 30/09/2005
I've updated the ToastForm class so that it stacks properly if the Height is changed and/or multiple forms are opened with different lifetimes.

Try putting the following code in a form and pressing the button several times in succession to see this in action:
VB Code:
Dim myRandom As New Random
    Dim formNumber As Integer = 1
     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim toast As New ToastForm(myRandom.Next(5000, 10000), "This is form number " & Me.formNumber.ToString())
         toast.Height = myRandom.Next(150, 300)
        toast.Show()
        Me.formNumber += 1
    End Sub
Edit: 01/10/2005
I don't know if it will help, but for those who have been having issues getting this to work I've attached a full project (VS.NET 2003) that was working for me, so hopefully for you too.

Edit: 07/10/2005
It appears that the issues that some have been having are due to a bug in the Framework that was fixed in SP1, so apply SP1 for the .NET Framework 1.1 and all should be well.

Edit: 21-Nov-2005
I've removed the original attachments and added new ones.  The attached solution was rewritten in VB 2005 with a few changes.  The attached class file is from that solution if you just want animation without the toast feature.

Edit: 27-Nov-2008
Set the TopMost property of the ToastForm class to True to ensure notification windows were not hidden behind other windows if the caller is not currently active.

----------


## uniquegodwin

Hey Jm...
This is really cool...
But,if u dont mind,please just tell me what this line does "AddHandler m_FadeTimer.Tick, AddressOf FadeForm"
It adds a timer to the form while closing..and what does AddressOf fadeform mean?

Thanks in advance  :Smilie: 

Godwin

----------


## jmcilhinney

That line simply attaches the FadeForm method to the Tick event of the Timer object.  Normally you would add the Timer to the form in the designer and double-click it to create an event handler automatically.  That line has the same effect as having "Handles m_FadeTimer.Tick" at the end of the procedure's declaration.  I just used that method so that you could see everthing that was happening, rather than do some things in the designer that you would be unaware of.

----------


## uniquegodwin

I used to use form1.controls.add(something) ...but,now,i learnt something new  :Wink: 
It works great..Im using this now in my program  :Smilie:   Thanks

Godwin

----------


## jmcilhinney

If you want to add a control to a form you would still need to do that.  A Timer is a component, not a control.  It doesn't get displayed on the form so it doesn't need to be added to the form's Controls property, and in fact cannot be.  Anything that you need to actually display on the form must still be added to it's Controls collection.

----------


## jmcilhinney

I have rewritten the code into a helper class that you can use with any existing form without making any changes to the form itself.  You might use this helper class something like this:
VB Code:
Private myForm As New Form
    Private myAnimator As New FormAnimator(myForm, FormAnimator.AnimationTypes.Blend, 300)
     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        myForm.Show()
    End Sub
     Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        myForm.Hide()
    End Sub
and the form will be animated automatically.  Here is the code for the FormAnimator helper class:
VB Code:
'Animates a form when it is shown, hidden or closed.
Public NotInheritable Class FormAnimator
     'The types of animation available.
    Public Enum AnimationTypes
        Roll = &H0      'Roll out from edge to show; Roll in to edge to hide.  Requires direction.  Default animation.
        Centre = &H10   'Expand out from centre to show; Collapse in to centre to hide.
        Slide = &H40000 'Slide out from edge to show; Slide in to edge to hide.  Requires direction.
        Blend = &H80000 'Blend from transaprent to opaque to show; Blend from opaque to transparent to hide.
    End Enum
     'The directions in which the Slide animation can be shown.
    'The Flags attribute indicates that directions can be combined.
    <Flags()> Public Enum SlideDirections
        None = 0
        Right = &H1 'Slide from left to right.
        Left = &H2  'Slide from right to left.
        Down = &H4  'Slide from top to bottom.
        Up = &H8    'Slide from bottom to top.
    End Enum
     Private Const AW_HIDE As Integer = &H10000      'Hide the form.
    Private Const AW_ACTIVATE As Integer = &H20000  'Activate the form.
     Private WithEvents m_Form As Form               'The form to be animated.
     Private m_Type As AnimationTypes                'The type of animation used to show and hide the form.
    Private m_Direction As SlideDirections          'The direction in which to Roll or Slide the form.
    Private m_Duration As Integer = 500             'The number of milliseconds over which the animation is played.
     'The type of animation used to show and hide the form.
    Public Property AnimationType() As AnimationTypes
        Get
            Return Me.m_Type
        End Get
        Set(ByVal Value As AnimationTypes)
            Me.m_Type = Value
        End Set
    End Property
     'The direction in which to Roll or Slide the form.
    Public Property SlideDirection() As SlideDirections
        Get
            Return Me.m_Direction
        End Get
        Set(ByVal Value As SlideDirections)
            Me.m_Direction = Value
        End Set
    End Property
     'The number of milliseconds over which the animation is played.
    Public Property AnimationDuration() As Integer
        Get
            Return Me.m_Duration
        End Get
        Set(ByVal Value As Integer)
            Me.m_Duration = Value
        End Set
    End Property
     'Windows API function used to animate the form.
    Private Declare Auto Function AnimateWindow Lib "user32" (ByVal hwnd As IntPtr, _
                                                              ByVal dwtime As Integer, _
                                                              ByVal dwflags As Integer) As Boolean
     'Creates a new FormAnimator object for the specified form.
    Public Sub New(ByVal form As Form)
        Me.m_Form = form
    End Sub
     'Creates a new FormAnimator object for the specified form using the specified animation type over the specified duration.
    Public Sub New(ByVal form As Form, _
                   ByVal type As AnimationTypes, _
                   ByVal duration As Integer)
        Me.New(form)
         Me.m_Type = type
        Me.m_Duration = duration
    End Sub
     'Creates a new FormAnimator object for the specified form using the specified animation type in the specified
    'direction over the specified duration.  This is intended to be used with Roll and Slide animations.
    Public Sub New(ByVal form As Form, _
                   ByVal type As AnimationTypes, _
                   ByVal direction As SlideDirections, _
                   ByVal duration As Integer)
        Me.New(form, type, duration)
         Me.m_Direction = direction
    End Sub
     'Animates the form automatically when it is shown or hidden.
    Private Sub m_Form_VisibleChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles m_Form.VisibleChanged
        Dim flags As Integer = Me.m_Type Or Me.m_Direction
         If Me.m_Form.Visible Then
            'Activate the form.
            flags = flags Or Me.AW_ACTIVATE
        Else
            'Hide the form.
            flags = flags Or Me.AW_HIDE
        End If
         Me.AnimateWindow(Me.m_Form.Handle, _
                         Me.m_Duration, _
                         flags)
    End Sub
     'Animates the form automatically when it closes.
    Private Sub m_Form_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles m_Form.Closing
        'Hide the form.
        Me.AnimateWindow(Me.m_Form.Handle, _
                         Me.m_Duration, _
                         Me.AW_HIDE Or Me.m_Type Or Me.m_Direction)
    End Sub
 End Class

----------


## RobDog888

This duplicates the Windows Forms animations, bu thow could you do a dual direction animation? Down + Right, etc? 

Very nice code btw.  :Wink:

----------


## jmcilhinney

I apologise to the author if this duplicates someone else's work.  To set a direction like down and right you use a bitwise Or for the SlideDirection property, e.g.
VB Code:
myAnimator.SlideDirection = FormAnimator.SlideDirections.Down Or FormAnimator.SlideDirections.Right

----------


## RobDog888

Ok, so its possible to 'Or' them to gether. Will this replicate the animated minimizing like MSN?

----------


## jmcilhinney

I've not used MSN Messenger so I don't know exactly what that looks like, but if you mean like shrinking towards its icon on the TaskBar then no, it won't.  That functionality is not included in the AnimateWindow API.

----------


## FYRe

> I have now removed my original code altogether and replaced it with some that uses the AnimateWindow API, which will fade a form in and out as well as use several other effects.  This code can be added to a form itself or it could be adapted to be used in a helper class.
> VB Code:
> Public Class AnimatedForm
>     Inherits System.Windows.Forms.Form
>      Public Enum AnimationTypes
>         None = 0
>         Centre = &H10   'Show outwards from centre out or hide inwards from edge.
>         Slide = &H40000 'Slide in or out in the specified direction.
>         Blend = &H80000 'Fade in or out.
> ...


 Hi JM,

I copied the whole code as given, however, it doesn't seem to work. Could you maybe attach a copy of the program? preferably ZIP it first before attaching it. I've read the comments and replies. The program seems interesting....

thks,
FYRe

----------


## jmcilhinney

> Hi JM,
> 
> I copied the whole code as given, however, it doesn't seem to work. Could you maybe attach a copy of the program? preferably ZIP it first before attaching it. I've read the comments and replies. The program seems interesting....
> 
> thks,
> FYRe


You won't be able to just copy that code and use it as is.  I would suggest the best course of action would be to use the helper class from post #6.  That is a self-contained class and you will just be able to copy and paste.  If you want to use the code that you have quoted in a particular form of your own, you should create your own form first as you normally would and then copy and paste just the contents of my AnimatedForm class into your own form.  Like I said, I think the helper class is the better option, though, because it means you don't have to change any code in your form or inherit from a different class than you normally would.  If this advice is not satisfactory then by all means post back and I'll post a project, but I think either of the methods I described should get you home.

----------


## maged

that's great jmcilhinney

nice work     :Thumb:   :Thumb:   :Thumb:

----------


## maged

sorry jmcilhinney, but i need to know why doesn't work on the mdiChild forms, 

it works great on normal forms.

but it doesn't work on :

1 - forms with the windowstate = maximized

2 - forms that is mdi child  for a mdiparent 

3 - forms that are showed using : .showdialog method

is there any possible solutions, as most of the applications i work on is MDI/PArent-Child Form applications. and i liked the fade effect very much.

i would like also your permession to use this effect in my application

thx for your kind attention

rgds

----------


## jmcilhinney

I've posted this code here for all to use freely.  As for those issues, I must admit that I haven't tested this too much, and not at all outside of regular vanilla forms.  I'll have a dig around and see what I can come up with.

----------


## maged

i will wait for your feed back

thx & RGDS

----------


## RobDog888

I wouldnt think that it would be a good idea to animate mdi child forms. Probably better to just animate the mdi parent.  :Wink:

----------


## maged

> I wouldnt think that it would be a good idea to animate mdi child forms


and y is that? is there any technical reasons   :Confused:

----------


## RobDog888

No, just from a professional program functionality standpoint. I cant recall ever seeing a mdi app that had the child forms animated. Usually they are always maximized so not much need is all.  :Wink:

----------


## jmcilhinney

> sorry jmcilhinney, but i need to know why doesn't work on the mdiChild forms, 
> 
> it works great on normal forms.
> 
> but it doesn't work on :
> 
> 1 - forms with the windowstate = maximized
> 
> 2 - forms that is mdi child  for a mdiparent 
> ...


My testing and research has yielded the following information.

1. The supplied code works correctly for Maximized forms when hiding or closing but has no effect when displaying.
2. The supplied code has no effect when displaying an MDI child form and behaves strangely when hiding or closing an MDI child form.
3. The supplied code works correctly for forms displayed using ShowDialog.

I will look into these issues further in the near future.  I may be able to incorporate my old code that used a Timer and Opacity to reproduce the Blend effect at least for MDI child and Maximized forms.

Also note that the call to AnimateWindow in the FormAnimator class is synchronous, so the app's UI will not be updated in other areas during the animation.  This means that if a form is placed over another form and then animated, the rear form will not be refreshed until the animation completes.  This can lead to some ugly visual effects.  I will look at using multi-threading to overcome this issue.

Stay tuned for future bulletins.

----------


## jmcilhinney

I have revised my code a little, so post #6 has been updated with the new version of the FormAnimator class.  I have also done a little more research and here are my findings.

MDI child forms do not support transparency at all.  Setting the Opacity of an MDI child form has no effect either.  This means that a call to AnimateWindow for an MDI child form using the Blend animation method will always fail.

Regular Forms:
The code provided works correctly in all cases.

Modal Dialogues (displayed using ShowDialog):
The code provided works correctly in all cases.

Maximized Forms:
The code provided has no effect when displaying a form, but works correctly for all animation types when hiding or closing a form.  One point to note is that the Blend effect is not so visually appealing when hiding or closing a Maximized form as for a Normal form.

MDI Child Forms:
The code provided has no effect when displaying a form.  When hiding, the form will be hidden, reshown and then hidden again.  When closing, the code provided works correctly for all but the Blend effect.

In short, you cannot successfully use the Blend effect for MDI child forms at all.  I will try to find a solution to the other issues but I cannot guarantee it will be soon, as I have been neglecting my real work too much already.  I'll get back to you.

----------


## jmcilhinney

OK, I have updated the code again and attached it to this post.  I have changed the nomenclature a little and improved support for MDI child forms.  It looks like MDI child forms don't support transparency at all so the Blend method is out completely.  I've managed to get them to animate properly when they are first shown and when they close.  The VisibleChanged event is raised differently for MDI children than for regular forms, so I've excluded support for animating child windows when showing them, other than the first time, and when hiding them.  How often do you set the Visible property of an MDI child form to False anyway.

Edit:
Attachment removed.  See first post.

----------


## maged

that is a great piece of work, thank you

mt only problem now is : 
[
everytime i think myself good in vb.net, someone in this forums proves me wrong   :Big Grin:  
]
  joking:

again thank you for the great additions, i will stay tuned for the coming modifications

rgds

----------


## wrecklesswun

How about mdiparents?

----------


## jmcilhinney

> How about mdiparents?


What about them?

----------


## jmcilhinney

I've rewritten the first post and attached the final code there.  I've also attached a demo class that creates a "toast" popup.

----------


## jmcilhinney

I've updated the ToastForm class so that it now will not receive focus when it is displayed. It will still receive focus if you click on it though.

----------


## jmcilhinney

I've updated the ToastForm class so that existing windows will move up the screen to make way for new ones so that they are not covered.

----------


## jmcilhinney

I've updated the ToastForm class so that it stacks properly if the Height is changed and/or multiple forms are opened with different lifetimes.

----------


## jud9r

Hi, I am having a problem running this.  When I click the button I get an error saying 




> An unhandled exception of type 'System.ArgumentException' occurred in system.windows.forms.dll
> 
> Additional Information: hdc


in m_Form_Load of FormAnimator.

Any idea why, or I have I made a noob mistake?  could you post a solution file in case it's something I have missed?

Cheers.

----------


## jmcilhinney

> Hi, I am having a problem running this.  When I click the button I get an error saying 
> 
> 
> 
> in m_Form_Load of FormAnimator.
> 
> Any idea why, or I have I made a noob mistake?  could you post a solution file in case it's something I have missed?
> 
> Cheers.


Someone else said they had the same issue, but I'm not sure what the problem is.  To test it out I downloaded the files I posted, created a new project, added the downloaded files as Existing Items and everything worked fine.  I can't really give you any clues I'm afraid except to try to track down exactly which line throws the exception and get an error message and a stack trace.

----------


## jmcilhinney

I don't know if it will help, but for those who have been having issues getting this to work I've attached a full project (VS.NET 2003) that was working for me, so hopefully for you too.  See post #1.

----------


## dee-u

I encountered this error...   :Frown: 

I'll check out the project you attached...

----------


## jmcilhinney

> I encountered this error


You're the third person to say that, but I've not had any issues and it seems that some others haven't either.  Could you perhaps put that If block in a Try...Catch block like this:
VB Code:
Try
    'code here.
Catch ex As Exception
    MessageBox.Show(ex.ToString())
End Try
By calling ToString on the exception you get much more information, including the call stack.

----------


## dee-u

I tried the project you posted and I also encounter the same error?   :Frown:  I'll try putting an error handler in it and post the error...

----------


## dee-u

Here is the error:




> Message: hdc
> Source: System.Windows.Form
> 
> Error:
> See the end of this message for details on invoking 
> just-in-time (JIT) debugging instead of this dialog box.
> 
> ************** Exception Text **************
> System.ArgumentException: hdc
> ...

----------


## jmcilhinney

Man, that exception is thrown so deep in the Framework that I'm not willing to even try to debug it, particularly given the fact that only some people seem to be getting that error.  I'm going to say that I have no idea what the problem is and leave it at that.  Sorry.  I guess the alternative to using APIs is to just use a Timer to animate the form.

----------


## dee-u

Perhaps you have something in your computer that we don't have?

----------


## jmcilhinney

There's obviously some difference, but it's just making an API call so that should be the same on every WinXP machine I would have thought.

----------


## dee-u

I have XP Pro with SP1, 1.1 FW, .Net 2003

----------


## jmcilhinney

I'm using XP SP2.  Perhaps that's an issue, but I don't see why.  I doubt the AnimateWindow API was changed at all with the update, but I suppose there might be some reason.  The question is, why haven't you installed SP2 yet?  Slacker!  :Smilie:

----------


## dee-u

Aside from you have SP2, do you have any clues why it doesn't run on some machines? How about providing us an installer for it?   :Smilie:

----------


## jmcilhinney

I have no clue what the issue might be and I can't see how an installer could make a difference.  Have you tried compiling a release build and running that?  Do you get the same exception if you do?  The only other thing I can suggest is to create your own project from scratch.  You could then generate new class files in the IDE and either write the code yourself or copy and paste it from the old files.  I don't really see why this would make a difference, but then I don't see why there's an issue in the first place.

----------


## dee-u

Ok, I'll try your suggestions later and will return to give a feedback...

----------


## FishGuy

http://www.vbforums.com/showthread.p...52#post2192252

----------


## jmcilhinney

It appears that the issues that some have been having are due to a bug in the Framework that was fixed in SP1, so apply SP1 for the .NET Framework 1.1 and all should be well.

----------


## K321

Hi all,

anyone knows whether this is also working with .net 2.0?

----------


## jmcilhinney

> Hi all,
> 
> anyone knows whether this is also working with .net 2.0?


The classes and project (I think that's what's in the ZIP file but it's been a while) that I've provided were created in VS.NET 2003.  There's nothng in there that wouldn't work in .NET 2.0 though.  You should just be able to open the project in VS 2005 and have it converted.  I think you'll find that you could also add those class files to a project as Existing Items exactly as they are.

----------


## K321

Thanks for the fast response. Question was more about the .net 2.0 instead of VS 2005. I still use VS 2003 and .net 1.1 but I wonder whether users with .net 2.0 might still be able to get my program running then. I've read about the bug with .net 1.1 which was fixed in SP1 so maybe someone already uses this on .net 2.0 before I add this to my program?

----------


## jmcilhinney

.NET 2.0 is not just an update to the Framework that everyone should use.  Version 2.0 of the Framework is only for applications written with VS 2005.  VS.NET 2003 is only capable of targeting versions 1.0 and 1.1.  Anyone using an application that you write using VS.NET 2003 should be installing version 1.1 of the Framework, even if they have version 2.0 installed already.  Most apps written for version 1.1 will still run if only version 2.0 is present but there is no guarantee.  Again, version 2.0 is not just an update for users of version 1.1.  It is intended for users of applications written with VS 2005.

----------


## K321

Yeah, I guess most users with 2.0 will also still have 1.1, you're right. As far as I remember .net 1.1 is automatically installed even if you only install VS 2005 so I could assume that *everyone* has .net 1.1 currently, right? At least before Vista comes, don't know how it is handled there.... 
Thanks!!

----------


## jmcilhinney

VS.NET 2002 is built on and installs version 1.0 of the Framework.  VS.NET 2003 is built on and installs version 1.1 of the Framework.  VS 2005 is built on and installs version 2.0 of the Framework.  You should supply a link, at the very least, that your users can use to download the correct version for the app you are supplying.  If you have apps on your machine built with all three version of VS.NET then you should have all three versions of the Framework installed too.  Only Windows Server 2003 comes with a the Framework as standard.  Everyone else has to install it themselves.  Vista will come with version 2.0 as standard.  Previous versions would still need to be installed for apps written with earlier versions of VS.NET.  Those apps will use version 2.0 if that's all that's available and most will work without issue, but there is no guarantee.

----------


## shakti5385

Sir this is in 2003 so what about the 2005.

Thanks

----------


## jmcilhinney

> Sir this is in 2003 so what about the 2005.
> 
> Thanks


The FormAnimator class should work as is.  The ToastForm is just a form, so you can create your own in VB 2005 and then add the same custom code as I did in before.

----------


## shakti5385

I think there is no FormAnimator class  as you suggest.
FormAnimator class

----------


## jmcilhinney

> I think there is no FormAnimator class  as you suggest.
> FormAnimator class


The FormAnimator class is one that I wrote myself and it's attached to the first post this thread.  It was the whole point of this thread.  Hit yourself over the head with something heavy and say "D'oh", then blush furiously.

----------


## shakti5385

> The FormAnimator class is one that I wrote myself and it's attached to the first post this thread.  It was the whole point of this thread.  Hit yourself over the head with something heavy and say "D'oh", then blush furiously.


  :Wink:   :Big Grin:

----------


## danasegarane

Dear John,
              How can change the form show style as disolving ?

Dana

----------


## jmcilhinney

> Dear John,
>               How can change the form show style as disolving ?
> 
> Dana


No idea.

----------


## danasegarane

Dear Jhon,
                I think you have misunderstand.During form unload you have given one method as disolve.Is there any method aval to show the form during load event

thnks
Dana

----------


## jmcilhinney

> Dear Jhon,
>                 I think you have misunderstand.During form unload you have given one method as disolve.Is there any method aval to show the form during load event
> 
> thnks
> Dana


I don't know what you mean.  There are four effects supported by AnimateWindow: Roll, Centre, Slide and Blend.  All four are supported on both loading and closing.

----------


## danasegarane

Dear Jhon,
           I want to show the form like a blend. Is this posible ?

----------


## jmcilhinney

> Dear Joho,
>            I want to show the form like a blend. Is this posible ?


Yes it is, and the very first paragraph of the very first post of this thread explains how.

----------


## danasegarane

I trying this method.

vb Code:
Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.m_activeDB = New FormAnimator(Me, _
                                         FormAnimator.AnimationMethod.Blend, _
                                         FormAnimator.AnimationDirection.Up, _
                                         1000)
        Dim mnumanger As New SystemMenuManager(Me, False, SystemMenuManager.MenuItemState.Disabled)
    End Sub
     Private Sub Form2_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        'Close the form by sliding down.
         Me.m_activeDB.Direction = FormAnimator.AnimationMethod.Blend
    End Sub

This Gives a nice effect during the closing of the Form.But it not showing the 
efffect during form load event.

Dana

----------


## jmcilhinney

1. I just tested the following code:
vb.net Code:
Public Class Form2
     Private m_activeDB As FormAnimator
     Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.m_activeDB = New FormAnimator(Me, _
                                         FormAnimator.AnimationMethod.Blend, _
                                         FormAnimator.AnimationDirection.Up, _
                                         1000)
    End Sub
 End Class
and it worked fine for me.

2. You don't blend a form in any direction so there's no point using the FormAnimator constructor that takes a direction.

3. In your Closing event handler you're assigning an animation method to a property that is supposed to take an animation direction.  Again, blending isn't done in any direction so setting one is pointless, but if you were going to set one you should at least use a value of the appropriate type.  If that code doesn't throw a compilation error then you must have Option Strict turned Off.  I suggest that you rectify that immediately.

----------


## kritikal

nice work  :Alien Frog:

----------


## shyguyjeff

nice work jm... :Thumb:   :Thumb:   :Thumb:   :Thumb:

----------


## jmcilhinney

[Basking in the glow of praise]Thank you, thank you.[/Basking in the glow of praise]  :Wink:

----------


## garyjohn_2000

Great work on the toastform class jmc! (1 more reason to bask in the glory of praise!  :Stick Out Tongue:  )


But theres a little problem that i have encountered using this toastform.

I am using VBExpress 2005 (.NET 2.0).
All seems to be well till I try to declare and Show the form from a new thread. When I do that, the form is visible till the duration of the animation, but after that the form simply disappears. I even tried to debug it while setting a breakpoint at Me.Close() and lifeTimer.Tick, but the breakpoints are never hit!  :Roll Eyes (Sarcastic):  . I have simply no idea where the form goes after it disappears. Two things I know for sure:  The form never closes itself,and the lifeTimer.Tick event doesn't fire.

Some threading issue perhaps? or the Timer? 

It seems that the Windows.Forms.Timer sticks to the UI thread only. So, the Timer.Tick event may not fire at all.

But on the other hand, the System.Timers.Timer is said to raise the Elapsed event on new threads from the ThreadPool every time it is raised. So, it throws an InvalidOperationException: "Cross-thread operation not valid: Control 'PopupNotifierForm' accessed from a thread other than the thread it was created on.", citing the (cross-thread) call to "Me.Close()" as invalid. Delegation didn't help either. That throws a NullReferenceException: "Object reference not set to an instance of an object". 

This is the code I am trying to delegate the Me.Close method.

VB Code:
Public Delegate Sub FormCloseDelegate()
Public Class ToastForm
'...
'...
    Public Sub FormClose()
        If Me.InvokeRequired Then
            Me.Invoke(New FormCloseDelegate(AddressOf FormClose)) 'Throws NullReferenceException: "Object reference not set to an instance of an object"
        Else
            Me.Close()
        End If
    End Sub
End Class


Even Threading.Timer using the TimerCallback throws the same exception.

VB Code:
Private LifeTimerCallback as New TimerCallback(AddressOf lifeTimer_CallbackMethod)
 Private Sub ToastForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'...
    Me.lifetimer = New Threading.Timer(Me.lifeTimerCallback, Nothing, lifetime, 0)
End Sub
 '...
 Private Sub lifeTimer_CallbackMethod(obj as Object)
    Me.FormClose()    'If I use Me.Close instead, it throws a InvalidOperationException: "Cross-thread operation not valid: Control 'PopupNotifierForm' accessed from a thread other than the thread it was created on."
End Sub

Am I doing anything wrong or is it just the way these things work? Is there no way to make the form work normally if instantiated and called from new threads? 

Any help will be truly appreciated.  :Smilie:  
And jmc, THANX ONCE AGAIN FOR THIS BEAUTIFUL SOLUTION!!!  :Thumb:

----------


## Tim Hadley

Thanks for your code Jim.  It's really great!  When using the FormAnimator class everything works great.  The only problem is that when my date time picker is displayed it's viewed as sunk down in the form and it lost it's blue border like my combo box has.  Do you have any idea on how to fix that problem?  is it a property on my date time picker?  I tried to look for the border property on the date time picker and realized that wasn't there.  Any help will be appreciated.

----------


## jmcilhinney

> Thanks for your code Jim.  It's really great!  When using the FormAnimator class everything works great.  The only problem is that when my date time picker is displayed it's viewed as sunk down in the form and it lost it's blue border like my combo box has.  Do you have any idea on how to fix that problem?  is it a property on my date time picker?  I tried to look for the border property on the date time picker and realized that wasn't there.  Any help will be appreciated.


If you don't use the FormAnimator does that not happen?  It sounds like it's not getting drawn using visual styles for some reason.  If you minimise the form and restore it does it get drawn properly then?

----------


## Tim Hadley

Yes you are correct.  If I don't use the Form Animator everything works fine.  Also, when I minimize the form it goes back to the original state.  I also have a drop down combo box right above the date time picker and once it is dropped over the date time picker and restored the date time picker goes back to the original state as well.

----------


## jmcilhinney

> Yes you are correct.  If I don't use the Form Animator everything works fine.  Also, when I minimize the form it goes back to the original state.  I also have a drop down combo box right above the date time picker and once it is dropped over the date time picker and restored the date time picker goes back to the original state as well.


I can't tell you exactly why but the DTP is obviously not getting drawn using visual styles the first time.  A workaround would be to handle the form's Shown event (assuming .NET 2.0+) and call the DTP's Refresh method to force an immediate repaint.  I guess the DTP may not look right during the animation but that's the best I've got for you I'm afraid.

----------


## Tim Hadley

Thanks!  That seemed to work just fine after the form loads.  I did the form' shown event and did a me.refresh and that took care of the date time picker being drawn right.  Thanks for all your help!

----------


## jmcilhinney

> Thanks!  That seemed to work just fine after the form loads.  I did the form' shown event and did a me.refresh and that took care of the date time picker being drawn right.  Thanks for all your help!


You shouldn't call Me.Refresh.  That will redraw the entire form, which is not needed.  If you read my post again you'll see I said call the Refresh method of the DateTimePicker, not the form.  If the DTP is all that needs to be repainted then that's all you should repaint.

----------


## Xancholy

Has there been any updates/replacements to this code since 2006 and the advent of framework3.5 ?

----------


## jmcilhinney

> Has there been any updates/replacements to this code since 2006 and the advent of framework3.5 ?


The principles in this thread use the Windows API, which hasn't changed in XP at least.  I don't know if there's anything new in Vista on this front.  .NET 3.5 includes no new functionality that can replace the unmanaged code so everything would be exactly the same.

----------


## Xancholy

Can you please tell me which posting number contains the most updated code ?

----------


## jmcilhinney

Whenever I update attached files in one of my CodeBank threads I always attach it to the first post and replace the old code, unless I have a specific reason to do otherwise.

----------


## Xancholy

Best practice. My only request would be to please include a sample image of toast in action... thanks

----------


## jmcilhinney

> Best practice. My only request would be to please include a sample image of toast in action... thanks


The whole point of this is the animation.  A screen shot of an animation is just a little useless.  Also, there's a fully working demo project attached for download.  You just need to download, unzip, open and run.  That's less than a minute's work to see a toast demo in all it's glory.  If you'd like to take a screen of it you're welcome to, but I don't see it impressing too many people.

----------


## jmcilhinney

I just ran this on Vista for the first time and the results were not especially inspiring.  I guess it has something to do with Aero and the drop shadows around windows.  Maybe there's a Vista replacement for the AnimateWindow API, or maybe the Slide animation just doesn't work properly on Vista.  I must say, I can't recall any of my installed apps using that effect.  The Blend effect works better but the drop shadow does disappear all of a sudden, making things less smooth than they ideally would be.  When I have time I may investigate this further.

EDIT: Just did a quick search and saw several people asking about issues with AnimateWindow under Vista but no solutions.  As such I can only recommend that you only use the Blend effect under Vista as the others produce unsatisfactory results.

----------


## scootabug

Hey JM,

This is great, but it's not suiting my requirements exactly.  I'm wondering if there's "easy" way to animate the window back to a particular point instead of just animating it as it's closed or opened?

Failing that I can set up my own functions to move the window with a timer and so on, but this is flawless so it's worth asking the silly question!

Cheers,
Scoota

----------


## jmcilhinney

> Hey JM,
> 
> This is great, but it's not suiting my requirements exactly.  I'm wondering if there's "easy" way to animate the window back to a particular point instead of just animating it as it's closed or opened?
> 
> Failing that I can set up my own functions to move the window with a timer and so on, but this is flawless so it's worth asking the silly question!
> 
> Cheers,
> Scoota


This API is only for showing and hiding the window.  You'll have to do as you suggested and use a Timer to move the form around while it's visible.

----------


## scootabug

Too easy, I'm already on my way.  Thanks for the quick response!

----------


## nbrege

Are these classes compatible with VS2008?  When I loaded the demo project there were a lot of errors to correct, mostly replacing the 'Me.' with the form names.  But it did run...

----------


## Atheist

Those are not errors, they're warnings.
jmcilhinney specifies that he created the project in VS2003 but there's no reason why it wouldnt work in 2008.

----------


## JuggaloBrotha

> Are these classes compatible with VS2008?  When I loaded the demo project there were a lot of errors to correct, mostly replacing the 'Me.' with the form names.  But it did run...


Why would you replace the 'Me' keyword with the form name?  'Me' already refers to the current class (the form in this case) that it needs to.

----------


## Atheist

Well in this case the warnings refer to shared members of the class, which "should" be accessed through the class, not an instance of the class.

----------


## jmcilhinney

Those warnings were due to referring to constants via the current instance. When I wrote that code I didn't know that constants are inherently Shared and 2003 didn't flag it. I will be rewriting this code sometime soon. It will still work as is though.

----------


## jmcilhinney

> I will be rewriting this code sometime soon.


I've removed the original attachments and added new ones. The solution attached to the first post was rewritten in VB 2005 with a few changes. The attached class file is from that solution, if you just want animation without the toast feature.

----------


## Minolwen

This works great and almost perfectly for what I need to do.  

Scenario:

I put a 15 second countdown timer on the initial form that activates the toast window.  Works beautifully!

Same setup but now when I run the project I move focus to notepad and typing continuously through the timer and through the toast window, meaning it did not steal focus.  Again, beautiful!

Same setup but now I minimize the application as soon as I run it, and the toast form doesn't show up.  I did set the toast form to always be on top to solve one other problem, but I doubt that affects this.

----------


## jmcilhinney

> This works great and almost perfectly for what I need to do.  
> 
> Scenario:
> 
> I put a 15 second countdown timer on the initial form that activates the toast window.  Works beautifully!
> 
> Same setup but now when I run the project I move focus to notepad and typing continuously through the timer and through the toast window, meaning it did not steal focus.  Again, beautiful!
> 
> Same setup but now I minimize the application as soon as I run it, and the toast form doesn't show up.  I did set the toast form to always be on top to solve one other problem, but I doubt that affects this.


That's a good point.  All my original tests were conducted with the demo app being the active app.  I tried using a Timer to spawn the Toast form and it did often get displayed behind another window.  I just set the form's TopMost property to True and that fixed it.

----------


## Xancholy

How can we ensure that the toast form appears within the bounds of the primary monitor in a multiple monitor setup ?

----------


## jmcilhinney

> How can we ensure that the toast form appears within the bounds of the primary monitor in a multiple monitor setup ?


It already does that for itself, although you'll have to make sure that the StartPosition is set to Manual.  I thought it was originally but I just downloaded the project and it's not, so either I forgot or that's a VS glitch.

```
Private Sub ToastForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    'Display the form just above the system tray.
    Me.Location = New Point(Screen.PrimaryScreen.WorkingArea.Width - Me.Width - 5, _
                            Screen.PrimaryScreen.WorkingArea.Height - Me.Height - 5)

    'Move each open form upwards to make room for this one.
    For Each openForm As ToastForm In ToastForm.openForms
        openForm.Top -= Me.Height + 5
    Next

    'Add this form from the open form list.
    ToastForm.openForms.Add(Me)

    'Start counting down the form's liftime.
    Me.lifeTimer.Start()
End Sub
```

----------


## webb315

First thanks for the awesome code.

Can you please tell me why my code is not working for loop? i have a list box. in which there are many items. and i use regular expression to match those values. and if there are match then the toast should pop up.. The thing is it does pops up but only for last item / match... even i used it in timer.. i want a popup for each match.. here is my code:


VB Code:
Dim myHTMLstring As String
        Dim mywebclient As New Net.WebClient
        myHTMLstring = mywebclient.DownloadString("www.somesite.com")
        TextBox18.Text = myHTMLstring
         Dim myMatches2 As MatchCollection
        Dim myRegex2 As New Regex("(?<=ON >> )[a-zA-Z0-9\. \$%?!&\#(|)_@^£;+/:\,^=]+")
        Dim t2 As String = _TextBox18.Text
        myMatches2 = myRegex2.Matches(t2)
        Dim successfulMatch2 As Match
        For Each successfulMatch2 In myMatches2
            If ListBox4.Items.Contains(successfulMatch2.Value) Then
                TextBox19.Text = successfulMatch2.Value
                Timer6.Enabled = True
                ListBox4.Items.Remove(successfulMatch2.Value)
            Else
            End If
         Next

ANd the timer


VB Code:
If Timer6.Enabled = True Then
            Static sliceCount As Integer = 0
            sliceCount += 1
            Dim slice As New ToastForm(Me.rng.Next(2000, 4000), sliceCount & ": " & TextBox19.Text & " Is Online")
            slice.Height = Me.rng.Next(100, 100)
            slice.Show()
        End If
        Timer6.Enabled = False

And yes how to change the width of the popup?  :Big Grin:

----------


## jmcilhinney

> Can you please tell me why my code is not working for loop?


If your UI thread is busy executing the loop then it can't execute the second code block.  Each thread can only do one thing at a time, so the Timer's Tick event won't be handled until the loop is finished.

----------


## webb315

> If your UI thread is busy executing the loop then it can't execute the second code block.  Each thread can only do one thing at a time, so the Timer's Tick event won't be handled until the loop is finished.


So can you give me any solution for this thing?

----------


## jmcilhinney

> So can you give me any solution for this thing?


I don't really understand why you're using a Timer at all but, regardless, your issue really has nothing to do with the topic of this thread.  I suggest that you start a new thread in the VB.NET forum.  Explain what you're trying to achieve and those with the time, knowledge and inclination can help you find the best way to achieve it.

----------


## webb315

> I don't really understand why you're using a Timer at all but, regardless, your issue really has nothing to do with the topic of this thread.  I suggest that you start a new thread in the VB.NET forum.  Explain what you're trying to achieve and those with the time, knowledge and inclination can help you find the best way to achieve it.


No problem mate.  :wave: 

Can you please tell me how to change the width of the popups?

----------


## jmcilhinney

> No problem mate. 
> 
> Can you please tell me how to change the width of the popups?


It's just a form so you set it's Width the way you would any form.

----------


## webb315

> It's just a form so you set it's Width the way you would any form.


Oh the hieght was the random one.. sorry my bad..  :Embarrassment:

----------


## vbjay.net

Thanks for this.  This is a great way to notify people.  I used it to show that there is a new release on my codeplex project so users can get the latest and greatest.

Employee Scheduler

----------


## sbllonely

hi, jmcilhinney. you know I try to log in my account that I can't open long ago.
because I just start again with vb.net. and I want to say that you are make me smile. you are imagine  :Smilie: 
Thank for your smooth slide code  :Smilie:

----------


## JEmlay

This is pure awesome!  Exactly what I was looking for...stacked notifications.

This base saved me tons of time so for that, many thanks!

Since I first grabbed this I made a bunch of changes:

Support to pass two text messages fields

Support to pass an image resource (icon)

Due to Win7 I had to kill the glass as the effects were just odd, so I have a single little box then of course had to create my own close button

Added a mouse over function that stops the timers.  Mousing out starts them again.

Added some click options to take me directly to the item in question.

So far my users absolutely love the upgrade as do I!

----------


## jmcilhinney

@JEmlay, glad to know that it's been put to good use.  If your code is proprietary then I understand but, if possible, it might be nice to post your extensions here to help others.

----------


## JEmlay

It's proprietary but I'll update the test I created from your project once everything is done.  That way myself and my team will always have it around to put in new projects.

----------


## JEmlay

As promised here's my changes.  I removed the passing of the icon and opted to instead simply change the form background globally based on my needs.  Those different small backgrounds include whatever image changes I need.  This was easier since a couple notifications required a couple images.

In this change up:

Support to pass two text message fields.

Killed glass and opted for simple square-ish form due to Win7 (possibly Vista as well) goofing it all up.  I also hard coded fade in and out as slide and roll were also goofed up by Win7.  There might be some extra code to clean up that are roll and slide specific.

Added a mouse over function that stops the timers. Mousing out starts them again.

Added a click option to handle the notification item in question.  Simply click the notification.

Added exit button for no other reason then to remain consistant with other pop up notifications out there (Outlook, Trillian.....).

Enjoy and again, a million thanks to the author!

----------


## Crystalii

I am having problems with the popup. I use JEmlays' version. But my problem has nothing to do with the feature he added, so I guess this is a problem concerning the original version as well.

Okay so when the form pops up in the bottom right corner, then let's say I am browing the web. I have to minimize the webbrowser, in order to see the form. Because the form is like behind the webbrowser, or whatever program I am running. Is it possible to make it stay on the top regardless what I am doing ?

----------


## Crystalii

Never mind, I fixed the problem.

Add this to Form_Load in FormAnimator.vb:


            Me.Form.TopMost = True

----------


## SirPereira

After almost 10 years later, I could still say that this is such a great contribution.

However, I'm facing some issues. I can only generate something like 12-16 toasts, after that Toasts do not show up at all.

They are set to TopMost.

Any ideas?

Thanks!

----------


## ByteKnight

Fantastic example! Really taught me a lot! I do have one question though. Is there a way to make it so that each instance of the ToastForm doesn't create an entry in the task bar?

EDIT: NEVERMIND!  :Smilie:  I found a property that I hadn't seen before. " Form.ShowInTaskbar " LOL How easy was that?

----------


## eliaspizarro

inputbox or msgbox disapear sometimes. for example add this to the code

    Sub errTest()
        Dim Notification As New frmNotification(5000, "This is a test message " & variable, "This is a second text message to pass")
        Notification.Show()
        variable += 1
    End Sub

    Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        errTest()
        errTest()
        errTest()

        MsgBox("test")
    End Sub

good job btw

regards,

----------


## jmcilhinney

> inputbox or msgbox disapear sometimes. for example add this to the code
> 
>     Sub errTest()
>         Dim Notification As New frmNotification(5000, "This is a test message " & variable, "This is a second text message to pass")
>         Notification.Show()
>         variable += 1
>     End Sub
> 
>     Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
> ...


Maybe if you could provide a clear explanation of what you expect to see and what you actually do see, we'd know what to look out for if we decide to test your code.

----------


## JuggaloBrotha

> inputbox or msgbox disapear sometimes. for example add this to the code
> 
>     Sub errTest()
>         Dim Notification As New frmNotification(5000, "This is a test message " & variable, "This is a second text message to pass")
>         Notification.Show()
>         variable += 1
>     End Sub
> 
>     Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
> ...


What are you even talking about?

----------

