2011-02-03 2 views
9


У меня есть программа, которая позволяет пользователю открывать несколько форм. Как только данный eventoccurs (например, прошло 30 секунд), мне нужно привлечь внимание пользователя к Форме, которая вызвала событие, без кражи фокуса. я уже получить форму на вершине сОбратите внимание на пользователя без кражи фокуса

f.TopMost = true; 

, но я хотел бы реализовать некоторую альтернативу к этому. Поскольку изменение цвета рамки кадра кажется почти невозможной задачей (это решение было бы лучшим), у кого-нибудь есть идея о том, как привлечь внимание без кражи фокуса?

ответ

19

Вариант A: Вам необходимо использовать FlashWindowEx из API окон. Это недоступно в .NET, поэтому вам нужно использовать PInvoke.

Вариант B: Используйте наконечник баллона из системного лотка. Он встроен в .NET, но требует, чтобы ваше приложение использовало значок уведомления, который вам может и не понадобиться. Подробнее здесь: http://msdn.microsoft.com/en-us/library/system.windows.forms.notifyicon.showballoontip.aspx

Вот пример того, как использовать Вариант А:

pInvoke.net имеет лучший пример: http://pinvoke.net/default.aspx/user32.FlashWindowEx

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

определяемые пользователем типы:

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

Примечания:

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

Подсказки & Трюки:

Пожалуйста, добавьте некоторые!

Пример кода:

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

Вот официальный 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

Хороший звонок при использовании 'NotifyIcon'! –

+0

Важно: В Windows 7 некоторые пользователи сообщили об этом как «Не работает». После некоторых исследований я обнаружил, что причина заключается в том, что если ваше приложение имеет несколько окон, и если какое-либо из этих окон активно, когда вы вызываете этот API для запуска другого окна, это не сработает. Он будет работать, только если все окна в вашей программе неактивны. Если вы застряли в первом сценарии, используйте более старый api FlashWindow: http://pinvoke.net/default.aspx/user32/FlashWindow.html – tunafish24

7

В Windows 7 прогресс бар на форма представлена ​​в ее задаче r кнопка; вы можете использовать это. Там также должен быть способ просто выделить кнопку панели задач, например, программы обмена мгновенными сообщениями, когда вы получаете новое сообщение.

+0

Мне бы хотелось увидеть, как просто выделить кнопку панели задач, а не мигать ... не имея возможности найти хорошие образцы кода, которые это делают. –

Смежные вопросы