summaryrefslogtreecommitdiffstats
path: root/samples/IrcChatSystem/ChatClientApp/Client
diff options
context:
space:
mode:
authorHalil İbrahim Kalkan <hi_kalkan@yahoo.com>2013-04-08 21:44:58 +0300
committerHalil İbrahim Kalkan <hi_kalkan@yahoo.com>2013-04-08 21:44:58 +0300
commit79953cb56cda204f190ffcd9995b27ebea25e62d (patch)
treede939755c2e32eaa5fa3e41e21114e1c727ed0a4 /samples/IrcChatSystem/ChatClientApp/Client
parent934c543eb6b0bd7173038e45a7dac0241d091da4 (diff)
downloadscs-79953cb56cda204f190ffcd9995b27ebea25e62d.zip
scs-79953cb56cda204f190ffcd9995b27ebea25e62d.tar.gz
scs-79953cb56cda204f190ffcd9995b27ebea25e62d.tar.bz2
Adding to github
Adding to github
Diffstat (limited to 'samples/IrcChatSystem/ChatClientApp/Client')
-rw-r--r--samples/IrcChatSystem/ChatClientApp/Client/ChatClient.cs103
-rw-r--r--samples/IrcChatSystem/ChatClientApp/Client/ChatController.cs155
-rw-r--r--samples/IrcChatSystem/ChatClientApp/Client/ClientHelper.cs93
-rw-r--r--samples/IrcChatSystem/ChatClientApp/Client/IChatController.cs41
-rw-r--r--samples/IrcChatSystem/ChatClientApp/Client/IChatRoomView.cs60
-rw-r--r--samples/IrcChatSystem/ChatClientApp/Client/ILoginFormView.cs26
-rw-r--r--samples/IrcChatSystem/ChatClientApp/Client/UserPreferences.cs140
-rw-r--r--samples/IrcChatSystem/ChatClientApp/Client/WindowsHelper.cs109
8 files changed, 727 insertions, 0 deletions
diff --git a/samples/IrcChatSystem/ChatClientApp/Client/ChatClient.cs b/samples/IrcChatSystem/ChatClientApp/Client/ChatClient.cs
new file mode 100644
index 0000000..709df89
--- /dev/null
+++ b/samples/IrcChatSystem/ChatClientApp/Client/ChatClient.cs
@@ -0,0 +1,103 @@
+using System;
+using Hik.Samples.Scs.IrcChat.Arguments;
+using Hik.Samples.Scs.IrcChat.Contracts;
+
+namespace Hik.Samples.Scs.IrcChat.Client
+{
+ /// <summary>
+ /// This class implements IChatClient to use to be invoked by Chat Server.
+ /// </summary>
+ internal class ChatClient : IChatClient
+ {
+ #region Private fields
+
+ /// <summary>
+ /// Reference to Chat Room window.
+ /// </summary>
+ private readonly IChatRoomView _chatRoom;
+
+ #endregion
+
+ #region Constructor
+
+ /// <summary>
+ /// Creates a new ChatClient.
+ /// </summary>
+ /// <param name="chatRoom">Reference to Chat Room window</param>
+ public ChatClient(IChatRoomView chatRoom)
+ {
+ _chatRoom = chatRoom;
+ }
+
+ #endregion
+
+ #region IChatClient implementation
+
+ /// <summary>
+ /// This method is used to get user list from chat server.
+ /// It is called by server, once after user logged in to server.
+ /// </summary>
+ /// <param name="users">All online user informations</param>
+ public void GetUserList(UserInfo[] users)
+ {
+ foreach (var user in users)
+ {
+ _chatRoom.AddUserToList(user);
+ }
+ }
+
+ /// <summary>
+ /// This method is called from chat server to inform that a message
+ /// is sent to chat room publicly.
+ /// </summary>
+ /// <param name="nick">Nick of sender</param>
+ /// <param name="message">Message text</param>
+ public void OnMessageToRoom(string nick, ChatMessage message)
+ {
+ _chatRoom.OnMessageReceived(nick, message);
+ }
+
+ /// <summary>
+ /// This method is called from chat server to inform that a message
+ /// is sent to the current used privately.
+ /// </summary>
+ /// <param name="nick">Nick of sender</param>
+ /// <param name="message">Message</param>
+ public void OnPrivateMessage(string nick, ChatMessage message)
+ {
+ _chatRoom.OnPrivateMessageReceived(nick, message);
+ }
+
+ /// <summary>
+ /// This method is called from chat server to inform that a new user
+ /// joined to chat room.
+ /// </summary>
+ /// <param name="userInfo">Informations of new user</param>
+ public void OnUserLogin(UserInfo userInfo)
+ {
+ _chatRoom.AddUserToList(userInfo);
+ }
+
+ /// <summary>
+ /// This method is called from chat server to inform that an existing user
+ /// has left the chat room.
+ /// </summary>
+ /// <param name="nick">Informations of new user</param>
+ public void OnUserLogout(string nick)
+ {
+ _chatRoom.RemoveUserFromList(nick);
+ }
+
+ /// <summary>
+ /// This method is called from chat server to inform that a user changed his/her status.
+ /// </summary>
+ /// <param name="nick">Nick of the user</param>
+ /// <param name="newStatus">New status of the user</param>
+ public void OnUserStatusChange(string nick, UserStatus newStatus)
+ {
+ _chatRoom.OnUserStatusChange(nick, newStatus);
+ }
+
+ #endregion
+ }
+}
diff --git a/samples/IrcChatSystem/ChatClientApp/Client/ChatController.cs b/samples/IrcChatSystem/ChatClientApp/Client/ChatController.cs
new file mode 100644
index 0000000..91a2241
--- /dev/null
+++ b/samples/IrcChatSystem/ChatClientApp/Client/ChatController.cs
@@ -0,0 +1,155 @@
+using System;
+using Hik.Communication.Scs.Communication;
+using Hik.Communication.Scs.Communication.EndPoints.Tcp;
+using Hik.Communication.ScsServices.Client;
+using Hik.Communication.ScsServices.Communication.Messages;
+using Hik.Samples.Scs.IrcChat.Arguments;
+using Hik.Samples.Scs.IrcChat.Contracts;
+
+namespace Hik.Samples.Scs.IrcChat.Client
+{
+ /// <summary>
+ /// This class is a mediator with view and SCS system.
+ /// </summary>
+ internal class ChatController : IChatController
+ {
+ #region Private fields
+
+ /// <summary>
+ /// Reference to login form.
+ /// </summary>
+ public ILoginFormView LoginForm { get; set; }
+
+ /// <summary>
+ /// Reference to chat room window.
+ /// </summary>
+ public IChatRoomView ChatRoom { get; set; }
+
+ /// <summary>
+ /// The object which handles remote method calls from server.
+ /// It implements IChatClient contract.
+ /// </summary>
+ private ChatClient _chatClient;
+
+ /// <summary>
+ /// This object is used to connect to SCS Chat Service as a client.
+ /// </summary>
+ private IScsServiceClient<IChatService> _scsClient;
+
+ #endregion
+
+ #region IChatController implementation
+
+ /// <summary>
+ /// Connects to the server.
+ /// It automatically Logins to server if connection success.
+ /// </summary>
+ public void Connect()
+ {
+ //Disconnect if currently connected
+ Disconnect();
+
+ //Create a ChatClient to handle remote method invocations by server
+ _chatClient = new ChatClient(ChatRoom);
+
+ //Create a SCS client to connect to SCS server
+ _scsClient = ScsServiceClientBuilder.CreateClient<IChatService>(new ScsTcpEndPoint(LoginForm.ServerIpAddress, LoginForm.ServerTcpPort), _chatClient);
+
+ //Register events of SCS client
+ _scsClient.Connected += ScsClient_Connected;
+ _scsClient.Disconnected += ScsClient_Disconnected;
+
+ //Connect to the server
+ _scsClient.Connect();
+ }
+
+ /// <summary>
+ /// Disconnects from server if it is connected.
+ /// </summary>
+ public void Disconnect()
+ {
+ if (_scsClient != null && _scsClient.CommunicationState == CommunicationStates.Connected)
+ {
+ try
+ {
+ _scsClient.Disconnect();
+ }
+ catch
+ {
+
+ }
+
+ _scsClient = null;
+ }
+ }
+
+ /// <summary>
+ /// Sends a public message to room.
+ /// It will be seen by all users in room.
+ /// </summary>
+ /// <param name="message">Message to be sent</param>
+ public void SendMessageToRoom(ChatMessage message)
+ {
+ _scsClient.ServiceProxy.SendMessageToRoom(message);
+ }
+
+ /// <summary>
+ /// Change status of user.
+ /// </summary>
+ /// <param name="newStatus">New status</param>
+ public void ChangeStatus(UserStatus newStatus)
+ {
+ _scsClient.ServiceProxy.ChangeStatus(newStatus);
+ }
+
+ /// <summary>
+ /// Sends a private message to a user.
+ /// </summary>
+ /// <param name="nick">Destination nick</param>
+ /// <param name="message">Message</param>
+ public void SendPrivateMessage(string nick, ChatMessage message)
+ {
+ _scsClient.ServiceProxy.SendPrivateMessage(nick, message);
+ }
+
+ #endregion
+
+ #region Private methods
+
+ /// <summary>
+ /// This method handles Connected event of _scsClient.
+ /// </summary>
+ /// <param name="sender">Source of event</param>
+ /// <param name="e">Event arguments</param>
+ private void ScsClient_Connected(object sender, EventArgs e)
+ {
+ try
+ {
+ _scsClient.ServiceProxy.Login(LoginForm.CurrentUserInfo);
+ ChatRoom.OnLoggedIn();
+ }
+ catch (ScsRemoteException ex)
+ {
+ Disconnect();
+ ChatRoom.OnLoginError(ex.InnerException != null ? ex.InnerException.Message : ex.Message);
+ }
+ catch
+ {
+ Disconnect();
+ ChatRoom.OnLoginError("Can not login to server. Please try again later.");
+ }
+ }
+
+ /// <summary>
+ /// This method handles Disconnected event of _scsClient.
+ /// </summary>
+ /// <param name="sender">Source of event</param>
+ /// <param name="e">Event arguments</param>
+ private void ScsClient_Disconnected(object sender, EventArgs e)
+ {
+ ChatRoom.OnLoggedOut();
+ }
+
+ #endregion
+ }
+}
diff --git a/samples/IrcChatSystem/ChatClientApp/Client/ClientHelper.cs b/samples/IrcChatSystem/ChatClientApp/Client/ClientHelper.cs
new file mode 100644
index 0000000..9b417db
--- /dev/null
+++ b/samples/IrcChatSystem/ChatClientApp/Client/ClientHelper.cs
@@ -0,0 +1,93 @@
+using System.IO;
+using System.Media;
+using System.Reflection;
+using System.Runtime.Serialization.Formatters.Binary;
+
+namespace Hik.Samples.Scs.IrcChat.Client
+{
+ /// <summary>
+ /// This class includes come helper methods that are using in chat client.
+ /// </summary>
+ public static class ClientHelper
+ {
+ /// <summary>
+ /// Gets the directory of executing assembly.
+ /// </summary>
+ /// <returns>Current directory</returns>
+ public static string GetCurrentDirectory()
+ {
+ return (new FileInfo(Assembly.GetExecutingAssembly().Location)).Directory.FullName;
+ }
+
+ /// <summary>
+ /// Gets the size of a file as bytes
+ /// </summary>
+ /// <param name="filePath">Path of file</param>
+ /// <returns>Size of file</returns>
+ public static long GetFileSize(string filePath)
+ {
+ using (var file = File.Open(filePath, FileMode.Open))
+ {
+ var lengthOfFile = file.Length;
+ file.Close();
+ return lengthOfFile;
+ }
+ }
+
+ /// <summary>
+ /// Serializes an object and writes it to a file.
+ /// Uses .NET binary serialization.
+ /// </summary>
+ /// <param name="obj">object to be serialized</param>
+ /// <param name="filePath">Path of file to serialize</param>
+ /// <returns>bytes of object</returns>
+ public static void SerializeObjectToFile(object obj, string filePath)
+ {
+ using (var file = new FileStream(filePath, FileMode.Create))
+ {
+ new BinaryFormatter().Serialize(file, obj);
+ file.Flush();
+ }
+ }
+
+ /// <summary>
+ /// Deserializes an object from a file.
+ /// Uses .NET binary deserialization.
+ /// </summary>
+ /// <param name="filePath">Path of file to deserialize</param>
+ /// <returns>deserialized object</returns>
+ public static object DeserializeObjectFromFile(string filePath)
+ {
+ using (var file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
+ {
+ return new BinaryFormatter().Deserialize(file);
+ }
+ }
+
+ /// <summary>
+ /// Plays incoming message sound (if sound is on).
+ /// </summary>
+ public static void PlayIncomingMessageSound()
+ {
+ if (!UserPreferences.Current.IsSoundOn)
+ {
+ return;
+ }
+
+ try
+ {
+ var filePath = Path.Combine(GetCurrentDirectory(), @"Sounds\incoming_message.wav");
+ if (!File.Exists(filePath))
+ {
+ return;
+ }
+
+ new SoundPlayer(filePath).Play();
+ }
+ catch
+ {
+
+ }
+ }
+ }
+}
diff --git a/samples/IrcChatSystem/ChatClientApp/Client/IChatController.cs b/samples/IrcChatSystem/ChatClientApp/Client/IChatController.cs
new file mode 100644
index 0000000..4fd90cf
--- /dev/null
+++ b/samples/IrcChatSystem/ChatClientApp/Client/IChatController.cs
@@ -0,0 +1,41 @@
+using Hik.Samples.Scs.IrcChat.Arguments;
+
+namespace Hik.Samples.Scs.IrcChat.Client
+{
+ /// <summary>
+ /// This interface defines method of chat controller that can be used by views.
+ /// </summary>
+ public interface IChatController
+ {
+ /// <summary>
+ /// Connects to the server.
+ /// It automatically Logins to server if connection success.
+ /// </summary>
+ void Connect();
+
+ /// <summary>
+ /// Disconnects from server if it is connected.
+ /// </summary>
+ void Disconnect();
+
+ /// <summary>
+ /// Sends a public message to room.
+ /// It will be seen all users in room.
+ /// </summary>
+ /// <param name="message">Message to be sent</param>
+ void SendMessageToRoom(ChatMessage message);
+
+ /// <summary>
+ /// Change status of user.
+ /// </summary>
+ /// <param name="newStatus">New status</param>
+ void ChangeStatus(UserStatus newStatus);
+
+ /// <summary>
+ /// Sends a private message to a user.
+ /// </summary>
+ /// <param name="nick">Destination nick</param>
+ /// <param name="message">Message</param>
+ void SendPrivateMessage(string nick, ChatMessage message);
+ }
+} \ No newline at end of file
diff --git a/samples/IrcChatSystem/ChatClientApp/Client/IChatRoomView.cs b/samples/IrcChatSystem/ChatClientApp/Client/IChatRoomView.cs
new file mode 100644
index 0000000..b5f11a8
--- /dev/null
+++ b/samples/IrcChatSystem/ChatClientApp/Client/IChatRoomView.cs
@@ -0,0 +1,60 @@
+using Hik.Samples.Scs.IrcChat.Arguments;
+
+namespace Hik.Samples.Scs.IrcChat.Client
+{
+ /// <summary>
+ /// This interface is used to interact with main chat room window by ChatController.
+ /// It is implemented by main window.
+ /// </summary>
+ public interface IChatRoomView
+ {
+ /// <summary>
+ /// This method is called when a message is sent to chat room.
+ /// </summary>
+ /// <param name="nick">Nick of sender</param>
+ /// <param name="message">Message</param>
+ void OnMessageReceived(string nick, ChatMessage message);
+
+ /// <summary>
+ /// This method is called when a private message is sent to the current user.
+ /// </summary>
+ /// <param name="nick">Nick of sender</param>
+ /// <param name="message">The message</param>
+ void OnPrivateMessageReceived(string nick, ChatMessage message);
+
+ /// <summary>
+ /// This method is called when user successfully logged in to chat server.
+ /// </summary>
+ void OnLoggedIn();
+
+ /// <summary>
+ /// This method is used to inform view if login is failed.
+ /// </summary>
+ /// <param name="errorMessage">Detail of error</param>
+ void OnLoginError(string errorMessage);
+
+ /// <summary>
+ /// This method is called when connection to server is closed.
+ /// </summary>
+ void OnLoggedOut();
+
+ /// <summary>
+ /// This methos is used to add a new user to user list in room view.
+ /// </summary>
+ /// <param name="userInfo">Informations of new user</param>
+ void AddUserToList(UserInfo userInfo);
+
+ /// <summary>
+ /// This metrhod is used to remove a user (that is disconnected from server) from user list in room view.
+ /// </summary>
+ /// <param name="nick">Nick of user to remove</param>
+ void RemoveUserFromList(string nick);
+
+ /// <summary>
+ /// This method is called from chat server to inform that a user changed his/her status.
+ /// </summary>
+ /// <param name="nick">Nick of the user</param>
+ /// <param name="newStatus">New status of the user</param>
+ void OnUserStatusChange(string nick, UserStatus newStatus);
+ }
+} \ No newline at end of file
diff --git a/samples/IrcChatSystem/ChatClientApp/Client/ILoginFormView.cs b/samples/IrcChatSystem/ChatClientApp/Client/ILoginFormView.cs
new file mode 100644
index 0000000..1f746d9
--- /dev/null
+++ b/samples/IrcChatSystem/ChatClientApp/Client/ILoginFormView.cs
@@ -0,0 +1,26 @@
+using Hik.Samples.Scs.IrcChat.Arguments;
+
+namespace Hik.Samples.Scs.IrcChat.Client
+{
+ /// <summary>
+ /// This interface is used to interact with login form by ChatController.
+ /// ChatController gets user informations over this interface.
+ /// </summary>
+ public interface ILoginFormView
+ {
+ /// <summary>
+ /// IP address of server to be connected.
+ /// </summary>
+ string ServerIpAddress { get; }
+
+ /// <summary>
+ /// TCP Port number of server to be connected.
+ /// </summary>
+ int ServerTcpPort { get; }
+
+ /// <summary>
+ /// User Login informations to be used while logging on to the server.
+ /// </summary>
+ UserInfo CurrentUserInfo { get; }
+ }
+} \ No newline at end of file
diff --git a/samples/IrcChatSystem/ChatClientApp/Client/UserPreferences.cs b/samples/IrcChatSystem/ChatClientApp/Client/UserPreferences.cs
new file mode 100644
index 0000000..64143c6
--- /dev/null
+++ b/samples/IrcChatSystem/ChatClientApp/Client/UserPreferences.cs
@@ -0,0 +1,140 @@
+using System;
+using System.IO;
+using Hik.Samples.Scs.IrcChat.Arguments;
+
+namespace Hik.Samples.Scs.IrcChat.Client
+{
+ /// <summary>
+ /// This class is used to save and load preferences of the user.
+ /// </summary>
+ [Serializable]
+ internal class UserPreferences
+ {
+ /// <summary>
+ /// Gets the singleton instance of this class.
+ /// </summary>
+ public static UserPreferences Current
+ {
+ get
+ {
+ if (_current == null)
+ {
+ lock (SyncObj)
+ {
+ if (_current == null)
+ {
+ _current = LoadPreferences();
+ }
+ }
+ }
+
+ return _current;
+ }
+ }
+
+ /// <summary>
+ /// Nick of the user.
+ /// </summary>
+ public string Nick { get; set; }
+
+ /// <summary>
+ /// Path of user's avatar file.
+ /// </summary>
+ public string AvatarFile { get; set; }
+
+ /// <summary>
+ /// Sound preference of user.
+ /// True if sound is on.
+ /// </summary>
+ public bool IsSoundOn { get; set; }
+
+ /// <summary>
+ /// Ip address of the chat server.
+ /// </summary>
+ public string ServerIpAddress { get; set; }
+
+ /// <summary>
+ /// TCP port of the chat server.
+ /// </summary>
+ public int ServerTcpPort { get; set; }
+
+ /// <summary>
+ /// Text style of user.
+ /// </summary>
+ public MessageTextStyle TextStyle { get; private set; }
+
+ /// <summary>
+ /// The singleton instance of this class.
+ /// </summary>
+ private static UserPreferences _current;
+
+ /// <summary>
+ /// Used to synronize threads while creating singleton object.
+ /// </summary>
+ private static readonly object SyncObj = new object();
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ private UserPreferences()
+ {
+ IsSoundOn = true;
+ TextStyle = new MessageTextStyle();
+ }
+
+ /// <summary>
+ /// Saves preferences to the disc.
+ /// </summary>
+ public void Save()
+ {
+ try
+ {
+ ClientHelper.SerializeObjectToFile(
+ this,
+ Path.Combine(ClientHelper.GetCurrentDirectory(), "Preferences.bin")
+ );
+ }
+ catch
+ {
+
+ }
+ }
+
+ /// <summary>
+ /// Load last preferences from the disc.
+ /// </summary>
+ /// <returns>Last user preferences (or default values if not found)</returns>
+ private static UserPreferences LoadPreferences()
+ {
+ try
+ {
+ var preferenceFile = Path.Combine(ClientHelper.GetCurrentDirectory(), "Preferences.bin");
+ if (File.Exists(preferenceFile))
+ {
+ return (UserPreferences)ClientHelper.DeserializeObjectFromFile(preferenceFile);
+ }
+ }
+ catch
+ {
+
+ }
+
+ return CreateDefault();
+ }
+
+ /// <summary>
+ /// Creates a default-valued instance of this class.
+ /// </summary>
+ /// <returns>UserPreferences object with default values</returns>
+ private static UserPreferences CreateDefault()
+ {
+ return new UserPreferences
+ {
+ Nick = "User Nick",
+ AvatarFile = Path.Combine(ClientHelper.GetCurrentDirectory(), @"Images\user_male.png"),
+ ServerIpAddress = "127.0.0.1",
+ ServerTcpPort = 10048
+ };
+ }
+ }
+}
diff --git a/samples/IrcChatSystem/ChatClientApp/Client/WindowsHelper.cs b/samples/IrcChatSystem/ChatClientApp/Client/WindowsHelper.cs
new file mode 100644
index 0000000..517bc1d
--- /dev/null
+++ b/samples/IrcChatSystem/ChatClientApp/Client/WindowsHelper.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Hik.Samples.Scs.IrcChat.Client
+{
+ /// <summary>
+ /// This class is used to flash window caption / taskbar button when a message received
+ /// and window is not active.
+ /// </summary>
+ public static class WindowsHelper
+ {
+ [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;
+ }
+ }
+}