2011-02-03 15 views
9


Ho un programma che consente all'utente di aprire diversi moduli. Una volta che si verifica un determinato evento (ad esempio: 30 secondi trascorsi), devo attirare l'attenzione dell'utente sul Modulo che ha attivato l'evento, senza rubare l'attenzione. ho già ottenere la forma sulla parte superiore conAttirare l'attenzione dell'utente senza rubare lo stato

f.TopMost = true; 

ma mi piacerebbe di attuare alcune alternativa a quella. Dato che cambiare il colore del bordo della cornice sembra un compito quasi impossibile (questa soluzione sarebbe stata la migliore), qualcuno ha qualche idea su come attirare l'attenzione senza rubare l'attenzione?

risposta

19

Opzione A: È necessario utilizzare FlashWindowEx dall'API di Windows. Questo non è disponibile in .NET, quindi è necessario utilizzare PInvoke.

Opzione B: utilizzare una punta a palloncino sulla barra delle applicazioni. Questo è integrato in .NET, ma richiede che l'applicazione utilizzi un'icona di notifica, che potresti non volere. Maggiori dettagli qui: http://msdn.microsoft.com/en-us/library/system.windows.forms.notifyicon.showballoontip.aspx

Ecco l'esempio di come utilizzare Opzione A:

pInvoke.net ha il miglior esempio: http://pinvoke.net/default.aspx/user32.FlashWindowEx

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

tipi definiti dall'utente:

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

Note:

//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; 

Suggerimenti & Trucchi:

Si prega di aggiungere alcuni!

codice di esempio:

/// <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); 
} 

Ecco l'esempio di Microsoft ufficiale: 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

Buona chiamata per l'uso di 'NotifyIcon'! –

+0

Importante: su Windows 7 alcuni utenti hanno segnalato che questo non funziona. Dopo alcune ricerche, ho scoperto che, se la tua applicazione ha più finestre e se una di queste finestre è attiva mentre chiami questa API per far lampeggiare un'altra finestra, non funzionerà. Funzionerà solo se tutte le finestre del tuo programma sono inattive. Se sei bloccato nel primo scenario, utilizza la vecchia API FlashWindow: http://pinvoke.net/default.aspx/user32/FlashWindow.html – tunafish24

7

In Windows 7, una barra di avanzamento su una forma è rappresentata nella sua taskba pulsante r; potresti sfruttarlo. C'è anche un modo per evidenziare semplicemente il pulsante della barra delle applicazioni, come fanno i programmi di messaggistica istantanea quando ricevi un nuovo messaggio.

+0

Mi piacerebbe vedere come evidenziare semplicemente il pulsante della barra delle applicazioni invece di farlo lampeggiare ... avere problemi nel trovare buoni esempi di codice che lo facciano. –

Problemi correlati