在有些时候,我们需要在自己的控件中加入象TextBox一样的插入符
这个功能可以使用Windows API完成
因此我封装了Caret的API,形成了Caret组件,可以方便的在控件设计中使用
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, IDisposable
{
#region Native
private const string User32 = "User32.dll";
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
}
///
1<summary>
2/// 产生一个新的系统插入符,并将其分配给指定的窗口
3/// </summary>
///
1<param name="hWnd"/>
窗口句柄
///
1<param name="hBitmap"/>
用作插入符的一幅位图的句柄.可以是0或1;在这种情况下,插入符可通过width和height参数创建.如设为1,则新插入符以灰色显示;而不是传统的黑色
///
1<param name="nWidth"/>
插入符宽度
///
1<param name="nHeight"/>
插入符宽度
///
1<returns>成功创建返回True;失败返回False</returns>
///
1<remarks>只有一个窗口得到键盘输入焦点或激活时才能给其创建插入符,在失去键盘输入焦点前应销毁插入符</remarks>
[DllImport(User32)]
private static extern bool CreateCaret(IntPtr hWnd,bool hBitmap, int nWidth, int nHeight);
///
1<summary>
2/// 使插入符出现在窗口的在插入符位置上,当插入符出现后即会自动闪烁
3/// </summary>
///
1<param name="hWnd"/>
窗口句柄
///
1<returns>成功创建返回True;失败返回False</returns>
///
1<remarks>只有窗口自己拥有插入符,且插入符有自己的形状,并且不被隐藏时才会出现,HideCaret是效果叠加的,举例说,如果你在程序中调过3次HideCaret,那就必需再调用3次ShowCaret </remarks>
[DllImport(User32)]
private static extern bool ShowCaret(IntPtr hWnd);
///
1<summary>
2/// 隐藏插入符,插入符隐藏后并没有破坏它的形状和插入符位置
3/// </summary>
///
1<param name="hWnd"/>
窗口句柄
///
1<returns>成功创建返回True;失败返回False</returns>
[DllImport(User32)]
private static extern bool HideCaret(IntPtr hWnd);
///
1<summary>
2/// 得到以毫秒为单位的插入符闪烁间隔
3/// </summary>
///
1<returns>成功返回闪烁间隔;失败返回0</returns>
[DllImport(User32)]
private static extern uint GetCaretBlinkTime();
///
1<summary>
2/// 以毫秒为单位的设置插入符闪烁间隔
3/// </summary>
///
1<param name="milliseconds"/>
插入符闪烁间隔
///
1<returns>成功创建返回True;失败返回False</returns>
[DllImport(User32)]
private static extern bool SetCaretBlinkTime(uint milliseconds);
///
1<summary>
2/// 销毁指定窗口的插入符
3/// </summary>
///
1<param name="hWnd"/>
窗口句柄
///
1<returns>成功创建返回True;失败返回False</returns>
///
1<remarks>只有窗口拥有插入符时才能销毁,否则该函数会立即返回FALSE</remarks>
[DllImport(User32)]
private static extern bool DestroyCaret(IntPtr hWnd);
///
1<summary>
2/// 移动插入符到指定位置
3/// </summary>
///
1<param name="x"/>
X坐标
///
1<param name="y"/>
Y坐标
///
1<returns>成功创建返回True;失败返回False</returns>
///
1<remarks>不管插入符是否可见,此函数都会移动插入符的位置</remarks>
[DllImport(User32)]
private static extern bool SetCaretPos(int x, int y);
///
1<summary>
2/// 得到插入符的位置
3/// </summary>
///
1<param name="ppt"/>
指向POINT结构的插入符位置
///
1<returns>成功创建返回True;失败返回False</returns>
[DllImport(User32)]
private static extern bool GetCaretPos(out POINT ppt);
#endregion
private Control _HostControl;
private Caret() { }
///
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):this(ctl,true,width,height){}
///
1<summary>
2/// 使用特定的大小创建一个插入符,可以指定黑色或灰色
3/// </summary>
///
1<param name="ctl"/>
插入符宿主
///
1<param name="black"/>
True为使用黑色,False为使用灰色
///
1<param name="width"/>
宽度
///
1<param name="height"/>
高度
///
1<remarks>创建完成后插入符默认为隐藏的</remarks>
public Caret(Control ctl,bool black, int width, int height)
{
_HostControl = ctl;
Caret.CreateCaret(this._HostControl.Handle, !black, width, height);
}
///
1<summary>
2/// 释放该插入符对象
3/// </summary>
public void Destroy()
{
Caret.DestroyCaret(_HostControl.Handle);
}
///
1<summary>
2/// 隐藏插入符,隐藏效果会叠加,即调用了几次Hide,要再次显示时就要调用几次Show
3/// </summary>
public void Hide()
{
Caret.HideCaret(this.HostControl.Handle);
}
///
1<summary>
2/// 显示插入符
3/// </summary>
public void Show()
{
Caret.ShowCaret(this.HostControl.Handle);
}
///
1<summary>
2/// 宿主窗体
3/// </summary>
public Control HostControl { get { return _HostControl; } }
///
1<summary>
2/// 获得或设置所有插入符闪烁时间间隔
3/// </summary>
///
1<value></value>
public static uint BlinkTime
{
get { return Caret.GetCaretBlinkTime(); }
set { Caret.SetCaretBlinkTime(value); }
}
///
1<summary>
2/// 获得或设置当前激活的控件的插入符的相对位置
3/// </summary>
///
1<value></value>
public static Point Position
{
get
{
POINT p = new POINT();
if (Caret.GetCaretPos( out p))
{
MessageBox.Show(p.x + "," + p.y);
return new Point(p.x, p.y);
}
return Point.Empty;
}
set {Caret.SetCaretPos( value.X, value.Y); }
}
}
}
转载请注明出处,如果您要使用该代码,请告之作者