我有一个让用户打开几个表单的程序。一旦给定的事件发生(例如:30秒过去了),我需要引起用户关注触发事件的表单,而不会窃取焦点。 我已经顶得上的形式获取用户关注度而不偷盗
f.TopMost = true;
,但我想实现一些替代了这一点。由于改变边框颜色的框架似乎几乎是不可能的任务(这种解决方案将是最好的),有人有没有想法如何获得关注而不偷窃焦点?
我有一个让用户打开几个表单的程序。一旦给定的事件发生(例如:30秒过去了),我需要引起用户关注触发事件的表单,而不会窃取焦点。 我已经顶得上的形式获取用户关注度而不偷盗
f.TopMost = true;
,但我想实现一些替代了这一点。由于改变边框颜色的框架似乎几乎是不可能的任务(这种解决方案将是最好的),有人有没有想法如何获得关注而不偷窃焦点?
选项A:您需要使用Windows API中的FlashWindowEx。这在.NET中不可用,所以您需要使用PInvoke。
选项B:使用系统托盘中的气球端。这是内置于.NET中的,但要求您的应用程序使用通知图标,这可能不是您想要的。更多细节在这里:http://msdn.microsoft.com/en-us/library/system.windows.forms.notifyicon.showballoontip.aspx
这里是如何使用选项A的例子:
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);
}
下面是微软官方的例子: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;
}
在Windows 7中,一个进度条上一个表单在其taskba中表示r按钮;你可能会利用这一点。还有一种方法可以突出显示任务栏按钮,就像IM程序在收到新消息时所做的一样。
使用`NotifyIcon`的好电话! – 2012-10-18 14:47:10
重要提示:在Windows 7上,有些用户将其报告为“不工作”。经过一番研究,我发现原因是如果你的应用程序有多个窗口,并且当你调用这个API来刷新另一个窗口时这些窗口中的任何一个是活动的,它将不起作用。它只会在程序中的所有窗口都处于非活动状态时才起作用。如果你被困在第一种情况下,然后使用旧的API FlashWindow:http://pinvoke.net/default.aspx/user32/FlashWindow.html – tunafish24 2015-10-26 20:00:49