Windows controls restricting user's Basic Law door (c#.net article)
Last Update:2017-02-28
Source: Internet
Author: User
window| Control/******************************************************************
Windows controls restrict the user's Basic Law door (. NET article)
C#.net's down there.
-------------------------------------------------------------------
This code demonstrates the basic way to control user input (masking non-numeric character input)
. NET to restrict user input, see many people are in the keyboard, or TextBox textchanged events to do
Personally think that's not true,
1. Cannot restrict user's pasting
2. Seriously interfere with data binding operation
3. Sometimes you also need to back up the original data to restore
In fact, the right time to restrict input is when Windows message WM_CHAR triggers
But. NET does not provide an event map for this message. What do we do?
Provide two columns for the scenario:
1 inheritance textbox rewrite WndProc function (Advantage Point OO programming advantages I don't say it)
Processing
if (M.msg==wm_char) {
Then take M.wparam to judge M.wparam is the int representation of the character entered by the user
If it is a restricted character direct return
Do not go base. WndProc (ref m);
}
if (m.msg==wm_paste)
{
Determine if the Clipboard data is compliant if it does not do any processing
Otherwise return does not go to the silent processing can
}
Base. WndProc (ref m);
2) Using API SetWindowLong to replace the default processing message function for processing
This is what this article is about, demonstrating how to declare an API and this method can be used in many languages.
But if you have multiple controls in your program that you want to limit input to, and you do a generic class library,
Use the recommended scenario one
Do not say much nonsense to see the code.
*******************************************************************/
Using System;
Using System.Drawing;
Using System.Collections;
Using System.ComponentModel;
Using System.Windows.Forms;
Using System.Data;
Using System.Runtime.InteropServices;
Using System.Text.RegularExpressions;
Using System.Diagnostics;
Namespace Setwndproc
{
<summary>
Summary description of the Form1.
</summary>
public class Form1:System.Windows.Forms.Form
{
Declaring a delegate
Public delegate IntPtr Newwndproc (IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
API specific help please check MSDN or go to MS website to find
[DllImport ("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SetWindowLong (IntPtr hWnd, int nindex, Newwndproc WndProc);
[DllImport ("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SetWindowLong (IntPtr hWnd, int nindex, IntPtr dwnewlong);
Useless to
[DllImport ("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr GetWindowLong (IntPtr hWnd, int nindex);
[DllImport ("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr CallWindowProc (IntPtr wndProc, IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
SetWindowLong with the constant, don't know what consciousness to see MSDN Bar
public const INT GWL_WNDPROC =-4;
Right-click menu message
public const int wm_contextmenu = 0x007b;
Paste Message
public const int wm_paste = 0x0302;
Input character message (keyboard input, input input is not like this message)
public const int WM_CHAR = 0x0102;
Be sure to declare it as a real-column variable otherwise, the local variable is easily _u71 after it is sent to the API. C Recycling,
There is an exception that cannot be caught at all
Private Newwndproc Wpr=null;
The silent processing function for a backup
Private INTPTR Oldwndproc=intptr.zero;
Private System.Windows.Forms.TextBox TextBox1;
<summary>
The required designer variable.
</summary>
Private System.ComponentModel.Container components = null;
Public Form1 ()
{
//
Required for Windows Forms Designer support
//
InitializeComponent ();
//
TODO: Add any constructor code after initializecomponent_u-29693.
//
}
<summary>
Clean up all resources that are in use.
</summary>
protected override void Dispose (bool disposing)
{
if (disposing)
{
if (Components!= null)
{
Components. Dispose ();
}
}
Base. Dispose (disposing);
}
Code generated #region the Windows forms Designer
<summary>
Designer supports required methods-do not use the Code editor to modify
The contents of this method.
</summary>
private void InitializeComponent ()
{
This.textbox1 = new System.Windows.Forms.TextBox ();
This. SuspendLayout ();
//
TextBox1
//
This.textBox1.Location = new System.Drawing.Point (32, 16);
This.textBox1.Name = "TextBox1";
This.textBox1.TabIndex = 0;
This.textBox1.Text = "555";
This.textBox1.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
Form1
//
This. AutoScaleBaseSize = new System.Drawing.Size (6, 14);
This. ClientSize = new System.Drawing.Size (152, 53);
This. Controls.Add (This.textbox1);
This. Name = "Form1";
This. Text = "Form1";
This. Load + = new System.EventHandler (this. Form1_Load);
This. Closed + = new System.EventHandler (this. form1_closed);
This. ResumeLayout (FALSE);
}
#endregion
<summary>
The main entry point for the application.
</summary>
[STAThread]
static void Main ()
{
Application.Run (New Form1 ());
}
Private IntPtr Textboxwndproc (intptr_u104? WND, int msg, IntPtr wParam, IntPtr LParam)
{
IntPtr Returnvar=intptr.zero;
Switch (msg)
{
Paste messages include Ctrl + V OR Right-click menu paste
Case Wm_paste:
Fetching Clipboard objects
IDataObject idata = Clipboard.getdataobject ();
To determine if it is text
if (Idata.getdatapresent (Dataformats.text))
{
Fetch data
String str;
str = (String) idata.getdata (Dataformats.text);
/*
To determine the position of the cursor on a textbox, if you need a sign
If the cursor can be used at the front, ^ ((\+|-) \d)? \d*) $
The following WM_CHAR should also be changed accordingly.
*/
If it's a number (you can paste it out)
if (Regex.IsMatch (str,@ "^ (\d{1,}) $") break;
}
Can not paste
Return (INTPTR) 0;
Case WM_CHAR:
int Keychar=wparam.toint32 ();
Debug.WriteLine (Keychar);
BOOL Charok= (keychar>47 && keychar<58) | | Digital
keychar==8 | | Backspace
keychar==3 | | keychar==22 | | keychar==24;//copy, paste, cut
If the character wParam that is not required is changed to character 0
Return (INTPTR) 0; Yes, but there's no keyboard tone that doesn't prohibit input.
if (!charok) wparam= (IntPtr) 0;
Break
No right-click menu (if required)
Case Wm_contextmenu:
Return (INTPTR) 0;
}
Functions that callback the default processing of a backup
Returnvar= CallWindowProc (Oldwndproc,hwnd,msg,wparam,lparam);
return Returnvar;
}
private void Form1_Load (object sender, System.EventArgs e)
{
This. Show ();
Backing up default handler functions
Oldwndproc=getwindowlong (TEXTBOX1.HANDLE,GWL_WNDPROC);
Materialized delegates (here is the callback function)
Wpr= New Newwndproc (this. TEXTBOXWNDPROC);
Replaces the control's default handler function (and returns the original default handler function, which is the geology of a function pointer)
Oldwndproc=setwindowlong (TEXTBOX1.HANDLE,GWL_WNDPROC,WPR);
}
private void Form1_Closed (object sender, System.EventArgs e)
{
Restore Default handler functions
if (!oldwndproc.equals (IntPtr.Zero))
SetWindowLong (TEXTBOX1.HANDLE,GWL_WNDPROC,OLDWNDPROC);
}
}
}