在有些时候,我们需要在自己的控件中加入象TextBox一样的插入符
这个功能我没有使用上一版所用的Caret API
而直接用了BitBlt函数完成
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Klezard.Windows.Forms
{
/// <summary>
/// 插入符
/// </summary>
public sealed class Caret : System.ComponentModel.Component
{
#region Native
private Timer tim = new Timer();
private const string User32 = "User32.dll";
private const string Gdi32 = "Gdi32.dll";
private static int DSTINVERT = 0x550009;
[DllImport(Gdi32)]
private static extern int BitBlt(
IntPtr hDestDC, int x, int y, int nWidth, int nHeight,
IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
[DllImport(User32)]
private static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport(User32)]
private static extern IntPtr GetDC(IntPtr hWnd);
[DllImport(User32)]
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hdc);
#endregion
private IntPtr dc;
private Control _HostControl;
private Caret() { }
Point _Position = Point.Empty;
Size _Size;
/// <summary>
/// 创建一个插入符
/// </summary>
/// <param name="ctl">插入符宿主</param>
/// <remarks>创建完成后插入符默认为隐藏的</remarks>
public Caret(Control ctl):this(ctl,8,16) { }
/// <summary>
/// 使用特定的大小创建一个插入符
/// </summary>
/// <param name="ctl">宿主</param>
/// <param name="width">宽度</param>
/// <param name="height">高度</param>
/// <remarks>创建完成后插入符默认为隐藏的</remarks>
public Caret(Control ctl, int width, int height)
{
if (ctl == null)
throw new NullReferenceException();
_HostControl = ctl;
dc = GetDC(ctl.Handle);
if (dc == IntPtr.Zero)
throw new NullReferenceException();
_Size = new Size(width, height);
tim.Interval = 530;
tim.Tick += new EventHandler(tim_Tick);
}
/// <summary>
/// 释放该插入符对象
/// </summary>
public void Destroy()
{
if (_HostControl != null)
ReleaseDC(_HostControl.Handle, dc);
this.Dispose();
}
/// <summary>
/// 显示插入符
/// </summary>
public void Show() { tim.Start(); }
/// <summary>
/// 隐藏插入符,隐藏效果会叠加,即调用了几次Hide,要再次显示时就要调用几次Show
/// </summary>
public void Hide() { tim.Stop(); }
//// <summary>
/// 宿主窗体
/// </summary>
public Control HostControl { get { return _HostControl; } }
//// <summary>
/// 获得或设置所有插入符闪烁时间间隔
/// </summary>
public int BlinkTime
{
get { return tim.Interval; }
set { tim.Interval = value; }
}
//// <summary>
/// 获得或设置插入符的相对位置
/// </summary>
public Point Position
{
get { return _Position; }
set
{
_Position = value;
HostControl.Refresh();
}
}
/// <summary>
/// 获得或设置插入符的大小
/// </summary>
public Size Size
{
get { return _Size; }
set
{
_Size = value;
HostControl.Refresh();
}
}
void tim_Tick(object sender, EventArgs e)
{
BitBlt(dc, Position.X, Position.Y, Size.Width, Size.Height, IntPtr.Zero, 0, 0, DSTINVERT);
}
}
}
转载请注明出处,如果您要使用该代码,请告之作者