314 lines
9.8 KiB
C#

using System;
using System.Windows.Forms;
using System.Collections;
using System.Threading;
namespace DevComponents.DotNetBar
{
/// <summary>
/// Summary description for MessageHandler.
/// </summary>
internal class MessageHandler
{
private static ArrayList m_Clients=new ArrayList();
//private static bool m_FilterInstalled=false;
//private static MessageFilterWrapper m_MessageFilter=null;
private static Hashtable m_FilterOnThread=new Hashtable();
private static ReaderWriterLock rwClientsListLock;
// Methods
static MessageHandler()
{
MessageHandler.rwClientsListLock = new ReaderWriterLock();
}
public static void RegisterMessageClient(IMessageHandlerClient client)
{
if(m_Clients.Contains(client))
return;
if(!m_FilterOnThread.ContainsKey(System.Threading.Thread.CurrentThread.GetHashCode()))
InstallMessageFilter();
LockCookie cookie1 = new LockCookie();
bool readerLockHeld = MessageHandler.rwClientsListLock.IsReaderLockHeld;
if (readerLockHeld)
{
cookie1 = MessageHandler.rwClientsListLock.UpgradeToWriterLock(-1);
}
else
{
MessageHandler.rwClientsListLock.AcquireWriterLock(-1);
}
try
{
m_Clients.Add(client);
}
finally
{
if (readerLockHeld)
{
MessageHandler.rwClientsListLock.DowngradeFromWriterLock(ref cookie1);
}
else
{
MessageHandler.rwClientsListLock.ReleaseWriterLock();
}
}
}
public static void UnregisterMessageClient(IMessageHandlerClient client)
{
if (m_Clients.Contains(client))
{
LockCookie cookie1 = new LockCookie();
bool readerLockHeld = MessageHandler.rwClientsListLock.IsReaderLockHeld;
if (readerLockHeld)
{
cookie1 = MessageHandler.rwClientsListLock.UpgradeToWriterLock(-1);
}
else
{
MessageHandler.rwClientsListLock.AcquireWriterLock(-1);
}
bool unregister = false;
try
{
m_Clients.Remove(client);
unregister = m_Clients.Count == 0;
}
finally
{
if (readerLockHeld)
{
MessageHandler.rwClientsListLock.DowngradeFromWriterLock(ref cookie1);
}
else
{
MessageHandler.rwClientsListLock.ReleaseWriterLock();
}
}
if (BarUtilities.AutoRemoveMessageFilter && unregister && m_FilterOnThread.ContainsKey(System.Threading.Thread.CurrentThread.GetHashCode()))
UninstallMessageFilter();
}
}
private static void InstallMessageFilter()
{
if(m_FilterOnThread.ContainsKey(System.Threading.Thread.CurrentThread.GetHashCode()))
return;
MessageFilterWrapper messageFilter=new MessageFilterWrapper();
Application.AddMessageFilter(messageFilter);
m_FilterOnThread.Add(System.Threading.Thread.CurrentThread.GetHashCode(),messageFilter);
}
private static void UninstallMessageFilter()
{
if(!m_FilterOnThread.ContainsKey(System.Threading.Thread.CurrentThread.GetHashCode()))
return;
MessageFilterWrapper messageFilter=m_FilterOnThread[System.Threading.Thread.CurrentThread.GetHashCode()] as MessageFilterWrapper;
Application.RemoveMessageFilter(messageFilter);
m_FilterOnThread.Remove(System.Threading.Thread.CurrentThread.GetHashCode());
}
private static IMessageHandlerClient GetModalClient()
{
MessageHandler.rwClientsListLock.AcquireReaderLock(-1);
try
{
foreach (IMessageHandlerClient client in m_Clients)
{
if (client.IsModal)
{
return client;
}
}
}
finally
{
MessageHandler.rwClientsListLock.ReleaseReaderLock();
}
return null;
}
private static IMessageHandlerClient[] GetMessageClients()
{
IMessageHandlerClient[] messageClients;
MessageHandler.rwClientsListLock.AcquireReaderLock(-1);
try
{
messageClients = (IMessageHandlerClient[])m_Clients.ToArray(typeof(IMessageHandlerClient));
}
finally
{
MessageHandler.rwClientsListLock.ReleaseReaderLock();
}
return messageClients;
}
public static bool OnSysKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
IMessageHandlerClient modalClient=MessageHandler.GetModalClient();
if(modalClient!=null)
{
if (!IsInvokeRequired(modalClient) && modalClient.OnSysKeyDown(hWnd, wParam, lParam))
return true;
return false;
}
IMessageHandlerClient[] messageClients = GetMessageClients();
foreach(IMessageHandlerClient client in messageClients)
{
if (!IsInvokeRequired(client) && client.OnSysKeyDown(hWnd, wParam, lParam))
return true;
}
return false;
}
public static bool OnSysKeyUp(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
IMessageHandlerClient modalClient=MessageHandler.GetModalClient();
if(modalClient!=null)
{
if (!IsInvokeRequired(modalClient) && modalClient.OnSysKeyUp(hWnd, wParam, lParam))
return true;
return false;
}
IMessageHandlerClient[] messageClients = GetMessageClients();
foreach(IMessageHandlerClient client in messageClients)
{
if (!IsInvokeRequired(client) && client.OnSysKeyUp(hWnd, wParam, lParam))
return true;
}
return false;
}
public static bool OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
IMessageHandlerClient[] messageClients = GetMessageClients();
foreach(IMessageHandlerClient client in messageClients)
{
if (!IsInvokeRequired(client) && client.OnKeyDown(hWnd, wParam, lParam))
return true;
}
return false;
}
public static bool OnMouseDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
IMessageHandlerClient[] messageClients = GetMessageClients();
foreach(IMessageHandlerClient client in messageClients)
{
if(!IsInvokeRequired(client) && client.OnMouseDown(hWnd,wParam,lParam))
return true;
}
return false;
}
private static bool IsInvokeRequired(IMessageHandlerClient client)
{
DotNetBarManager manager = client as DotNetBarManager;
if (manager != null && manager.ParentForm != null && manager.ParentForm.InvokeRequired)
return true;
else if (client is Control && ((Control)client).InvokeRequired)
return true;
return false;
}
public static bool OnMouseMove(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
IMessageHandlerClient[] messageClients = GetMessageClients();
foreach(IMessageHandlerClient client in messageClients)
{
if(!IsInvokeRequired(client) && client.OnMouseMove(hWnd, wParam, lParam))
return true;
}
return false;
}
public static bool OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam)
{
IMessageHandlerClient modalClient = MessageHandler.GetModalClient();
if (modalClient != null)
{
if (!IsInvokeRequired(modalClient) && modalClient.OnMouseWheel(hWnd, wParam, lParam))
return true;
return false;
}
IMessageHandlerClient[] messageClients = GetMessageClients();
foreach (IMessageHandlerClient client in messageClients)
{
if (!IsInvokeRequired(client) && client.OnMouseWheel(hWnd, wParam, lParam))
return true;
}
return false;
}
}
internal class MessageFilterWrapper:IMessageFilter
{
public bool PreFilterMessage(ref System.Windows.Forms.Message m)
{
switch(m.Msg)
{
case NativeFunctions.WM_SYSKEYDOWN:
{
return MessageHandler.OnSysKeyDown(m.HWnd,m.WParam,m.LParam);
}
case NativeFunctions.WM_SYSKEYUP:
{
return MessageHandler.OnSysKeyUp(m.HWnd,m.WParam,m.LParam);
}
case (int)WinApi.WindowsMessages.WM_KEYDOWN:
{
return MessageHandler.OnKeyDown(m.HWnd,m.WParam,m.LParam);
}
case NativeFunctions.WM_LBUTTONDOWN:
case NativeFunctions.WM_NCLBUTTONDOWN:
case NativeFunctions.WM_RBUTTONDOWN:
case NativeFunctions.WM_MBUTTONDOWN:
case NativeFunctions.WM_NCMBUTTONDOWN:
case NativeFunctions.WM_NCRBUTTONDOWN:
{
return MessageHandler.OnMouseDown(m.HWnd,m.WParam,m.LParam);
}
case NativeFunctions.WM_MOUSEMOVE:
{
return MessageHandler.OnMouseMove(m.HWnd,m.WParam,m.LParam);
}
case NativeFunctions.WM_MOUSEWHEEL:
{
return MessageHandler.OnMouseWheel(m.HWnd, m.WParam, m.LParam);
}
}
return false;
}
public void PostFilterMessage(ref System.Windows.Forms.Message m)
{
}
}
internal interface IMessageHandlerClient
{
bool OnSysKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam);
bool OnSysKeyUp(IntPtr hWnd, IntPtr wParam, IntPtr lParam);
bool OnKeyDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam);
bool OnMouseDown(IntPtr hWnd, IntPtr wParam, IntPtr lParam);
bool OnMouseMove(IntPtr hWnd, IntPtr wParam, IntPtr lParam);
bool OnMouseWheel(IntPtr hWnd, IntPtr wParam, IntPtr lParam);
bool IsModal{get;}
}
}