miranda/Speak/Speak/Interop/Subclassing.cs
2013-05-08 21:39:27 +00:00

72 lines
2.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace Speak.Interop
{
public class Subclassing : IDisposable
{
private const int GWL_WNDPROC = -4;
[DllImport("user32", SetLastError = true)]
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, Win32WndProc newProc);
[DllImport("user32", SetLastError = true)]
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr newProc);
[DllImport("user32")]
private static extern int CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImport("kernel32.dll")]
public static extern void SetLastError(uint dwErrCode);
private IntPtr wHandle;
private Win32WndProc wProc;
private IntPtr oldWndProc = IntPtr.Zero;
public Subclassing(IntPtr wHandle)
{
this.wHandle = wHandle;
}
public int StartSubclassing(Win32WndProc newWindowProc)
{
wProc = newWindowProc;
SetLastError(0);
if (oldWndProc != IntPtr.Zero)
SetWindowLong(wHandle, GWL_WNDPROC, wProc);
else
oldWndProc = SetWindowLong(wHandle, GWL_WNDPROC, wProc);
return Marshal.GetLastWin32Error();
}
public int CallParent(IntPtr hWnd, int Msg, int wParam, int lParam)
{
if (Msg == 0x02 || Msg == 0x10)
{
StopSubclass();
}
return CallWindowProc(oldWndProc, hWnd, Msg, wParam, lParam);
}
public void StopSubclass()
{
if (wHandle != IntPtr.Zero && oldWndProc != IntPtr.Zero)
{
SetWindowLong(wHandle, GWL_WNDPROC, oldWndProc);
wHandle = IntPtr.Zero;
wProc = null;
}
}
#region Implementation of IDisposable
public void Dispose()
{
StopSubclass();
}
#endregion
}
public delegate int Win32WndProc(IntPtr hWnd, int Msg, int wParam, int lParam);
}