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

类别:.NET开发 点击:0 评论:0 推荐:

  在有些时候,我们需要在自己的控件中加入象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);
        }
    }
}

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

本文地址:http://com.8s8s.com/it/it41509.htm