简体   繁体   English

无需关注焦点即可吸引用户注意力

[英]Get user attention without stealing focus

I have a program that lets the user open several forms. 我有一个程序,让用户打开几个表单。 Once a given event occurs (ex : 30 seconds have passed) I need to get user attention on the Form that triggered the event, without stealing the focus. 一旦发生给定事件(例如:30秒已经过去),我需要让用户注意触发事件的表单,而不会窃取焦点。 I already get the form on top with: 我已经将表格放在首位:

f.TopMost = true;

but I'd like to implement some alternative to that. 但我想实现一些替代方案。 Since changing the border color of the frame seems a nearly impossible task ( this solution would have been the best one), does anyone has an idea on how to get attention without stealing focus? 因为改变框架的边框颜色似乎是一项几乎不可能完成的任务(这个解决方案本来就是最好的),有没有人知道如何在不偷窃焦点的情况下获得关注?

Option A: You need to use FlashWindowEx from the windows API. 选项A:您需要使用Windows API中的FlashWindowEx。 This isn't available in .NET, so you need to use PInvoke. 这在.NET中不可用,因此您需要使用PInvoke。

Option B: Use a balloon tip from the system tray. 选项B:使用系统托盘中的气球提示。 This is built into .NET, but requires that your application use a notification icon, which you might not want. 它内置于.NET中,但要求您的应用程序使用您可能不需要的通知图标。 More details here: http://msdn.microsoft.com/en-us/library/system.windows.forms.notifyicon.showballoontip.aspx 更多细节: http//msdn.microsoft.com/en-us/library/system.windows.forms.notifyicon.showballoontip.aspx

Here is the example for how to use Option A: 以下是如何使用选项A的示例:

pInvoke.net has the best example: http://pinvoke.net/default.aspx/user32.FlashWindowEx pInvoke.net就是最好的例子: http ://pinvoke.net/default.aspx/user32.FlashWindowEx

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

User-Defined Types: 用户定义的类型:

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

Notes: 笔记:

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

Tips & Tricks: 提示与技巧:

Please add some! 请加一些!

Sample Code: 示例代码:

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

Here is the official Microsoft example: http://msdn.microsoft.com/en-us/library/ms679347(v=vs.85).aspx 以下是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;
    }

In Windows 7, a progress bar on a form is represented in its taskbar button; 在Windows 7中,表单上的进度条显示在其任务栏按钮中; you might leverage that. 你可以利用它。 There's also got to be a way to simply highlight the taskbar button, like IM programs do when you get a new message. 还有一种方法可以简单地突出显示任务栏按钮,就像IM程序在收到新消息时所做的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM