Solved

Formatting the values returned from RegEnumValue

Posted on 2000-03-30
8
341 Views
Last Modified: 2008-03-10
I've been putting together a nice little class for reading and writing to the registry, copying or deleteing registry keys and all of their sub keys and/or values.  


My problem is that after running RegEnumValue, I'm displaying the contents of the values in a grid. This works fine for values of type string, but I'm not formatting the DWORD or BINARY return values correctly for display.  

What I'd like to do, is translate DWORD values so that they display exactly as they do in RegEdit.  So, a DWORD with a hex value of 20000, decimal value of 131072 will display as:

0x00020000 (131072)

and a BINARY value will display as:
9A 01 00 00 34 00 00 00
84 00 00 00 FC 02 00 00

and so on ....

(extra points if you can display it as:)
9A 01 00 00 34 00 00 00  ....4...
84 00 00 00 FC 02 00 00  .....u..

with the character representation on the right.

These are the two main types I need help displaying, but extra points for a more complete answer that formats all of the possible Registry value types.

Here is the kind of function I was trying to write:
(but it's not working properly)

Public Function FormatValue(vValue As Variant, nType As Long) As String
Dim Temp As String
Dim J As Long

 Select Case nType
     Case REG_DWORD
         For J = 1 To Len(vValue)
             Temp = Temp & CStr(CDec(Asc(Mid(vValue, J, 1))))
         Next J
         Temp = "0x0" & Temp & IIf(7 - Len(Temp) > 0, String(7 - Len(Temp), "0"), "")
         FormatValue = Temp
     Case REG_BINARY
         For J = 1 To Len(vValue)
             Temp = Temp & IIf(Len(CStr(Hex(Asc(Mid(vValue, J, 1))))) > 1, "", "0") & CStr(CDec(Asc(Mid(vValue, J, 1)))) & IIf(J Mod 8 = 0, vbCrLf, Space(1))
         Next J
         FormatValue = Temp
     Case Else
         FormatValue = vValue
End Select

End Function
0
Comment
Question by:mdougan
  • 5
  • 3
8 Comments
 
LVL 3

Accepted Solution

by:
Gordonp earned 200 total points
ID: 2672515
Public Function FormatValue(byData() As Byte, nType As Integer) As String

    Select Case nType
        Case REG_DWORD
            Dim dwValue As Long
            CopyMemory dwValue, byData(0), LenB(dwValue)
            FormatValue = Format(dwValue, "0x00000000") & " (" & dwValue & ")"
                       
        Case REG_SZ
            FormatValue = byData

        Case REG_BINARY
            'Coming Soon

    End Select
       
End Function

Heres the DWORD part of your question.

this assumes you copied the data into a byte array from the pointer returned by RegEnumValue.

I'll have the bit for the REG_BINARY just shortly

Gordon
0
 
LVL 3

Expert Comment

by:Gordonp
ID: 2672651
       Case REG_BINARY
            Dim sLine As String
            Dim sLine2 As String
       
            Dim I As Integer
            For I = 0 To UBound(byData)
                sLine = sLine & Format(byData(I), "00") & " "
                sLine2 = sLine2 & Chr(byData(I))
                               
                If (I Mod 8) = 0 Then
                    FormatValue = FormatValue & vbCrLf & sLine & vbTab & sLine2
                    sLine = ""
                    sLine2 = ""
                End If
            Next

Here the bit for the Binary formatting

Hope this helps

Gordon
0
 
LVL 18

Author Comment

by:mdougan
ID: 2673199
So far, this looks great, but I hadn't been copying the data to a byte array.  When I tried to do it in your routine I got a type missmatch, so, I'm not sure how to load the byte array.  

Here is the code I use in the enum function, which puts the value into a variant/string.  This type of variable works fine for the routine that copies one tree to another, but if you can suggest how to put the value into a byte array instead of a string/variant then the points are yours:

            nRet = RegEnumValue(hKey, nIndex, ValueName, nValueNameLen, ByVal 0&, nType, ByVal Value, nValueLen)
            If nRet = ERROR_SUCCESS Then
                ReDim Preserve Values(0 To 2, 0 To nStrings) As Variant
                Values(0, nStrings) = Left$(ValueName, nValueNameLen)
                Values(1, nStrings) = Left$(Value, nValueLen - 1)
                Values(2, nStrings) = nType


Or, if you can modify your routine to use a variant/string is the input parm, and then copy to a byte array in the routine, even better.
0
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
LVL 18

Author Comment

by:mdougan
ID: 2684351
GordonP's answer looks good, but it only takes me half way.  I'm currently getting the value out of RegEnumValue as a variant/string.  To use GordonP's function, I'd need it to be in a byte array.  

So, I'd either need a way to put the value in a Byte Array from RegEnumValue or, better for me, to have GordonP's function accept a variant/string and then do whatever it has to do to format it for display.

I'm opening this back up since GordonP hasn't replied in a couple of days.
0
 
LVL 3

Expert Comment

by:Gordonp
ID: 2692442
Ok, I'm back.

I was on holiday.

Have you tried passing a byte array to RegEnumValue instead of a string

Other option is to convert your string

Dim byData() as byte
byData = strconv(Value,vbFromUnicode)

Hope these help

Gordon
0
 
LVL 18

Author Comment

by:mdougan
ID: 2700695
Adjusted points from 150 to 200
0
 
LVL 18

Author Comment

by:mdougan
ID: 2700696
Thanks!  I was finally able to get it to display as I wanted it to.  I did have to make a few adjustments to your original routine, so I'll post the final version below for the benefit of others that might buy this question.  

Putting the values returned from RegEnumValue into a variant/string type variable worked for me, as I created a two dimensional variant array that would hold the name of the key, the value, and the type of the key.  In all of the code for copying the values or otherwise manipulating the registry, I didn't have to do anything to the value, it was only in displaying it that I had to muck around with it.  So, I was happy to convert it to the byte array in the display routine.  Thanks for the strconv using vbFromUnicode, I don't think I ever would have figured that out on my own.

Some of the things that I had to change to get it to display the binary like RegEdit, I had to pad a line that was less than 8 characters, so that the last line's char rep would line up with the others.  I also changed certain ascii codes to "." in the char rep to match what RegEdit displays.  Also, I added the HEX function to get the hex rep of the decimal values.  This was necessary for both the DWORD and BINARY displays.  I also put in code to keep the very first line of the binary display from being prefaced by a tab.

Thanks again!

Public Function FormatValues(vValue As Variant, nType As Integer) As String
Dim sLine As String
Dim sLine2 As String
Dim i As Integer
Dim byData() As Byte
Dim sTemp As String
   
    byData = StrConv(vValue, vbFromUnicode)
                       
    Select Case nType
        Case REG_DWORD
            Dim dwValue As Long
            CopyMemory dwValue, byData(0), LenB(dwValue)
            sTemp = Hex(dwValue)
            FormatValues = "0x" & IIf(Len(sTemp) < 8, String(8 - Len(sTemp), "0"), "") & sTemp & " (" & dwValue & ")"
                         
        Case REG_SZ
            FormatValues = vValue

        Case REG_BINARY
        For i = 0 To UBound(byData)
            sTemp = Trim(Format(Hex(byData(i)), "@@"))
            sLine = sLine & IIf(Len(sTemp) < 2, "0", "") & sTemp & " "
            sLine2 = sLine2 & IIf((byData(i) < 32 Or _
                                  byData(i) = 127 Or _
                                 (byData(i) >= 129 And byData(i) <= 144) Or _
                                 (byData(i) >= 147 And byData(i) <= 159)), _
                                 ".", Chr(byData(i)))
            If ((i + 1) Mod 8) = 0 Then
                FormatValues = FormatValues & IIf(Len(FormatValues) > 0, vbCrLf, "") & sLine & vbTab & sLine2
                sLine = ""
                sLine2 = ""
            End If
        Next
        FormatValues = FormatValues & IIf(Len(FormatValues) > 0, vbCrLf, "") & sLine & IIf(Len(sLine) < 24, Space(24 - Len(sLine)), "") & vbTab & sLine2
    End Select
         
End Function
0
 
LVL 18

Author Comment

by:mdougan
ID: 2700705
Thanks again.
0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
vb6 programatically bring window to front 8 70
Sending a email via excel using vba 6 79
MS Date Picker 64 bit 32 bit issue 12 53
Recommendation vb6 to vb.net or others 14 142
Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
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…

786 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