Home All Groups Group Topic Archive Search About
Author
20 Oct 2005 1:09 PM
Arpan
A VB6 Form has 4 OptionButtons named opHex, opDec, opOct & opBin. As is
evident from the names, the OptionButtons convert numbers from one
number system to another.

This Form also has a menu with the same 4 items as the OptionButtons
i.e. numbers can be converted from one number system to another number
system either by using the OptionButtons or by using the menu. This
part of the application is exactly similar to the standard Windows
calculator. This means that at any point of time, only one of the menu
items & only one of the OptionButtons will be checked.

Now to get the hexadecimal equivalent of a number, I coded this (the
1st sub-routine computes the hexadecimal equivalent using the opHex
OptionButton & the 2nd sub-routine does the same using the menu):

Private Sub opHex_Click()
    mnuViewHex.Checked = True
    mnuViewDec.Checked = False
    mnuViewOct.Checked = False
    mnuViewBin.Checked = False

    txtNum1.Text = Hex(txtNum1.Text)
    lblDisplay.Caption = txtNum1.Text
End Sub

Private Sub mnuViewHex_Click()
    opHex.Value = True

    mnuViewHex.Checked = True
    mnuViewDec.Checked = False
    mnuViewOct.Checked = False
    mnuViewBin.Checked = False

    txtNum1.Text = Hex(txtNum1.Text)
    lblDisplay.Caption = txtNum1.Text
End Sub

Now suppose I enter 64 (in decimal number system) & click the opHex
OptionButton. This gives the correct hexadecimal equivalent which is 40
but when I do the same by navigating to the menu & clicking the Hex
menu item, the result changes to 28!

After a few experiments, I concluded that if the very 1st line in the
sub-routine mnuViewHex_Click() i.e. opHex.Value = True is removed, then
selecting the Hex menu item gives the correct hexadecimal equivalent of
64 as 40 but expectedly, the opHex OptionButton doesn't get checked &
that is a must!

Why is this happening & how do I overcome this problem?

Thanks,

Arpan

Author
20 Oct 2005 2:07 PM
Bob Butler
Show quote Hide quote
"Arpan" <arpan***@hotmail.com> wrote in message
news:1129813750.420560.238320@g44g2000cwa.googlegroups.com
> A VB6 Form has 4 OptionButtons named opHex, opDec, opOct & opBin. As
> is evident from the names, the OptionButtons convert numbers from one
> number system to another.
>
> This Form also has a menu with the same 4 items as the OptionButtons
> i.e. numbers can be converted from one number system to another number
> system either by using the OptionButtons or by using the menu. This
> part of the application is exactly similar to the standard Windows
> calculator. This means that at any point of time, only one of the menu
> items & only one of the OptionButtons will be checked.
>
> Now to get the hexadecimal equivalent of a number, I coded this (the
> 1st sub-routine computes the hexadecimal equivalent using the opHex
> OptionButton & the 2nd sub-routine does the same using the menu):
>
> Private Sub opHex_Click()
>     mnuViewHex.Checked = True
>     mnuViewDec.Checked = False
>     mnuViewOct.Checked = False
>     mnuViewBin.Checked = False
>
>     txtNum1.Text = Hex(txtNum1.Text)
>     lblDisplay.Caption = txtNum1.Text
> End Sub
>
> Private Sub mnuViewHex_Click()
>     opHex.Value = True

The line above triggers the opHex_Click event which does the conversion

>     mnuViewHex.Checked = True
>     mnuViewDec.Checked = False
>     mnuViewOct.Checked = False
>     mnuViewBin.Checked = False
>
>     txtNum1.Text = Hex(txtNum1.Text)
>     lblDisplay.Caption = txtNum1.Text

The 64 was converted to 40 by the opHex_Click event and the above lines
converted 40 to 28

> End Sub
>
> Why is this happening & how do I overcome this problem?

The simplest option would be to change your menu code to
    Private Sub mnuViewHex_Click()
    opHex.Value = True
    End Sub
that will trigger the opHex_Click which will do all the work

I'd also suggest doing:
  lblDisplay.Caption = Hex$(txtNum1.Text)
that way you don't change the value in the textbox


--
Reply to the group so all can participate
VB.Net: "Fool me once..."
Author
20 Oct 2005 2:53 PM
Arpan
Thanks, Bob, for your advice. Didn't realize that the Hex function was
getting executed twice.

Regards,

Arpan
Author
20 Oct 2005 3:58 PM
Jeff Johnson [MVP: VB]
"Arpan" <arpan***@hotmail.com> wrote in message
news:1129820014.341783.247430@g43g2000cwa.googlegroups.com...

> Thanks, Bob, for your advice. Didn't realize that the Hex function was
> getting executed twice.

That's why they invented "stepping through code." F8 is your friend.
Author
20 Oct 2005 8:29 PM
Rick Rothstein [MVP - Visual Basic]
Here is an approach I might have implemented (sort of top of the
head) to do what you are trying to do. First, I'd get rid of the
Label and do all input and display from the TextBox. Next, as Bob
pointed out, don't execute any functional code in the Menu events;
simply use them to fire the Click event for the OptionButtons.
Next, I created a subroutine to handle the check marks on the Menu
and call that from each OptionButton Click event. The logic behind
the code is this... always store the value in the TextBox as a
decimal value in the DecimalValue variable (this variable has
form-wide scope so any code on the form can access it). We do this
in the TextBox's Change event; however, we need a way to
distinguish if the change was from the user keying in a value or
the user clicking back and forth on the OptionButtons. We use a
Boolean flag variable (FromKeyboard) to make that distinction; it
is set to True in the KeyDown event for the TextBox (and False
again in the Change event). This allows the user to type and
modify the number in the TextBox while still being able to view
the number in Dec, Hex, Bin or Oct. Oh! And I also provided you
with conversion function between decimal and hex numbers. Finally,
I have provided a entry filter function (named IsInputValid) for
you to make sure that only proper text characters are allowed to
be typed in by the user for the various option selections (for
example, in Oct mode, the number 8 and 9 are not allowed; in Bin
mode, only 0 and 1, etc.). Anyway, play around with it and see
what you think.

Rick

Dim OldText As String
Dim OldSelStart As Long
Dim OldDecimalValue As Long
Dim DecimalValue As Long
Dim FromKeyboard As Boolean

Private Sub Form_Activate()
  txtNum1.SetFocus
End Sub

Private Sub Form_Load()
  opDec.Value = True
  With txtNum1
    .Text = 0
    .SelStart = 0
    .SelLength = 1
  End With
  DecimalValue = 0
End Sub

Private Sub mnuViewBin_Click()
  opBin.Value = True
End Sub

Private Sub mnuViewDec_Click()
  opDec.Value = True
End Sub

Private Sub mnuViewHex_Click()
  opHex.Value = True
End Sub

Private Sub mnuViewOct_Click()
  opOct.Value = True
End Sub

Private Sub opBin_Click()
  txtNum1.Text = Dec2Bin(DecimalValue)
  CheckMenu
End Sub

Private Sub opDec_Click()
  txtNum1.Text = DecimalValue
  CheckMenu
End Sub

Private Sub opHex_Click()
  txtNum1.Text = Hex(DecimalValue)
  CheckMenu
End Sub

Private Sub opOct_Click()
  txtNum1.Text = Oct(DecimalValue)
  CheckMenu
End Sub

Private Sub txtNum1_Change()
  If IsInputValid() Then
    If FromKeyboard Then
      If mnuViewHex.Checked Then
        DecimalValue = Val("&H" & txtNum1.Text)
      ElseIf mnuViewOct.Checked Then
        DecimalValue = Val("O" & txtNum1.Text)
      ElseIf mnuViewBin.Checked Then
        DecimalValue = Bin2Dec(txtNum1.Text)
      Else
        DecimalValue = txtNum1.Text
      End If
    End If
  Else
    txtNum1.Text = OldText
    txtNum1.SelStart = OldSelStart
    DecimalValue = OldDecimalValue
  End If
  FromKeyboard = False
End Sub

Private Sub txtNum1_KeyDown(KeyCode As Integer, Shift As Integer)
  OldText = txtNum1.Text
  OldSelStart = txtNum1.SelStart
  OldDecimalValue = DecimalValue
  FromKeyboard = True
End Sub

Sub CheckMenu()
  mnuViewHex.Checked = opHex.Value
  mnuViewDec.Checked = opDec.Value
  mnuViewOct.Checked = opOct.Value
  mnuViewBin.Checked = opBin.Value
End Sub

Function Bin2Dec(BinaryString As String) As Variant
  Dim X As Integer
  For X = 0 To Len(BinaryString) - 1
      Bin2Dec = CDec(Bin2Dec) + Val(Mid(BinaryString, _
                Len(BinaryString) - X, 1)) * 2 ^ X
  Next
End Function

Function Dec2Bin(ByVal DecimalIn As Variant) As String
  Dec2Bin = ""
  DecimalIn = Int(CDec(DecimalIn))
  Do While DecimalIn <> 0
      Dec2Bin = Trim$(Str$(DecimalIn - 2 * _
                      Int(DecimalIn / 2))) & Dec2Bin
      DecimalIn = Int(DecimalIn / 2)
  Loop
End Function

Function IsInputValid() As Boolean
  If opHex.Value Then
    If txtNum1.Text Like "*[!0-9a-fA-F]*" Then Exit Function
  ElseIf opDec.Value Then
    If txtNum1.Text Like "*[!0-9]*" Then Exit Function
  ElseIf opOct.Value Then
    If txtNum1.Text Like "*[!0-7]*" Then Exit Function
  ElseIf opBin.Value Then
    If txtNum1.Text Like "*[!01]*" Then Exit Function
  End If
  IsInputValid = True
End Function