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.
Last edited by jmcilhinney; Nov 26th, 2008 at 10:38 PM.
Reason: Remove original and replace with better code
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?
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.
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.
Re: Animated Window Effects, AKA Fading form in and out
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
Last edited by jmcilhinney; Aug 30th, 2005 at 10:08 PM.
Re: Animated Window Effects, AKA Fading form in and out
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
Re: Animated Window Effects, AKA Fading form in and out
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.
Re: Animated Window Effects, AKA Fading form in and out
Originally Posted by jmcilhinney
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.
End Enum
'The Flags attribute allows horizontal and vertical directions to 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
Private m_AnimationType As AnimationTypes = AnimationTypes.None 'The type of animation used to show and hide the window.
Private m_SlideDirection As SlideDirections = SlideDirections.None 'The direction in which to slide the window if the animation type is Slide.
Private m_AnimationDuration As Integer = 500 'The number of milliseconds over which the animation is played.
'The type of animation used to show and hide the window.
Public Property AnimationType() As AnimationTypes
Get
Return Me.m_AnimationType
End Get
Set(ByVal Value As AnimationTypes)
Me.m_AnimationType = Value
End Set
End Property
'The direction in which to slide the window if the animation type is Slide.
Public Property SlideDirection() As SlideDirections
Get
Return Me.m_SlideDirection
End Get
Set(ByVal Value As SlideDirections)
Me.m_SlideDirection = Value
End Set
End Property
'The number of milliseconds over which the animation is played.
Public Property AnimationDuration() As Integer
Get
Return Me.m_AnimationDuration
End Get
Set(ByVal Value As Integer)
Me.m_AnimationDuration = Value
End Set
End Property
Private Declare Auto Function AnimateWindow Lib "user32" (ByVal hwnd As IntPtr, _
ByVal dwtime As Integer, _
ByVal dwflags As Integer) As Boolean
Protected Overrides Sub OnLoad(ByVal e As EventArgs)
Me.AnimateWindow(Me.Handle, _
Me.AnimationDuration, _
Me.m_AnimationType Or Me.m_SlideDirection)
End Sub
Protected Overrides Sub OnClosing(ByVal e As System.ComponentModel.CancelEventArgs)
Me.AnimateWindow(Me.Handle, _
Me.AnimationDuration, _
AW_HIDE Or Me.m_AnimationType Or Me.m_SlideDirection)
End Sub
End Class
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....
Re: Animated Window Effects, AKA Fading form in and out
Originally Posted by FYRe
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.
Re: Animated Window Effects, AKA Fading form in and out
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.
Re: Animated Window Effects, AKA Fading form in and out
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.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
Re: Animated Window Effects, AKA Fading form in and out
Originally Posted by 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
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.
Re: Animated Window Effects, AKA Fading form in and out
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.
Re: Animated Window Effects, AKA Fading form in and out
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.
Last edited by jmcilhinney; Sep 29th, 2005 at 12:24 AM.
Re: Animated Window Effects with "Toast" popup demo
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.
Look into the heart of infinity and find your truth
Colonel Tom Edwards: This is the most fantastic story I've ever heard Jeff Trent: And every word of it's true, too Colonel Tom Edwards: That's the fantastic part of it
Re: Animated Window Effects with "Toast" popup demo
Originally Posted by jud9r
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.
Re: Animated Window Effects with "Toast" popup demo
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.
Re: Animated Window Effects with "Toast" popup demo
Originally Posted by dee-u
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.
Re: Animated Window Effects with "Toast" popup demo
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
at System.Windows.Forms.DibGraphicsBufferManager.CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, Int32 ulWidth, Int32 ulHeight, IntPtr& ppvBits)
at System.Windows.Forms.DibGraphicsBufferManager.CreateBuffer(IntPtr src, Int32 offsetX, Int32 offsetY, Int32 width, Int32 height)
at System.Windows.Forms.DibGraphicsBufferManager.AllocBuffer(Graphics targetGraphics, IntPtr targetDC, Rectangle targetBounds)
at System.Windows.Forms.DibGraphicsBufferManager.AllocBufferInTempManager(Graphics targetGraphics, IntPtr targetDC, Rectangle targetBounds)
at System.Windows.Forms.DibGraphicsBufferManager.AllocBuffer(IntPtr target, Rectangle targetBounds)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Label.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.Control.SendMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.Label.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
at System.Windows.Forms.Control.DefWndProc(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Label.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
at System.Windows.Forms.Control.DefWndProc(Message& m)
at System.Windows.Forms.Form.DefWndProc(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at WindowsApplication2.FormAnimator.AnimateWindow(IntPtr hWnd, Int32 dwTime, Int32 dwFlags)
at WindowsApplication2.FormAnimator.m_Form_Closing(Object sender, CancelEventArgs e) in E:\VBForumsFiles\FormAnimationAndToastDemo\WindowsApplication2\FormAnimator.vb:line 322
at System.ComponentModel.CancelEventHandler.Invoke(Object sender, CancelEventArgs e)
at System.Windows.Forms.Form.OnClosing(CancelEventArgs e)
at System.Windows.Forms.Form.WmClose(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control.SendMessage(Int32 msg, Int32 wparam, Int32 lparam)
at System.Windows.Forms.Form.Close()
at WindowsApplication2.ToastForm.lifeTimer_Tick(Object sender, EventArgs e) in E:\VBForumsFiles\FormAnimationAndToastDemo\WindowsApplication2\ToastForm.vb:line 229
at System.Windows.Forms.Timer.OnTick(EventArgs e)
at System.Windows.Forms.Timer.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr idEvent, IntPtr dwTime)
************** JIT Debugging **************
To enable just in time (JIT) debugging, the config file for this
application or machine (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.
When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the machine
rather than being handled by this dialog.
Regards,
™
As a gesture of gratitude please consider rating helpful posts. c",)
Re: Animated Window Effects with "Toast" popup demo
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.