2012-01-19 13 views
14

Używam C#/WPF do utworzenia aplikacji. W tej aplikacji chcę migotać okno, jeśli wystąpi określone zdarzenie, aby użytkownik tej aplikacji wiedział, że coś się stało. Jak mogę to uzyskać w mojej aplikacji C# WPF.Wymuszenie mrugnięcia okna po wystąpieniu określonego zdarzenia w C#/WPF

Podobnie jak w komunikatorze Yahoo Messenger, jeśli otrzymasz wiadomość, okno komunikatu miga, aby uzyskać fokus, chcę użyć tego efektu w mojej aplikacji.

+0

Jestem nowy w WPF i Szukałem na google ale nie znalazłem żadnego łatwego rozwiązania, które łatwo zrozumiałbym ... –

+0

@Marco Ten link pokazuje, jak sprawić, aby okno mrugało w taskbie r, a nie jak migać w regularnym rozmiarze okna. – Rachel

Odpowiedz

27

Flashing okno i pasek zadań w sposób podobny do IM powiadomień mogą być realizowane w WPF przy użyciu następującego kodu. Wykorzystuje PlatformInvoke do wywołania funkcji WinAPI FlashWindowEx pomocą uchwytu Win32 z WPF Application.Current.MainWindow

Code

public class FlashWindowHelper 
{ 
    private IntPtr mainWindowHWnd; 
    private Application theApp; 

    public FlashWindowHelper(Application app) 
    { 
     this.theApp = app; 
    } 

    public void FlashApplicationWindow() 
    { 
     InitializeHandle(); 
     Flash(this.mainWindowHWnd, 5); 
    } 

    public void StopFlashing() 
    { 
     InitializeHandle(); 

     if (Win2000OrLater) 
     { 
      FLASHWINFO fi = CreateFlashInfoStruct(this.mainWindowHWnd, FLASHW_STOP, uint.MaxValue, 0); 
      FlashWindowEx(ref fi); 
     } 
    } 

    private void InitializeHandle() 
    { 
     if (this.mainWindowHWnd == IntPtr.Zero) 
     { 
      // Delayed creation of Main Window IntPtr as Application.Current passed in to ctor does not have the MainWindow set at that time 
      var mainWindow = this.theApp.MainWindow; 
      this.mainWindowHWnd = new System.Windows.Interop.WindowInteropHelper(mainWindow).Handle; 
     } 
    } 

    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    private static extern bool FlashWindowEx(ref FLASHWINFO pwfi); 

    [StructLayout(LayoutKind.Sequential)] 
    private struct FLASHWINFO 
    { 
     /// <summary> 
     /// The size of the structure in bytes. 
     /// </summary> 
     public uint cbSize; 
     /// <summary> 
     /// A Handle to the Window to be Flashed. The window can be either opened or minimized. 
     /// </summary> 
     public IntPtr hwnd; 
     /// <summary> 
     /// The Flash Status. 
     /// </summary> 
     public uint dwFlags; 
     /// <summary> 
     /// The number of times to Flash the window. 
     /// </summary> 
     public uint uCount; 
     /// <summary> 
     /// The rate at which the Window is to be flashed, in milliseconds. If Zero, the function uses the default cursor blink rate. 
     /// </summary> 
     public uint dwTimeout; 
    } 

    /// <summary> 
    /// Stop flashing. The system restores the window to its original stae. 
    /// </summary> 
    public const uint FLASHW_STOP = 0; 

    /// <summary> 
    /// Flash the window caption. 
    /// </summary> 
    public const uint FLASHW_CAPTION = 1; 

    /// <summary> 
    /// Flash the taskbar button. 
    /// </summary> 
    public const uint FLASHW_TRAY = 2; 

    /// <summary> 
    /// Flash both the window caption and taskbar button. 
    /// This is equivalent to setting the FLASHW_CAPTION | FLASHW_TRAY flags. 
    /// </summary> 
    public const uint FLASHW_ALL = 3; 

    /// <summary> 
    /// Flash continuously, until the FLASHW_STOP flag is set. 
    /// </summary> 
    public const uint FLASHW_TIMER = 4; 

    /// <summary> 
    /// Flash continuously until the window comes to the foreground. 
    /// </summary> 
    public const uint FLASHW_TIMERNOFG = 12; 

    /// <summary> 
    /// Flash the spacified Window (Form) until it recieves focus. 
    /// </summary> 
    /// <param name="hwnd"></param> 
    /// <returns></returns> 
    public static bool Flash(IntPtr hwnd) 
    { 
     // Make sure we're running under Windows 2000 or later 
     if (Win2000OrLater) 
     { 
      FLASHWINFO fi = CreateFlashInfoStruct(hwnd, FLASHW_ALL | FLASHW_TIMERNOFG, uint.MaxValue, 0); 

      return FlashWindowEx(ref fi); 
     } 
     return false; 
    } 

    private static FLASHWINFO CreateFlashInfoStruct(IntPtr handle, uint flags, uint count, uint timeout) 
    { 
     FLASHWINFO fi = new FLASHWINFO(); 
     fi.cbSize = Convert.ToUInt32(Marshal.SizeOf(fi)); 
     fi.hwnd = handle; 
     fi.dwFlags = flags; 
     fi.uCount = count; 
     fi.dwTimeout = timeout; 
     return fi; 
    } 

    /// <summary> 
    /// Flash the specified Window (form) for the specified number of times 
    /// </summary> 
    /// <param name="hwnd">The handle of the Window to Flash.</param> 
    /// <param name="count">The number of times to Flash.</param> 
    /// <returns></returns> 
    public static bool Flash(IntPtr hwnd, uint count) 
    { 
     if (Win2000OrLater) 
     { 
      FLASHWINFO fi = CreateFlashInfoStruct(hwnd, FLASHW_ALL | FLASHW_TIMERNOFG, count, 0); 

      return FlashWindowEx(ref fi); 
     }    

     return false; 
    } 

    /// <summary> 
    /// A boolean value indicating whether the application is running on Windows 2000 or later. 
    /// </summary> 
    private static bool Win2000OrLater 
    { 
     get { return Environment.OSVersion.Version.Major >= 5; } 
    } 
} 

Wykorzystanie

var helper = new FlashWindowHelper(Application.Current); 

// Flashes the window and taskbar 5 times and stays solid 
// colored until user focuses the main window 
helper.FlashApplicationWindow(); 

// Cancels the flash at any time 
helper.StopFlashing(); 
+0

To jest świetny przykład ... z wyjątkiem dla mnie ikona paska zadań miga tylko raz przez mniej niż sekundę :( – Julien

+0

Naprawdę? Na jakim systemie operacyjnym? Użyłem powyższego (było to w umyśle WinXP) i to by mogło błyskać na dobre 5 sekundy, potem pozostaję na pomarańczowo –

+0

Przepraszam, klamka okna używana przez twoją klasę była niepoprawna dla mojego projektu Zmodyfikowałem ją nieznacznie, aby zaakceptować niestandardowe klamki i wszystko jest dobrze, dziękuję bardzo! – Julien

6

Możesz użyć klasy TaskBarItem, aby ikona paska zadań aplikacji migała. Oto kilka zasobów, które pomogą Ci to osiągnąć:
- http://social.msdn.microsoft.com/Forums/en/wpf/thread/369bc5ee-a9a7-493f-978f-27a8ddedea06
- http://www.bobpowell.net/flashbar.htm

Następnie można flash, shake, fade-in fade-out lub whatever one of the other zillion FX użyciu WPF animacje. To bardzo proste i prawie nie wymaga kodu, jeśli masz Expression Blend, praca jest jeszcze łatwiejsza.

+0

Po prostu chcę migać okno WPF, nie chcę wyświetlać postępu. Używam tego kodu, ale nie pomogło mi to w moim zadaniu. Czy możesz mi po prostu powiedzieć, jak wyglądać okno WPF na konkretne wydarzenie, czy kliknę przycisk lub w określonym oknie czasowym miga. –

+0

Odpowiedź zaktualizowana. Nie odniosłem się do paska postępu, możesz spowodować, że ikona paska zadań zacznie migać sama, z wyjątkiem oprócz migania okna. – Shimmy

+1

Niektóre linki są martwe, pls naprawić je. –

Powiązane problemy