Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

How do I store an integer as a hex value into a file?

Posted on 2004-11-03
13
Medium Priority
?
340 Views
Last Modified: 2012-05-05
I am using VB6 and have a requirement to store an integer value into a hex 2-byte field in a file, with the bytes reversed. For example, an integer of 512 needs to be stored in the file as 0020. I know how to convert the value of 512 into a hex string with the ascii characters "200" but I don't know how to store this as a 2-byte hex field with a value of 0020. Any assistance would be greatly appreciated.
0
Comment
Question by:dombrov55
  • 4
  • 4
  • 2
  • +3
13 Comments
 
LVL 1

Expert Comment

by:J-Mik
ID: 12484308
Dombrov55,

Where are you storing this to? If the field is a 2-byte numeric field, then hex or not, you should be able to send 512 directly into it, without the need to convert it to ASCII. By converting 512 into "200", you've turned it into a 3-byte character field.
0
 
LVL 18

Expert Comment

by:JR2003
ID: 12484657
Option Explicit

Private Sub Command1_Click()

    Dim sBinString As String
    Dim iResultLong As Long
    Dim sHexResult As String
   
    sBinString = ConvertToBinaryReversedString(512)
    iResultLong = ConvertBinToDecimal(sBinString)
    sHexResult = Hex(iResultLong)
    MsgBox sHexResult
End Sub

Private Function ConvertToBinaryReversedString(ByVal InInt As Long) As String

    Dim sBin As String
    Dim i As Long
    i = 1
    sBin = String(16, "0")
    While InInt > 0
        If InInt And 1 Then
            Mid$(sBin, i, 1) = "1"
        Else
            Mid$(sBin, i, 1) = "0"
        End If
        InInt = InInt / 2
        i = i + 1
    Wend
    ConvertToBinaryReversedString = sBin
   
End Function

Private Function ConvertBinToDecimal(ByVal InBinString As String) As Long

    Dim iResult As Long
    Dim i As Long
    For i = 1 To Len(InBinString)
        If Mid(InBinString, i, 1) = "1" Then
            iResult = iResult + 2 ^ (Len(InBinString) - i)
        End If
    Next i
    ConvertBinToDecimal = iResult
End Function
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 32

Expert Comment

by:Erick37
ID: 12484902
You can use the API rtlMoveMemory (CopyMemory) to reverse the byte order of the integer.  This example flips the bytes of the input integer and saves the result to a second integer.  You can either use the resulting integer as a number, or format it as text.

Option Explicit

Private Declare Sub MoveMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private Sub Command1_Click()

    Dim nIn As Integer
    Dim nOut As Integer
   
    nIn = 512
   
    'Flip the bytes of the integers
    Call MoveMemory(ByVal VarPtr(nOut), ByVal VarPtr(nIn) + 1, 1)
    Call MoveMemory(ByVal VarPtr(nOut) + 1, ByVal VarPtr(nIn), 1)
   
    'Test the results
    Debug.Print Format(Hex(nIn), "0000")
    Debug.Print Format(Hex(nOut), "0000")

End Sub
0
 

Author Comment

by:dombrov55
ID: 12489507
Thanks for the very prompt responses but I think I need to clarify what I am asking for. I will have numeric input, string format, that needs to be converted to hex and stored in reverse order. So my input could be "1000", which is hex 03E8 but it needs to be stored as E803, but not  as "3E8" or "E803". The data field in the file is a 2-byte field and the application reading this data (not my application) expects it in this format.

0
 
LVL 32

Expert Comment

by:Erick37
ID: 12489703
If your input is a string, then first convert it to integer data type before flipping the order (integers are 2 bytes).  Since the output datafield expects 2 bytes you must save the data as integer data type (not string because the string "E803" requires 4 bytes).

Your result in HEX is &HE803, which is stored internally as an integer with the value of -6141.

Option Explicit

Private Declare Sub MoveMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private Sub Command1_Click()

    Dim sInput As String
    Dim nIn As Integer
    Dim nOut As Integer
   
    'Convert your string input to an integer first
    sInput = "1000"
    nIn = CInt(sInput)
   
    'Flip the bytes of the integers
    Call MoveMemory(ByVal VarPtr(nOut), ByVal VarPtr(nIn) + 1, 1)
    Call MoveMemory(ByVal VarPtr(nOut) + 1, ByVal VarPtr(nIn), 1)
   
    'The result is in nOut (integer = 2 bytes)
    Debug.Print "nOut = " & nOut
    Debug.Print "nOut in HEX = " & Format(Hex(nOut), "0000")


End Sub
0
 
LVL 3

Expert Comment

by:onemorecoke
ID: 12489961
Just do:

sHex=format$(mid$(hex$(512),3,2),"00") & format$(mid$(hex$(512),1,2),"00")

It will work perfectly!

onemorecoke
0
 

Author Comment

by:dombrov55
ID: 12490024
Thanks very much Erik, I'm getting very close as it does give me the result I want, sort of.  However, the integer field in my data record ends up getting stored a 03E8, although I know a -6141 is really  FFFFE803. Do I need one more step that has to do with signed our unsigned, or do I And off those high-order bits from nOut?

0
 
LVL 32

Expert Comment

by:Erick37
ID: 12493794
How are you saving/writing the data?
FFFFE803 is a Long (4 byte) data type representation of the result.  If you save the result in an Integer (2 byte) then it will be E803.
0
 
LVL 26

Expert Comment

by:EDDYKT
ID: 12494955
Private Declare Function LoByte Lib "TLBINF32" Alias "lobyte" (ByVal Word As Integer) As Byte
Private Declare Function HiByte Lib "TLBINF32" Alias "hibyte" (ByVal Word As Integer) As Byte
Private Declare Function loword Lib "TLBINF32" (ByVal DWord As Long) As Integer
Private Declare Function hiword Lib "TLBINF32" (ByVal DWord As Long) As Integer

Private Sub Form_Load()

    Value = 512
    Debug.Print LoByte(loword(Value))
    Debug.Print HiByte(loword(Value))
    Debug.Print LoByte(hiword(Value))
    Debug.Print HiByte(hiword(Value))
End Sub
0
 

Author Comment

by:dombrov55
ID: 12497216
Erik,

I'm storing as an integer (2 bytes), however, when I I look at the file after it's been stored, the value appears as 03E8, correct number of bytes, but the bytes are reversed from how I need them. I'm using a Put statement to write the record and have Opened the file As Random.
0
 
LVL 32

Accepted Solution

by:
Erick37 earned 1000 total points
ID: 12497876
Right,  When you save data in binary (using Put #) it is stored on Intel/Windows machines in byte reversed order called Little-Endian.  So your data will appear in the file as already byte reversed.  When you read it back using Get, it is unflipped for you.

If the application that is reading the data needs this byte reversed order, then you need not flip the bytes before using the Put statement.
0
 

Author Comment

by:dombrov55
ID: 12500565
Thanks again Erik, that was it! Turns out what I needed was embarrassingly easy, all I needed was to assign the integer to the field on my record and do the Put #.  I should have mentioned at the beginning that I was using the Put #.  I had previously tried assigning the integer to the record and doing output with the Print # statement but in that case I believe it stored the actual integer, not the hex value as required. I did learn something here and appreciate the responses from everyone, even picked up on some other code I might be able to use somewhere else.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Suggested Courses
Course of the Month14 days, 15 hours left to enroll

578 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question