|
-
Sep 2nd, 2008, 04:38 PM
#1
Thread Starter
Fanatic Member
[RESOLVED] [2008] 1 to 9 digits only textbox
Hi!!
I'm creating a Sudoku Solver and as you know in a Sudoku you can only enter the numbers 1, 2, 3, 4, 5, 6, 7, 8, 9. So in the textboxes of my program I have to limit the user input to these numbers. I went looking for a code for this in the forum and found this one from .paul.. This code is very good except that it also accepts the number 0. So I made my own:
Code:
Private Sub Textbox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Textbox1.TextChanged
Select Case e.KeyValue
Case Keys.Back, Keys.Delete, Keys.Left, Keys.Right, Keys.Home, Keys.End
Case Keys.D1 To Keys.D9, Keys.NumPad1 To Keys.NumPad9
If e.Modifiers <> 0 Then
e.SuppressKeyPress = True
e.Handled = False
End If
Case Else
e.SuppressKeyPress = True
e.Handled = False
End Select
End Sub
Everything works fine, from the exception that if I press Alt+0111 (or any other combination) I still get charater in the textbox (in this case an "o").
What is making me go crazy is that with If e.Modifiers <> 0 Then this input should be suppressed. How can I overcome this?
Thks a lot for the help!
-
Sep 2nd, 2008, 05:40 PM
#2
Re: [2008] 1 to 9 digits only textbox
try this:
vb Code:
Public Class intTextbox
Inherits TextBox
Const WM_PASTE As Integer = &H302
Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
e.Handled = Not (Char.IsControl(e.KeyChar) OrElse Char.IsDigit(e.KeyChar) And e.KeyChar <> "0"c)
MyBase.OnKeyPress(e)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_PASTE Then
Dim strText As String = Me.Text
strText = strText.Remove(Me.SelectionStart, Me.SelectionLength)
strText = strText.Insert(Me.SelectionStart, Clipboard.GetText)
Dim result As Integer = 0
If Not (Integer.TryParse(strText, result) And (result >= 1) And result.ToString.Length = Clipboard.GetText.Length) Then
Return
End If
End If
MyBase.WndProc(m)
End Sub
End Class
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
-
Sep 3rd, 2008, 07:17 AM
#3
Thread Starter
Fanatic Member
Re: [2008] 1 to 9 digits only textbox
Thks a lot paul. Just be curiosity would this could also work with a richtextbox instead?
-
Sep 3rd, 2008, 07:30 AM
#4
Re: [2008] 1 to 9 digits only textbox
For my Sudoku game, I use button's for the cells. If you're interested, I can send you the button class and whatnot
-
Sep 3rd, 2008, 07:45 AM
#5
Thread Starter
Fanatic Member
Re: [2008] 1 to 9 digits only textbox
If you use buttons how can the user input numbers?
-
Sep 3rd, 2008, 09:05 AM
#6
Re: [2008] 1 to 9 digits only textbox
Easily, capture the key pressed in the button's keypress event
I also used a button because you have the ability to draw the tiny available numbers on each button (which I've provided a menu item to turn that on and off) plus by using a button I've got it so when the user presses the up, down, left, or right arrow keys, focus moves automatically to the next button on the grid
If you're interested in trying it out, the exe is available on my website: http:/www.Juggalobrotha.com/games.html
I can give ya the code for the buttons later on if you're interested
-
Sep 3rd, 2008, 09:42 AM
#7
Lively Member
Re: [2008] 1 to 9 digits only textbox
could you post the code for the buttons?
-
Sep 3rd, 2008, 10:26 AM
#8
Thread Starter
Fanatic Member
Re: [2008] 1 to 9 digits only textbox
Nice program JuggaloBrotha. The code for the buttons would be nice.
-
Sep 3rd, 2008, 10:46 AM
#9
Re: [2008] 1 to 9 digits only textbox
I had to strip some of the stuff out of it, you guys should be able to implement it pretty easily into your own program(s)
Code:
'Loop to initialize things:
For x As Integer = 0I To 8I
For y As Integer = 0I To 8I
p = New CellButton(x, y)
p.Location = New Point() 'Set the location here
p.Size = New Size() 'Set the size here
p.Font = Me.Font
Me.Controls.Add(p)
m_Cells(x, y) = p
AddHandler p.KeyPressed, AddressOf CellsKeyPressed
Next y
Next x
'Here's the KeyPress event:
Private Sub CellsKeyPressed(ByVal c As CellButton, ByVal k As CellButton.CellKey)
Dim x As Integer = c.x
Dim y As Integer = c.y
Select Case k
Case CellButton.CellKey.KeyLeft
x -= 1
If x < 0 Then x += 8
StatusToolStripLabel.Text = String.Empty
Case CellButton.CellKey.KeyRight
x += 1
If x >= m_ArrayTopIndex + 1 Then x -= 8
StatusToolStripLabel.Text = String.Empty
Case CellButton.CellKey.KeyUp
y -= 1
If y < 0 Then y += 8
StatusToolStripLabel.Text = String.Empty
Case CellButton.CellKey.KeyDown
y += 1
If y >= m_ArrayTopIndex + 1 Then y -= 8
StatusToolStripLabel.Text = String.Empty
Case CellButton.CellKey.Key1 To CellButton.CellKey.Key9
Dim fv As Integer = k - CellButton.CellKey.KeyDelete
If fv <> c.forcedVal Then
Dim AllowedNumbers As New List(Of Integer)
AllowedNumbers.AddRange(GetNumbersLeft(x, y))
If AllowedNumbers.Contains(fv) = True Then
'Update your board
c.SetForcedVal(fv, False, GetNumbersLeft(x, y))
End If
End If
Case CellButton.CellKey.KeyDelete
If c.forcedVal <> 0 Then
'Update your board
c.SetForcedVal(0, False, GetNumbersLeft(x, y))
End If
Case Else
End Select
End Sub
'Here's the CellButton class that inherits from a Button:
Option Explicit On
Option Strict On
<System.Diagnostics.DebuggerStepThrough()> _
Friend Class CellButton
Inherits System.Windows.Forms.Button
Friend Enum CellKey
KeyDelete = 0I
Key1 = 1I
Key2 = 2I
Key3 = 3I
Key4 = 4I
Key5 = 5I
Key6 = 6I
Key7 = 7I
Key8 = 8I
Key9 = 9I
KeyUp = 10I
KeyDown = 11I
KeyLeft = 12I
KeyRight = 13I
End Enum
Friend ReadOnly x As Integer
Friend ReadOnly y As Integer
Friend forcedVal As Integer
Private v As Integer
Private m_NumberCanChangeBoolean As Boolean
Private m_AvailNumbers As New List(Of Integer)
Private solValues As Integer
Private m_ShowAvailNumbs As Boolean
Friend Sub New(ByVal x As Integer, ByVal y As Integer)
Me.x = x
Me.y = y
End Sub
Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
Select Case keyData
Case Keys.Up
RaiseEvent KeyPressed(Me, CellKey.KeyUp)
Return True
Case Keys.Down
RaiseEvent KeyPressed(Me, CellKey.KeyDown)
Return True
Case Keys.Left
RaiseEvent KeyPressed(Me, CellKey.KeyLeft)
Return True
Case Keys.Right
RaiseEvent KeyPressed(Me, CellKey.KeyRight)
Return True
Case Keys.Delete
RaiseEvent KeyPressed(Me, CellKey.KeyDelete)
Return True
Case Else
Return MyBase.ProcessDialogKey(keyData)
End Select
End Function
Protected Overrides Function ProcessDialogChar(ByVal charCode As Char) As Boolean
If m_NumberCanChangeBoolean = True Then
Dim k As CellKey = CellKey.Key1
Select Case charCode
Case "1"c : k = CellKey.Key1
Case "2"c : k = CellKey.Key2
Case "3"c : k = CellKey.Key3
Case "4"c : k = CellKey.Key4
Case "5"c : k = CellKey.Key5
Case "6"c : k = CellKey.Key6
Case "7"c : k = CellKey.Key7
Case "8"c : k = CellKey.Key8
Case "9"c : k = CellKey.Key9
Case "0"c, "."c, " "c : k = CellKey.KeyDelete
Case Else
Return False
End Select
RaiseEvent KeyPressed(Me, k)
Return True
Else
Return False
End If
End Function
Friend Event KeyPressed(ByVal sender As CellButton, ByVal key As CellKey)
Friend Sub SetForcedVal(ByVal v As Integer, ByVal PreSetBoard As Boolean, ByVal AvailableNumbers() As Integer)
forcedVal = v
Me.m_AvailNumbers.Clear()
Me.m_AvailNumbers.AddRange(AvailableNumbers)
If PreSetBoard = True Then
ForeColor = Color.Black
Me.v = v
Me.solValues = 1I << (v - 1I)
Else
If v > 0 Then
ForeColor = Color.Gray
Me.v = v
Me.solValues = 1I << (v - 1I)
Else
ForeColor = Color.Black
Me.solValues = 0I
Me.v = 0I
End If
End If
Me.Refresh()
End Sub
Private Shared bigfont As New Font("Microsoft Sans Serif", 20.0F, FontStyle.Bold)
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
Dim ExitSub As Boolean = False
Dim TopValue As Integer = 0I
For i As Integer = 1I To TopValue
Dim vi As Integer = 1I << (i - 1I)
If Me.solValues = vi Then
e.Graphics.DrawString(CStr(i), bigfont, New SolidBrush(Me.ForeColor), 5.0F, 4.0F)
ExitSub = True
End If
Next i
If ExitSub = False AndAlso m_ShowAvailNumbs = True Then
If m_AvailNumbers.Count > 0I Then
For Numb As Integer = 0I To m_AvailNumbers.Count - 1I
Select Case m_AvailNumbers(Numb)
Case 1 : e.Graphics.DrawString("1", Me.Font, New SolidBrush(Me.ForeColor), 2.0F, 0.0F)
Case 2 : e.Graphics.DrawString("2", Me.Font, New SolidBrush(Me.ForeColor), 12.0F, 0.0F)
Case 3 : e.Graphics.DrawString("3", Me.Font, New SolidBrush(Me.ForeColor), 22.0F, 0.0F)
Case 4 : e.Graphics.DrawString("4", Me.Font, New SolidBrush(Me.ForeColor), 2.0F, 11.0F)
Case 5 : e.Graphics.DrawString("5", Me.Font, New SolidBrush(Me.ForeColor), 12.0F, 11.0F)
Case 6 : e.Graphics.DrawString("6", Me.Font, New SolidBrush(Me.ForeColor), 22.0F, 11.0F)
Case 7 : e.Graphics.DrawString("7", Me.Font, New SolidBrush(Me.ForeColor), 2.0F, 22.0F)
Case 8 : e.Graphics.DrawString("8", Me.Font, New SolidBrush(Me.ForeColor), 12.0F, 22.0F)
Case 9 : e.Graphics.DrawString("9", Me.Font, New SolidBrush(Me.ForeColor), 22.0F, 22.0F)
End Select
Next Numb
End If
End If
End Sub
Friend Sub OtherCellChanged(ByVal AvailableNumbers() As Integer)
Me.m_AvailNumbers.Clear()
Me.m_AvailNumbers.AddRange(AvailableNumbers)
Me.Refresh()
End Sub
Friend Property NumberCanChange() As Boolean
Get
Return m_NumberCanChangeBoolean
End Get
Set(ByVal value As Boolean)
m_NumberCanChangeBoolean = value
End Set
End Property
Friend Property ShowAvailableNumbers() As Boolean
Get
Return m_ShowAvailNumbs
End Get
Set(ByVal value As Boolean)
m_ShowAvailNumbs = value
Me.Refresh()
End Set
End Property
End Class
You'll need to make a GetNumbersLeft() function that returns an integer array.
I'm sure there's a couple of other things that's not quite right in here.
Last edited by JuggaloBrotha; Sep 3rd, 2008 at 10:49 AM.
-
Sep 5th, 2008, 08:45 AM
#10
Re: [2008] 1 to 9 digits only textbox
Ok, I had a few minutes to pull out the use of the button code and put it into an example.
Last edited by JuggaloBrotha; Jun 30th, 2010 at 03:00 PM.
-
Sep 5th, 2008, 08:56 AM
#11
Re: [2008] 1 to 9 digits only textbox
You could create a user control like this
Code:
Imports System.Object
Imports System.Windows.Forms
Public Class testClass
Inherits TextBox
Private Const WM_RBUTTONUP As Long = &H205
Public Const WM_COPY = &H301
Public Const WM_Paste = &H302
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_COPY Then
MessageBox.Show("Cannot copy")
Return
End If
If m.Msg = WM_RBUTTONUP Then
Return
End If
If m.Msg = WM_Paste Then
Return
End If
MyBase.WndProc(m)
End Sub
Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
MyBase.OnKeyPress(e)
If Not (Char.IsNumber(e.KeyChar)) Then
MessageBox.Show("Not number")
e.Handled = True
End If
End Sub
End Class
And you need to modify this part
Code:
Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
MyBase.OnKeyPress(e)
If Not (Char.IsNumber(e.KeyChar)) Then
MessageBox.Show("Not number")
e.Handled = True
Else
'Validate Here
End If
End Sub
Please mark you thread resolved using the Thread Tools as shown
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|