Getting wrong data using ReadProcessMemory in VB6

AchilleTalon used Ask the Experts™
I want to read the text in the panes of another application's status bar usng VB6. I found the code from Ark. It sort of works in that it returns strings having the correct number of characters (using the ReadProcessMemory function). But the strings all contain empty squares.
I tried to convert the string to hex using Hex$(Asc$(Mid$(string,   etc.) but that returns Zero.
The code shows a test procedure that displays no error when running. The application I am trying to get information from was written in NT and I traced the procedure, it goes through the NT portion.
I do not know how to get the data from memory into recognizable data
Thanks in advance

Private Sub cmdRdSBr_Click()
'Gets the Status Bar handle and tries to extract the entire text in the different panels
Dim hwndStBr As Long
Dim hwndStBrChld As Long
Dim sBrTxt As String
Dim lpEnumFunc As Long
Dim lParam As Long
Dim nCount As Long
Dim pid As Long
Dim hProcess As Long
Dim lWritten As Long
Dim lpSysShared As Long, hFileMapping As Long, dwSize As Long
Dim lRet As Long
Dim sTemp As String
Dim SBText() As String
Dim sRet As String
Dim i As Integer
Dim j As Integer
Dim k As Integer
'Find the status bar handle
hwndStBr = FindWindowEx(hwndPHD, 0&, "msctls_statusbar32", vbNullString)
Do While hwndStBr = 0
    hwndStBr = FindWindowEx(hwndPHD, 0&, "msctls_statusbar32", vbNullString)
'Display the first panel
lblWinCaption.Caption = GetText(hwndStBr)
nCount = SendMessage(hwndStBr, SB_GETPARTS, 0, ByVal 0&)        'Ok, this works
lblWinCaption.Caption = nCount
ReDim SBText(nCount - 1)
sTemp = String(dwSize, 0)
If IsWindowsNT Then 'WinNT staff
      lpSysShared = GetMemSharedNT(pid, dwSize, hProcess)
      WriteProcessMemory hProcess, ByVal lpSysShared, ByVal sTemp, dwSize, lWritten
      For i = 0 To nCount - 1
          lRet = SendMessage(hwndStBr, SB_GETTEXT, i, ByVal lpSysShared)    'lRet = number of characters returned
          If lRet Then
             ReadProcessMemory hProcess, ByVal lpSysShared, ByVal sTemp, dwSize, lWritten
             SBText(i) = Left(sTemp, (lRet And &HFFFF&))        'This is just empty squares, where is the real text?
          End If
      Next i
      FreeMemSharedNT hProcess, lpSysShared, dwSize
   Else  'Win9x staff
        lpSysShared = GetMemShared95(dwSize, hFileMapping)
        CopyMemory ByVal lpSysShared, ByVal sTemp, dwSize
        For i = 0 To nCount - 1
            lRet = SendMessage(hwndStBr, SB_GETTEXT, ByVal i, ByVal lpSysShared) 'This crashes PhD...
            If lRet Then
                CopyMemory ByVal sTemp, ByVal lpSysShared, dwSize
                   SBText(i) = Left(sTemp, (lRet And &HFFFF&))
            End If
        Next i
        FreeMemShared95 hFileMapping, lpSysShared
End If
lblWinCaption.Caption = SBText(nCount - 1)
End Sub

Open in new window

Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®


Some additional input: I changed the sTemp = String(dwSize, 0) to sTemp = String(dwSize, "A") and re-ran the code above. This time I am getting all "A"s in sTemp after the ReadProcessMemory.
This tells me the WriteProcessMemory and ReadProcessMemory functions work but the SendMessage(hwndStBr, SB_GETTEXT, i, byVal lpSysShared) function does not put the content of the pane #i into the shared memory.
Any ideas?
Author of the Year 2009
One possibility is that the targetted status bar is  owner-draw .  As it states here:

     SB_GETTEXT Message
>>If the text has the SBT_OWNERDRAW drawing type, this message returns the 32-bit value associated with the text instead of the length and operation type.
In that case, your lRet value will not be a length value.  Also, it's not clear that the buffer will be filled with valid data in that case, either.
I suggest that you try this procedure on a few other windows, such as WordPad.Exe
Author of the Year 2009
The legendary Ark provided a good description of the SBT_OWNERDRAW situation here:


DanRollins, thank you for the inputs.
I tried both and none worked
1. This does not appear to be a case of SBT_OWNERDRAW as the test is negative. I copied Ark's code you linked to and it does not get into that path
2. I tried using WordPad and my code reports the correct number of panes (3) but again sTemp is not being overwritten by the SendMessage function. The starnge thing is that lret has the correct value, ie the number of characters.
Found the problem !
Reasoning that there was something wrong with the allocated memory, I went over the differences between my code and another code from Ark that I had tried and found working (the Desktop Shuffle demo he wrote back in 2002).  I found a missing statement related to the thread Id (GetWindowThreadProcessId) which outputs the ProcessID used in the memory allocation function.
Adding the statement back in resulted in the code working and I am now a very happy camper.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial