.Net精简框加下子类化控件
在.net框加下我们可以直接重写(override)WndProc函数,以达到处理Windows消息的目的。可是在精简框架下,没有了WndProc方法。所以只能使用API来实现这个目的。代码如下:
Code
using System;
using System.Runtime.InteropServices;
/**//// <summary>
/// 提供子类化窗体功能
/// </summary>
public class SubClassWin:IDisposable
{
private readonly int handle;
private const int GWL_WNDPROC = (-4);
private readonly WndProcDelegate newWndProc;
private readonly int oldWndProc;
[DllImport("Coredll.dll", EntryPoint = "SetWindowLong")]
private static extern int SetWindowLong(int hwnd, int nIndex, WndProcDelegate newProc);
[DllImport("Coredll.dll", EntryPoint = "SetWindowLong")]
private static extern int SetWindowLong(int hwnd, int nIndex,int newProc);
[DllImport("Coredll.dll", EntryPoint = "CallWindowProc")]
private static extern int CallWindowProc(int lpPrevWndFunc, int hWnd, int Msg, int wParam, int lParam);
public delegate int WndProcDelegate(int hwnd, int uMsg, int wParam, int lParam);
/**//// <summary>
/// 构造函数
/// </summary>
/// <param name="handle">要子类化的窗体句柄</param>
public SubClassWin(int handle)
{
this.handle = handle;
newWndProc = WndProc;
// 注意 newProc 必须声明成字段,以防止被GC回收。
oldWndProc = SetWindowLong(handle, GWL_WNDPROC, newWndProc);
}
/**//// <summary>
/// 重写此方法以处理Window消息,重写时如果不处理消息,则必须调用默认实现
/// </summary>
protected virtual int WndProc(int hwnd, int uMsg, int wParam , int lParam)
{
return CallWindowProc(oldWndProc, hwnd, uMsg, wParam, lParam);
}
Implementation of IDisposable#region Implementation of IDisposable
public void Dispose()
{
if(oldWndProc != 0)
{
SetWindowLong(handle, GWL_WNDPROC, oldWndProc);
}
}
#endregion
}
using System;
using System.Runtime.InteropServices;
/**//// <summary>
/// 提供子类化窗体功能
/// </summary>
public class SubClassWin:IDisposable
{
private readonly int handle;
private const int GWL_WNDPROC = (-4);
private readonly WndProcDelegate newWndProc;
private readonly int oldWndProc;
[DllImport("Coredll.dll", EntryPoint = "SetWindowLong")]
private static extern int SetWindowLong(int hwnd, int nIndex, WndProcDelegate newProc);
[DllImport("Coredll.dll", EntryPoint = "SetWindowLong")]
private static extern int SetWindowLong(int hwnd, int nIndex,int newProc);
[DllImport("Coredll.dll", EntryPoint = "CallWindowProc")]
private static extern int CallWindowProc(int lpPrevWndFunc, int hWnd, int Msg, int wParam, int lParam);
public delegate int WndProcDelegate(int hwnd, int uMsg, int wParam, int lParam);
/**//// <summary>
/// 构造函数
/// </summary>
/// <param name="handle">要子类化的窗体句柄</param>
public SubClassWin(int handle)
{
this.handle = handle;
newWndProc = WndProc;
// 注意 newProc 必须声明成字段,以防止被GC回收。
oldWndProc = SetWindowLong(handle, GWL_WNDPROC, newWndProc);
}
/**//// <summary>
/// 重写此方法以处理Window消息,重写时如果不处理消息,则必须调用默认实现
/// </summary>
protected virtual int WndProc(int hwnd, int uMsg, int wParam , int lParam)
{
return CallWindowProc(oldWndProc, hwnd, uMsg, wParam, lParam);
}
Implementation of IDisposable#region Implementation of IDisposable
public void Dispose()
{
if(oldWndProc != 0)
{
SetWindowLong(handle, GWL_WNDPROC, oldWndProc);
}
}
#endregion
}
使用方法如下:
Code
public class SampleWin:SubClassWin
{
public SampleWin(int handle) : base(handle)
{
}
protected override int WndProc(int hwnd, int uMsg, int wParam, int lParam)
{
/*
* 处理你所关注的消息
if (uMsg == 0)
{
return 1;
}
*/
// 必须调用基类的实现,将消息交给窗体的默认实现来处理
return base.WndProc(hwnd, uMsg, wParam, lParam);
}
}
public class SampleWin:SubClassWin
{
public SampleWin(int handle) : base(handle)
{
}
protected override int WndProc(int hwnd, int uMsg, int wParam, int lParam)
{
/*
* 处理你所关注的消息
if (uMsg == 0)
{
return 1;
}
*/
// 必须调用基类的实现,将消息交给窗体的默认实现来处理
return base.WndProc(hwnd, uMsg, wParam, lParam);
}
}