Final Code Check Needed

Hi,
In my app I have 2 text fields - Hex1Field, and RField.

Hex1Field will contain the first 2 hexadecimal digits of a colour.
RField should display the RGB equivalent in RField.text.

My code below is in the keydown event of Hex1Field, but it’s working strangely.

Dim R As String = "&h" + Hex1Field.text Dim RResult As Integer = Val(R) RField.text = str(RResult)

When I enter the letter f in Hex1Field, the digit 0 appears in the RField.
When I enter another f, the RField changes to 15.

ff (hexadecimal) should return 255 in the RField - not 15??

Any Ideas, why it is doing that?

Thanks.

Because the Text doesn’t change until AFTER you return from KeyDown. Move the code to the TextChange event instead.

Thank you Kem - that did the trick!

Arghhhhhhhh.

I am now trying to do the reverse, but if I enter a 0 in the RField, it will not let me enter any other digits?
I can enter for example: 123 or 11 etc, but if I start with a 0, I can no longer any other digits??

Here is my code in the TextChange event:

Hex1Field.text = Hex(Val(RField.text))

My novice head is telling me that it has something to do with me needing to create a variable first, and then set the variable as a Double (I’m probably wrong though) :frowning:

To computers preceding zeros are useless.
When you enter 0, it thinks you’re done, especially if you’re evaluating it as a number.
To leave the zero there, you’d have to take it in as a string, and evaluate it as a number without showing the user.

???
Now I have come to a complete dead end :frowning:
I can’t see how I can take it as a string, if I can’t type in anything after a 0?

Any chance of an example of what you mean by take it in as a string, and evaluate it as a number without showing the user?
I am not asking for a complete solution to replace my code (as I want to learn this).

I just need an example of what you meant.

Thank you for spending the time to try and help me :slight_smile:

Dim inNumber as String = "1001"

if CBDl(InNumber) = 1001 Then
msgbox "We Match"
End if

Basic example but this is how I do what Tim is referring to. Many times I take a string that is numeric and use it in mathematical decisions like above. HTH>

If that’s all the code involved, it doesn’t explain the result you’re getting. Do you have any code in the KeyDown event of RField?

Tim,
I also have the following code in the KeyDown event:

[code] // DISALLOW ALL KEYS BY DEFAULT
Dim skipKey As Boolean = True

// ALLOW DIGITS 0-9
If Key >= “0” And Key <= “9” Then skipKey = False

// ALLOW THE BACKSPACE KEY
If Key = Chr(8) Then skipKey = False

// ALLOW THE DELETE KEY
If Key = Chr(127) Then skipKey = False

// IF ENTER OR TAB KEYS ARE PRESSED
If Key = Chr(9) or Key = Chr(13) Then
skipKey = False
// SET FOCUS TO THE NEXT TEXT FIELD
GField.SetFocus
Return True
end if

Return skipKey[/code]

That still doesn’t explain why a 0 would block any other digits. Something else is going on. Set a breakpoint in your keydown code and step through it and make sure skipKey is being set to false.

Tim,
I’m not familiar with the debugger at all, but I set a breakpoint at the beginning of the keydown code, and then ran the app.
After I press 0, I was taken back to the debugger and skipkey was false. I then stepped through once, and skipkey looks as if it is true?

Here is the screenshot:

You need to press the “step in” button (looks like an arrow pointing at a block) to allow the line of code to execute. If you then check the value of skipKey you should see it is false as expected.

Jason,
Step In causes the same screenshot.

When text in RField changes then it updates the text in Hex1Field and the TextChange event handler of Hex1Field changes the text of RField. For the key 0 the value of Hex1Field is always a single numeric zero that is coverted to a single character string of ‘0’ so the next zero typed in RField is never displayed in the RField.

//
// Hex1Field : TextChange
//
Dim R As String = "&h" + Hex1Field.text
Dim RResult As Integer = Val(R)
RField.text = str(RResult)

//
// RField : KeyDown
//
 // DISALLOW ALL KEYS BY DEFAULT
  Dim skipKey As Boolean = True
  
  // ALLOW DIGITS 0-9
  If Key >= "0" And Key <= "9" Then skipKey = False
  
  // ALLOW THE BACKSPACE KEY
  If Key = Chr(8) Then skipKey = False
  
  // ALLOW THE DELETE KEY
  If Key = Chr(127) Then skipKey = False
  
  
  // IF ENTER OR TAB KEYS ARE PRESSED
  If Key = Chr(9) or Key = Chr(13) Then
    skipKey = False
    // SET FOCUS TO THE NEXT TEXT FIELD
    GField.SetFocus
    Return True
  end if
  
  Return skipKey

//
// RFeild : TextChange
//
Hex1Field.text = Hex(Val(RField.text))

Syed,
I am not sure what you mean by the following statement:

Is it possible to try and re-phrase it?

Yes, most certainly.

First time 0 key is pressed in RField. The code in TextChange event handler of RField updates the Hex1Field with Hex value 0. The text of Hex1Field is updated and as a result the code in TextChange event handler of Hex1Field is executed. The Hex value 0 in Hex1Field is converted to decimal (numeric value of) 0 as an Integer and then coverted to String with function Str, resulting in a string that has one character ‘0’ that is saved as the value of RField.Text.

At this time the value of RField.Text is a string = ‘0’

Second time 0 key is pressed in RField. The code in TextChange event handler of RField updates the Hex1Field with Hex value 0. The text of Hex1Field is updated and as a result the code in TextChange event handler of Hex1Field is executed. The Hex value 0 in Hex1Field is converted to decimal (numeric value of) 0 as an Integer and then coverted to String with function Str, resulting in a string that has one character ‘0’ that is saved as the value of RField.Text.

At this time the value of RField.Text is again a string = ‘0’

And so on.

Any non-zero key in RField should update the Hex1Field and RField Text after a zero has been typed already in RField.

Why this does not go in to an endless loop (causing a Stack Overflow Exception) on Windows is unknown at this time. However somewhat similar situation used to cause Stack Overflow Exception on Linux and not in Windows for the same Xojo code.

Ahhhh, so the TextChange event of one field, is causing the TextChange event of the other field to fire, which in turn starts the loop over again, resulting in a kind of endless loop.

That makes sense!
If I moved the TextChange event code into the LostFocus event handler - would that resolve the situation?

The right way to resolve it is to only fire the code if the field has focus when the text changes. A simple way to do that is to create a property on the window like FocusField As TextEdit. The GotFocus event will store a reference to itself in FocusField, and the LostFocus event will set FocusField to nil. TextChange can check that property to see if its code should fire.

So, create the property as described. In each field, implement GotFocus and LostFocus.

Event GotFocus()
  FocusField = me
End

Event LostFocus()
  FocusField = nil
End

Event TextChange()
  if FocusField is me then
    // Do the TextChange stuff
  end if
End

Now if you really want to do it the “right” way, you’d subclass the TextField (or TextArea, whichever you’re using) and implement a HasFocus computed property as Boolean using the GotFocus and LostFocus events to set the property.

Why not use Window.Focus instead of creating your own focusField variable?

Event TextChange()
   if Focus is me then
      // do the textchange stuff
   end
end

Oh, they must have introduced that in just the last few minutes because otherwise, you know, I would have known about it…

@#$%!