[Klezard]插入符组件(Caret)第二版

在有些时候,我们需要在自己的控件中加入象TextBox一样的插入符
这个功能我没有使用上一版所用的Caret API
而直接用了BitBlt函数完成

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace Klezard.Windows.Forms
{

///

1<summary>   
2/// 插入符   
3/// </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;

///

1<summary>   
2/// 创建一个插入符   
3/// </summary>

///

1<param name="ctl"/>

插入符宿主
///

1<remarks>创建完成后插入符默认为隐藏的</remarks>

public Caret(Control ctl):this(ctl,8,16) { }

///

1<summary>   
2/// 使用特定的大小创建一个插入符   
3/// </summary>

///

1<param name="ctl"/>

宿主
///

1<param name="width"/>

宽度
///

1<param name="height"/>

高度
///

1<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);
}

///

1<summary>   
2/// 释放该插入符对象   
3/// </summary>

public void Destroy()
{
if (_HostControl != null)
ReleaseDC(_HostControl.Handle, dc);
this.Dispose();
}

///

1<summary>   
2/// 显示插入符   
3/// </summary>

public void Show() { tim.Start(); }

///

1<summary>   
2/// 隐藏插入符,隐藏效果会叠加,即调用了几次Hide,要再次显示时就要调用几次Show   
3/// </summary>

public void Hide() { tim.Stop(); }

////

1<summary>   
2/// 宿主窗体   
3/// </summary>

public Control HostControl { get { return _HostControl; } }

////

1<summary>   
2/// 获得或设置所有插入符闪烁时间间隔   
3/// </summary>

public int BlinkTime
{
get { return tim.Interval; }
set { tim.Interval = value; }
}

////

1<summary>   
2/// 获得或设置插入符的相对位置   
3/// </summary>

public Point Position
{
get { return _Position; }
set
{
_Position = value;
HostControl.Refresh();
}
}

///

1<summary>   
2/// 获得或设置插入符的大小   
3/// </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);
}
}
}

转载请注明出处,如果您要使用该代码,请告之作者

Published At
Categories with Web编程
Tagged with
comments powered by Disqus