自己寫的數字文本框控件

數字文本框可能是大家常用的,也需要的控件。
其實在dotnet裏,大家是可以使用masktextbox的。
 
以前使用delphi,vc時都編過數字文本框控件。
可惜那時候無法跨語言使用。
 
基於以前的基礎我整理了一下以前的代碼,把它改成了
dotnet的控件。至少在vs裏面是可以所有的語言都能使用的。
希望能夠對大家有所幫助。
 
基本思想如下:
重載wndproc處理WM_CHAR和WM_PASTE
 
代碼copy如下:
 
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Hob.Toolbox.Controls
{
    /// <summary>
    /// 數字編輯框控件
    /// dotnet裏可以採用masktextbox,但是可能會有佔位符
    /// </summary>
    public class NumberTextBox:TextBox
    {
        #region windows api
        private const uint WM_CHAR = 0x0102;
        private const uint WM_PASTE = 0x0302;
        private const int CF_TEXT = 1;
        [DllImport("user32")]
        private static extern bool MessageBeep(uint type);
        [DllImport("user32")]
        private static extern bool OpenClipboard(IntPtr hwnd);
        [DllImport("user32")]
        private static extern bool CloseClipboard();
        [DllImport("user32")]
        private static extern IntPtr GetClipboardData(uint uFormat);
        [DllImport("kernel32.dll")]
        private static extern IntPtr GlobalLock(IntPtr hMem);
        [DllImport("kernel32.dll")]
        private static extern bool GlobalUnlock(IntPtr hMem);
        #endregion
        protected override void WndProc(ref Message m)
        {
            switch ((uint)m.Msg)
            {
                case WM_CHAR://處理char
                    OnChar(ref m);
                    break;
                case WM_PASTE://處理paste
                    OnPaste(ref m);
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }
        /// <summary>
        /// 處理字符輸入
        /// </summary>
        /// <param name="m"></param>
        private void OnChar(ref Message m)
        {
            uint nChar = (uint)m.WParam;
            //backspace,ctrl+v,ctrl+c,ctrl+x,ctrl+z
            if((nChar == 8)||(nChar==22)||(nChar==3)||(nChar==24)||(nChar==26))
         {
                base.WndProc(ref m);
                return;
         }
            if (!IsValidChar(nChar))//無效字符返回
            {
                MessageBeep(0xFFFFFFFF);
                return;
            }
            base.WndProc(ref m);
        }
        /// <summary>
        /// 是否有效字符
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        private bool IsValidChar(uint c)
        {
            if ((c >= '0') && (c <= '9'))
                return true;
            if ((c == 13) && Multiline)
                return true;
            return false;
        }
        /// <summary>
        /// 是否有效的字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private bool IsValidStr(string str)
        {
            int len = str.Length;
            for (int i = 0; i < len; i++)
            {
                char c = str[i];
                if (!IsValidChar((uint)c))
                    return false;
            }
            return true;
        }
        /// <summary>
        /// 粘貼時的處理
        /// </summary>
        /// <param name="m"></param>
        private void OnPaste(ref Message m)
        {
            bool pasteok = true;
            if (OpenClipboard(Handle))
            {
                IntPtr ClipHandle = GetClipboardData(CF_TEXT);
                if (ClipHandle != IntPtr.Zero)
                {
                    //判斷是否拷貝後的內容正確
                    IntPtr pbuf = GlobalLock(ClipHandle);
                    string sbuf = Marshal.PtrToStringAnsi(pbuf);
                    string stext=Text;
                    int bindex=SelectionStart;
                    int eindex=SelectionStart+SelectionLength;
                    string newtext=stext.Substring(0,bindex)
                         +sbuf+stext.Substring(eindex,stext.Length-eindex);
                    pasteok = IsValidStr(newtext);
                    GlobalUnlock(ClipHandle);
                }
                CloseClipboard();
            }
            if (!pasteok)
            {
                MessageBeep(0xFFFFFFFF);
                return;
            }
            base.WndProc(ref m);
        }
    }
}
下載鏈接:
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章