.NET AnimateWindow

2019-02-27 10:11发布

问题:

I am trying to make a notification window like Outlook uses when you receive a new email. I have a modeless form for the notification window with two Label controls on it to display the notification info. To get the fade-in effect, I am p/invoking the Win32 AnimateWindow function. Everything seems to be working alright except for one thing.

When I p/invoke AnimateWindow, the text in the Label controls just appears on the Form after the animation effect is over. I would like it to gradually fade in with the rest of the Form. I suspect that it has something to do with when the Form updates its child controls. I'm thinking that the Form doesn't tell its children to update until after the AnimateWindow call. I have tried sticking Form.Update() calls after setting the text fields for the Labels, but that doesn't help.

Basic steps I'm taking now:

// Main form of the application.
public class MainForm : Form
{
   // The notification toast.
   protected ToastForm toast;

   // Public method called to show and update the toast.
   public void UpdateToast( string text1, string text2 )
   {
      // Create a new toast form if one does not exist yet.
      if ( this.toast == null )
      {
         this.toast = new ToastForm();
      }

      // Update the toast form's Label controls.
      // Note that this isn't exactly how it's done in my app.  There are fields safely
      // wrapping the Label controls.  I just did it this way here to be concise.
      this.toast.firstLabel.Text = text1;
      this.toast.secondLabel.Text = text2;

      // This doesn't help.
      this.toast.Update();

      // P/invoke the Win32 AnimateWindow function on the toast form.
      User32.AnimateWindow( this.toast.Handle, 750, AnimateWindowFlags.AW_ACTIVATE | AnimateWindowFlags.AW_BLEND );

      // Call Show method on the toast form.  This is needed to get the controls to
      // update at all.
      this.toast.Show( this );
   }
}

Does anyone have any suggestions to get this to work?

EDIT:
I worked out a hack. After the Label text is assigned, I set the toast's size to 0 width and 0 height. Next I call first Show and then Hide on the toast. Then I set the toast's size back to what it was originally. Finally, I call AnimateWindow on the toast. Yeah, it works, but it is a hack... Any better ideas?

回答1:

There is a great example of this on the codeproject site.



回答2:

By default, WinForms controls use GDI+ to render text. I suspect that this is the reason for this behavior.

Try disabling compatible text rendering in the entire application or for the labels to force it to use GDI instead.



回答3:

Just use a timer and fade the form in through its Opacity property. Should work great for you.