Get user attention without stealing focus

前端 未结 2 1345
北恋
北恋 2020-12-16 19:20

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 e

相关标签:
2条回答
  • 2020-12-16 19:55

    Option A: You need to use FlashWindowEx from the windows API. This isn't available in .NET, so you need to use PInvoke.

    Option B: Use a balloon tip from the system tray. This is built into .NET, but requires that your application use a notification icon, which you might not want. More details here: http://msdn.microsoft.com/en-us/library/system.windows.forms.notifyicon.showballoontip.aspx

    Here is the example for how to use Option A:

    pInvoke.net has the best example: 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

        [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 讨论(0)
  • 2020-12-16 19:58

    In Windows 7, a progress bar on a form is represented in its taskbar button; 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.

    0 讨论(0)
提交回复
热议问题