C# - WinForms: Extended TextBox won't undo after paste | Newbie | | Join Date: Jun 2009
Posts: 3
| |
I am using: C#, .Net, Windows Forms
I have created a derived class from the System.Windows.Forms.TextBox class that only allows hexadecimal characters to be entered, whether typed or pasted. (pasting just strips out all non-hex characters). It works fine except for the fact that I can't undo after pasting into the box. I feel this must have something to do with the fact that I took over WindProc for the WM_PASTE message, but I'm not sure what I'm supposed to insure that undo works with my altered paste. - using System;
-
using System.Collections.Generic;
-
using System.Linq;
-
using System.Text;
-
using System.Windows.Forms;
-
using System.Text.RegularExpressions;
-
-
class HexTextBox : TextBox {[indent]
-
private const int WM_PASTE = 0x302;
-
-
public HexTextBox()
-
base() {
-
this.KeyPress += new KeyPressEventHandler(KeyPressHandler);
-
}
-
-
protected override void WndProc(ref Message m) {
-
switch (m.Msg) {
-
case WM_PASTE:
-
OnPaste();
-
break;
-
default:
-
base.WndProc(ref m);
-
break;
-
}
-
}
-
-
protected virtual void OnPaste() {
-
string text = Clipboard.GetText();
-
if (text != null) {
-
text = StripNonHex(text);
-
InsertText(text);
-
}
-
}
-
-
protected virtual string StripNonHex(string text) {
-
return Regex.Replace(text, @"[^0-9a-fA-F]+", "").ToUpper();
-
}
-
-
protected virtual void InsertText(string newtext) {
-
int start = this.SelectionStart;
-
string oldtext = this.Text;
-
-
int end = start + this.SelectionLength;
-
int caretpos = start + newtext.Length;
-
-
this.Text = oldtext.Substring(0, start) + newtext + oldtext.Substring(end, oldtext.Length - end);
-
-
this.SelectionStart = caretpos;
-
}
-
-
protected void KeyPressHandler(object sender, KeyPressEventArgs e) {
-
int key = (int) char.ToUpper(e.KeyChar);
-
if (char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar)) {
-
e.Handled = false;
-
} else if ((key > 64) && (key < 71)) { // A(65) to F(70)
-
e.KeyChar = (char) key;
-
e.Handled = false;
-
} else {
-
e.Handled = true;
-
}
-
}
-
}
Any help would be appreciated as I'd like to make a good robust hex-editing textbox with more features for my project, but undo is a must.
|  | Moderator | | Join Date: Mar 2008 Location: Arizona, USA
Posts: 2,307
| | | re: C# - WinForms: Extended TextBox won't undo after paste
I commend how much time you must have spent formatting that inside a set of [quote] tags, using a bunch of[indent] tags and all but... If you just copy/paste from Visual Studio and wrap it with [code] tags it will save you a lot of work. TIP: When you are writing your question, there is a button on the tool bar that wraps the [code] tags around your copy/pasted code. It helps a bunch. Its the button with a '#' on it. More on tags. They're cool. Check'em out. |  | Moderator | | Join Date: Mar 2008 Location: Arizona, USA
Posts: 2,307
| | | re: C# - WinForms: Extended TextBox won't undo after paste Quote:
I feel this must have something to do with the fact that I took over WindProc for the WM_PASTE message,
If you think that is what broke it... don't do it that way. As anyone who has read my cookbook can tell you: There is more than one way to skin a cat.
Is there a reason you can't just use the TextChanged event instead of the more elaborate scheme of taking over windows messaging? When the text is changed (any press or paste) parse the text.
| | Newbie | | Join Date: Jun 2009
Posts: 3
| | | re: C# - WinForms: Extended TextBox won't undo after paste Quote:
Originally Posted by tlhintoq Is there a reason you can't just use the TextChanged event instead of the more elaborate scheme of taking over windows messaging? Because I'm an idiot :P
But anyways, I tried it with the TextChanged event and I'm still hitting the same problem: If I change the .Text property, undo doesn't work, although it functions just fine if user only tries to insert valid characters, but that's the whole point of this control. -
class HexTextBox : TextBox {
-
-
private static Regex nonhex = new Regex(@"[^0-9a-fA-F]+");
-
-
public HexTextBox()
-
: base() {
-
this.TextChanged += new EventHandler(TextChangedHandler);
-
}
-
-
protected void TextChangedHandler(object sender, EventArgs e) {
-
int caret = this.SelectionStart - this.Text.Length;
-
this.Text = nonhex.Replace(this.Text, "").ToUpper();
-
this.SelectionStart = caret + this.Text.Length;
-
}
-
}
-
Also, Thanks!
|  | Moderator | | Join Date: Mar 2008 Location: Arizona, USA
Posts: 2,307
| | | re: C# - WinForms: Extended TextBox won't undo after paste
Here's what I did to test this.. - New windows form project
- Drag a text box
- Gave it a handler for text change from the properties pallet | Events tab
- Pasted in your event handler code
- Adjusted the variable name references to match my project, but logic remains the same.
- using System;
-
using System.Collections.Generic;
-
using System.ComponentModel;
-
using System.Data;
-
using System.Drawing;
-
using System.Linq;
-
using System.Text;
-
using System.Windows.Forms;
-
using System.Text.RegularExpressions;
-
-
namespace Testing
-
{
-
public partial class Form1 : Form
-
{
-
private static Regex nonhex = new Regex(@"[^0-9a-fA-F]+");
-
public Form1()
-
{
-
InitializeComponent();
-
}
-
-
private void textBox1_TextChanged(object sender, EventArgs e)
-
{
-
int caret = ((TextBox)sender).SelectionStart - ((TextBox)sender).Text.Length;
-
((TextBox)sender).Text = nonhex.Replace(((TextBox)sender).Text, "").ToUpper();
-
((TextBox)sender).SelectionStart = caret + ((TextBox)sender).Text.Length;
-
}
-
}
-
-
}
I can cut/copy/paste/undo just fine.
So then I made a new class derived from TextBox and put in your logic. - class HexBox : TextBox
-
{
-
public HexBox()
-
{
-
this.TextChanged += new EventHandler(HexBox_TextChanged);
-
}
-
-
void HexBox_TextChanged(object sender, EventArgs e)
-
{
-
int caret = ((TextBox)sender).SelectionStart - ((TextBox)sender).Text.Length;
-
((TextBox)sender).Text = nonhex.Replace(((TextBox)sender).Text, "").ToUpper();
-
((TextBox)sender).SelectionStart = caret + ((TextBox)sender).Text.Length;
-
-
}
-
}
-
Then added a new HexBox to the form - public Form1()
-
{
-
InitializeComponent();
-
-
HexBox Yogi = new HexBox();
-
Yogi.Location = new Point(50,50);
-
this.Controls.Add(Yogi);
-
}
-
Yep that works too.
Recapping that makes the final project with a TextBox and a HexBox look like this. - using System;
-
using System.Collections.Generic;
-
using System.ComponentModel;
-
using System.Data;
-
using System.Drawing;
-
using System.Linq;
-
using System.Text;
-
using System.Windows.Forms;
-
using System.Text.RegularExpressions;
-
-
namespace Testing
-
{
-
public partial class Form1 : Form
-
{
-
private static Regex nonhex = new Regex(@"[^0-9a-fA-F]+");
-
public Form1()
-
{
-
InitializeComponent();
-
-
HexBox Yogi = new HexBox();
-
Yogi.Location = new Point(50,50);
-
this.Controls.Add(Yogi);
-
}
-
-
private void textBox1_TextChanged(object sender, EventArgs e)
-
{
-
int caret = ((TextBox)sender).SelectionStart - ((TextBox)sender).Text.Length;
-
((TextBox)sender).Text = nonhex.Replace(((TextBox)sender).Text, "").ToUpper();
-
((TextBox)sender).SelectionStart = caret + ((TextBox)sender).Text.Length;
-
}
-
-
-
-
class HexBox : TextBox
-
{
-
public HexBox()
-
{
-
this.TextChanged += new EventHandler(HexBox_TextChanged);
-
}
-
-
void HexBox_TextChanged(object sender, EventArgs e)
-
{
-
int caret = ((TextBox)sender).SelectionStart - ((TextBox)sender).Text.Length;
-
((TextBox)sender).Text = nonhex.Replace(((TextBox)sender).Text, "").ToUpper();
-
((TextBox)sender).SelectionStart = caret + ((TextBox)sender).Text.Length;
-
}
-
}
-
}
-
}
-
Hope it helps ya.
| | Newbie | | Join Date: Jun 2009
Posts: 3
| | | re: C# - WinForms: Extended TextBox won't undo after paste
First off, thanks for the help.
Ok, so the changes here are that instead of going through the textbox directly (ie, this.Text) we're going through the sender object (ie, ((TextBox)sender).Text), right? I don't see any other changes.
This works fine when I am only typing 0-9 & A-F but if I type an 'H' (which properly doesn't show up) or an 'a' (which properly becomes capitalized) undo breaks. If I paste 'BADDAD' undo works fine, but breaks on 'baddad' or 'Bad your dad is' (which both properly show up as 'BADDAD').
Are you not getting the same results? This might all be too big of a problem to waste time on since text boxes only do simple 'current value or last value' swapping instead of a real undo stack, but I'd like the box to function like normal except for what happens to its text input.
If you're seriously still not having any trouble with it, then I'm not sure what to do, because the behavior is definitely real on my machine, so please let me know if it's functioning the same on your machine or if undo really does work.
(Don't know if I should have mentioned it, I'm using: VisualStudio 2008, targeting .Net 3.5, on 64-bit Vista)
Thanks again, and I appreciate the help! :)
|  | Moderator | | Join Date: Mar 2008 Location: Arizona, USA
Posts: 2,307
| | | re: C# - WinForms: Extended TextBox won't undo after paste Quote:
Ok, so the changes here are that instead of going through the textbox directly (ie, this.Text) we're going through the sender object (ie, ((TextBox)sender).Text), right?
Right. This takes the sending control object named 'sender' and casts it from type object back to type TextBox. This way instead of making a specific new control (HexBox) we just process any TextBox for hex input. Quote:
Are you not getting the same results?
I can't say I tried to beat it up and make sure it was bullet-proof. I typed a little, I cut, I pasted, I undo'd. It may not be so much that it does or doesn't work, as just unexpected behavior of the undo code that you didn't write. After all, you are relying on Microsoft's idea of how undo should work. I don't know if it has a time element inside, or stops at a space, or just the last ten typed characters or what.
If you need to, I suppose you could just write it a little more code for doing your own "undo". After the text is parsed, and the approved hex-only content is in place then set some private variable to that. Override the undo so that it inserts the private variable. Quote:
(Don't know if I should have mentioned it, I'm using: VisualStudio 2008, targeting .Net 3.5, on 64-bit Vista)
Visual Studio 2008
targeting .Net 2.0
64-bit Vista ultimate
8 gig ram
4 cpu
5 monitors
1 poodle
6 robot toys
4 viper pilot mini legos
3rd mocha frappicino of the day
|  | Similar .NET Framework bytes | | | Forums
Visit our community forums for general discussions and latest on Bytes
/bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 229,155 network members.
|