2011-02-03 12 views
9


Mam program, który pozwala użytkownikowi otworzyć kilka formularzy. Gdy dane zdarzenie wystąpi (np. Minęło 30 sekund), muszę zwrócić uwagę użytkownika na Formularz, który wywołał zdarzenie, nie kradnąc fokusu. ja już się z formularza na górze zZdobądź uwagę użytkownika bez kradzieży ostrości

f.TopMost = true; 

ale chciałbym wdrożyć jakąś alternatywę dla tego. Ponieważ zmiana koloru ramki na ramce wydaje się prawie niemożliwym zadaniem (rozwiązanie to byłoby najlepsze), ktoś ma pomysł, jak zwrócić uwagę, nie kradnąc ostrości?

Odpowiedz

19

Opcja A: Musisz użyć FlashWindowEx z Windows API. To nie jest dostępne w .NET, więc musisz użyć PInvoke.

Opcja B: Użyj końcówki balonu z zasobnika systemowego. Jest to wbudowane w .NET, ale wymaga, aby Twoja aplikacja korzystała z ikony powiadomienia, której możesz nie chcieć. Więcej szczegółów tutaj: http://msdn.microsoft.com/en-us/library/system.windows.forms.notifyicon.showballoontip.aspx

Tutaj jest przykładem, jak korzystać Opcja A:

pInvoke.net ma najlepszy przykład: http://pinvoke.net/default.aspx/user32.FlashWindowEx

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

zdefiniowane przez użytkownika typy:

[StructLayout(LayoutKind.Sequential)] 
public struct FLASHWINFO 
{ 
    public UInt32 cbSize; 
    public IntPtr hwnd; 
    public UInt32 dwFlags; 
    public UInt32 uCount; 
    public UInt32 dwTimeout; 
} 

Notatki:

//Stop flashing. The system restores the window to its original state. 
public const UInt32 FLASHW_STOP = 0; 
//Flash the window caption. 
public const UInt32 FLASHW_CAPTION = 1; 
//Flash the taskbar button. 
public const UInt32 FLASHW_TRAY = 2; 
//Flash both the window caption and taskbar button. 
//This is equivalent to setting the FLASHW_CAPTION | FLASHW_TRAY flags. 
public const UInt32 FLASHW_ALL = 3; 
//Flash continuously, until the FLASHW_STOP flag is set. 
public const UInt32 FLASHW_TIMER = 4; 
//Flash continuously until the window comes to the foreground. 
public const UInt32 FLASHW_TIMERNOFG = 12; 

Wskazówki & Sztuczki:

Proszę dodać!

Przykładowy kod:

/// <summary> 
/// Flashes a window 
/// </summary> 
/// <param name="hWnd">The handle to the window to flash</param> 
/// <returns>whether or not the window needed flashing</returns> 
public static bool FlashWindowEx(IntPtr hWnd) 
{ 
    FLASHWINFO fInfo = new FLASHWINFO(); 

    fInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(fInfo)); 
    fInfo.hwnd = hWnd; 
    fInfo.dwFlags = FLASHW_ALL; 
    fInfo.uCount = UInt32.MaxValue; 
    fInfo.dwTimeout = 0; 

    return FlashWindowEx(ref fInfo); 
} 

...

/// Minor adjust to the code above 
/// <summary> 
/// Flashes a window until the window comes to the foreground 
/// Receives the form that will flash 
/// </summary> 
/// <param name="hWnd">The handle to the window to flash</param> 
/// <returns>whether or not the window needed flashing</returns> 
public static bool FlashWindowEx(Form frm) 
{ 
     IntPtr hWnd = frm.Handle; 
     FLASHWINFO fInfo = new FLASHWINFO(); 

     fInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(fInfo)); 
     fInfo.hwnd = hWnd; 
     fInfo.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG; 
     fInfo.uCount = UInt32.MaxValue; 
     fInfo.dwTimeout = 0; 

     return FlashWindowEx(ref fInfo); 
} 

Oto oficjalny przykład Microsoft: http://msdn.microsoft.com/en-us/library/ms679347(v=vs.85).aspx

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

    [StructLayout(LayoutKind.Sequential)] 
    public 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 FlashWindowFlags dwFlags; //uint 
     /// <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; 
    } 


    public enum FlashWindowFlags : uint 
    { 
     /// <summary> 
     /// Stop flashing. The system restores the window to its original state. 
     /// </summary> 
     FLASHW_STOP = 0, 

     /// <summary> 
     /// Flash the window caption. 
     /// </summary> 
     FLASHW_CAPTION = 1, 

     /// <summary> 
     /// Flash the taskbar button. 
     /// </summary> 
     FLASHW_TRAY = 2, 

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

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

     /// <summary> 
     /// Flash continuously until the window comes to the foreground. 
     /// </summary> 
     FLASHW_TIMERNOFG = 12 
    } 


    public static bool FlashWindow(IntPtr hWnd, 
            FlashWindowFlags fOptions, 
            uint FlashCount, 
            uint FlashRate) 
    { 
     if(IntPtr.Zero != hWnd) 
     { 
      FLASHWINFO fi = new FLASHWINFO(); 
      fi.cbSize = (uint)Marshal.SizeOf(typeof(FLASHWINFO)); 
      fi.dwFlags = fOptions; 
      fi.uCount = FlashCount; 
      fi.dwTimeout = FlashRate; 
      fi.hwnd = hWnd; 

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

    public static bool StopFlashingWindow(IntPtr hWnd) 
    { 
     if(IntPtr.Zero != hWnd) 
     { 
      FLASHWINFO fi = new FLASHWINFO(); 
      fi.cbSize = (uint)Marshal.SizeOf(typeof(FLASHWINFO)); 
      fi.dwFlags = (uint)FlashWindowFlags.FLASHW_STOP; 
      fi.hwnd = hWnd; 

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

Dobrze zadzwoń, używając 'NotifyIcon'! –

+0

Ważne: W systemie Windows 7 niektórzy użytkownicy zgłosili to jako Nie działa. Po pewnych badaniach odkryłem, że powodem jest to, że jeśli twoja aplikacja ma wiele okien i jeśli którekolwiek z tych okien jest aktywne, gdy wywołasz ten interfejs API, aby błyskać innym oknem, to nie zadziała. Będzie działać tylko wtedy, gdy wszystkie okna w twoim programie są nieaktywne. Jeśli utknąłeś w pierwszym scenariuszu, użyj starszego api FlashWindow: http://pinvoke.net/default.aspx/user32/FlashWindow.html – tunafish24

7

W systemie Windows 7 pasek postępu na formularz jest reprezentowany w jego taskba przycisk r; możesz to wykorzystać. Musi być też sposób na podświetlenie przycisku paska zadań, tak jak robią to programy IM, gdy otrzymujesz nową wiadomość.

+0

Chciałbym zobaczyć, jak po prostu podświetlić przycisk paska zadań zamiast go migać ... mając problem ze znalezieniem dobrych próbek kodu, które to robią. –

Powiązane problemy