채팅 프로그램을 개발하면서 여러가지 상황을 만나보게 된다.
채팅창에 글을 적고 있는데 다른 최소화된 대화창에 누군가가 쓴 글이 수신될때 이를 알려줘야하는데 그동안 간단하게 Activate을 사용했었다.
그렇게 되면, 최소화된 창이 Focus되면서 Taskbar에 깜박거리게 된다. 여기까지는 좋았다.
그런데 기존에 열심히 작성하던 채팅 박스가 Focus를 잃게 되면서 글을 작성할 수 없는 상태가 되는 것이다.
그래서 구글링해서 좋은 정보를 찾았다.
폼의 핸들을 찾아서 강제로 깜박거리게 하는 것이다.
관련 소스는 아래와 같다.
public class CFlashWindow
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FlashWindowEx(ref FLASHWINFO pwfi);
[StructLayout(LayoutKind.Sequential)]
private struct FLASHWINFO
{
///
/// The size of the structure in bytes.
///
public uint cbSize;
///
/// A Handle to the Window to be Flashed. The window can be either opened or minimized.
///
public IntPtr hwnd;
///
/// The Flash Status.
///
public uint dwFlags;
///
/// The number of times to Flash the window.
///
public uint uCount;
///
/// The rate at which the Window is to be flashed, in milliseconds. If Zero, the function uses the default cursor blink rate.
///
public uint dwTimeout;
}
///
/// Stop flashing. The system restores the window to its original stae.
///
public const uint FLASHW_STOP = 0;
///
/// Flash the window caption.
///
public const uint FLASHW_CAPTION = 1;
///
/// Flash the taskbar button.
///
public const uint FLASHW_TRAY = 2;
///
/// Flash both the window caption and taskbar button.
/// This is equivalent to setting the FLASHW_CAPTION | FLASHW_TRAY flags.
///
public const uint FLASHW_ALL = 3;
///
/// Flash continuously, until the FLASHW_STOP flag is set.
///
public const uint FLASHW_TIMER = 4;
///
/// Flash continuously until the window comes to the foreground.
///
public const uint FLASHW_TIMERNOFG = 12;
///
/// Flash the spacified Window (Form) until it recieves focus.
///
///The Form (Window) to Flash. ///
public static bool Flash(System.Windows.Forms.Form form)
{
// Make sure we're running under Windows 2000 or later
if (Win2000OrLater)
{
FLASHWINFO fi = Create_FLASHWINFO(form.Handle, FLASHW_ALL | FLASHW_TIMERNOFG, uint.MaxValue, 0);
return FlashWindowEx(ref fi);
}
return false;
}
private static FLASHWINFO Create_FLASHWINFO(IntPtr handle, uint flags, uint count, uint timeout)
{
FLASHWINFO fi = new FLASHWINFO();
fi.cbSize = Convert.ToUInt32(Marshal.SizeOf(fi));
fi.hwnd = handle;
fi.dwFlags = flags;
fi.uCount = count;
fi.dwTimeout = timeout;
return fi;
}
///
/// Flash the specified Window (form) for the specified number of times
///
///The Form (Window) to Flash. ///The number of times to Flash. ///
public static bool Flash(System.Windows.Forms.Form form, uint count)
{
if (Win2000OrLater)
{
FLASHWINFO fi = Create_FLASHWINFO(form.Handle, FLASHW_ALL, count, 0);
return FlashWindowEx(ref fi);
}
return false;
}
///
/// Start Flashing the specified Window (form)
///
///The Form (Window) to Flash. ///
public static bool Start(System.Windows.Forms.Form form)
{
if (Win2000OrLater)
{
FLASHWINFO fi = Create_FLASHWINFO(form.Handle, FLASHW_ALL, uint.MaxValue, 0);
return FlashWindowEx(ref fi);
}
return false;
}
///
/// Stop Flashing the specified Window (form)
///
//////
public static bool Stop(System.Windows.Forms.Form form)
{
if (Win2000OrLater)
{
FLASHWINFO fi = Create_FLASHWINFO(form.Handle, FLASHW_STOP, uint.MaxValue, 0);
return FlashWindowEx(ref fi);
}
return false;
}
///
/// A boolean value indicating whether the application is running on Windows 2000 or later.
///
private static bool Win2000OrLater
{
get { return System.Environment.OSVersion.Version.Major >= 5; }
}
}
위와 같이 하고 사용은 아래와 같이한다.
// 폼이 포커스를 갖게되기전까지 계속 깜박거림 FlashWindow.Flash(this); // 5초간 계속 깜박거림 FlashWindow.Flash(this, 5); // 강제로 깜박거리게 하는 시작 FlashWindow.Start(this); // 강제깜박인 중지 FlashWindow.Stop(this);




