Private Declare Function SendMessageLong Lib "user32" _
Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam
As Long, _
ByVal lParam As Long) As Long
Private Declare Function SendMessageStr Lib "user32" _
Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As
Long, _
ByVal lParam As String) As Long
Private Const LB_GETTEXT = &H189
Private Const LB_GETCOUNT = &H18B
Sub test()
Dim r As Long
Dim i As Long
Dim maxItems As Long
Dim listStr As String
Dim lLBhwnd As Long
lLBhwnd = 7275646
maxItems = SendMessageLong(lLBhwnd, LB_GETCOUNT, 0, 0)
For i = 0 To maxItems - 1
listStr = Space$(64)
r = SendMessageStr(lLBhwnd, LB_GETTEXT, i, listStr)
If r > 0 Then
MsgBox Left$(listStr, r)
End If
Next
End Sub
Would there be a way to get the readable data?
RBS
Not with these APIs. These listboxes are "ownerdrawn", which means, the real
text can be anywhere in any way in the process memory. Try to use the
Accessibility API.
Juergen.
RBS
"Juergen Thuemmler" <th...@removethisgmx.de> wrote in message
news:OHQh2Gd9...@TK2MSFTNGP14.phx.gbl...
RBS
"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message
news:%23Gb4zKd...@TK2MSFTNGP12.phx.gbl...
Start with "AccessibleObjectFromPoint()" in MSDN.
Juergen.
RBS
"Juergen Thuemmler" <th...@removethisgmx.de> wrote in message
news:eoPtMsd...@TK2MSFTNGP09.phx.gbl...
It can read quite a few controls, but unfortunately, it can't read the
listbox items and it comes out as question marks.
Apart from the above article I haven't found much that applies to VB.
Any other suggestions?
RBS
"Juergen Thuemmler" <th...@removethisgmx.de> wrote in message
news:eoPtMsd...@TK2MSFTNGP09.phx.gbl...
> Apart from the above article I haven't found much that applies to VB.
The IAccessible interface functions apply to VB just like any other API
functions: Use it or not.
> Any other suggestions?
No.
Juergen.
RBS
"Juergen Thuemmler" <th...@removethisgmx.de> wrote in message
news:O9LVLYg9...@TK2MSFTNGP10.phx.gbl...
You can't hard code a window handle. A window handle may be different any
time the window is created.
--
----------------------------------------------------------------------
THORSTEN ALBERS Universität Freiburg
albers@
uni-freiburg.de
----------------------------------------------------------------------
Reading data from a listbox in another process can be tricky.
- Kev
"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message
news:OceikAd9...@TK2MSFTNGP12.phx.gbl...
1) Really important this is bad,bad,bad
lLBhwnd = 7275646
You MUST get the handle every time, it will change.
2) Add a ByVal in the right place:
r = SendMessageStr(lLBhwnd, LB_GETTEXT, i, BYVAL listStr)
That should do the job - works for me.
Best Regards
Dave O.
"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message
news:OceikAd9...@TK2MSFTNGP12.phx.gbl...
This suggests to me a Unicode conversion problem.
Regards
Dave O.
> > Private Declare Function SendMessageStr Lib "user32" _
> > Alias "SendMessageA" _
> > (ByVal hwnd As Long, _
> > ByVal wMsg As Long, ByVal
wParam
> > As Long, _
************
> > ByVal lParam As String) As Long
************
Cited, but not read, eh?
It's fair enough, hWnd, wMsg and wParam are all declared ByVal but don't
*need* the "ByVal" in the call while the lParam does, how is anybody
supposed to know that without experience?
Best Regards
Dave O.
Yes, I know that, but this is just to keep the posting simple.
RBS
"Thorsten Albers" <albe...@MOVEuni-freiburg.de> wrote in message
news:01c5f60d$4d744380$978ee684@thaldesk...
RBS
"Kevin Provance" <ca...@tpasoft.com> wrote in message
news:OzFOr%23g9FH...@TK2MSFTNGP14.phx.gbl...
Know that, just tried to simplify the posting.
Will try your suggestion.
RBS
"Dave" <nob...@nowhere.com> wrote in message
news:urmD%23yl9F...@TK2MSFTNGP14.phx.gbl...
Hard to tell from the thread if you're still having issues with this. But I
wrote this long ago, and it works great for standard listboxes:
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA"
(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As
Any) As Long
Private Const LB_GETTEXT = &H189
Private Const LB_GETTEXTLEN = &H18A
Private Const LB_GETCOUNT = &H18B
Private Const LB_ERR = (-1)
' Within some routine, assuming you have a valid hWnd...
Dim nCount As Long, i As Long
Dim TxtLen As Long
Dim Buffer As String
nCount = SendMessage(hWnd, LB_GETCOUNT, 0&, ByVal 0&)
If nCount <> LB_ERR Then
For i = 0 To nCount - 1
TxtLen = SendMessage(hWnd, LB_GETTEXTLEN, i, ByVal 0&)
If Len(Buffer) < (TxtLen + 1) Then
Buffer = Space$(TxtLen + 1)
End If
If SendMessage(hWnd, LB_GETTEXT, i, ByVal Buffer) <> LB_ERR Then
Debug.Print Left$(Buffer, TxtLen)
End If
Next i
End If
Later... Karl
--
Working without a .NET?
http://classicvb.org/
RBS
"Karl E. Peterson" <ka...@mvps.org> wrote in message
news:%23aPTJGq...@tk2msftngp13.phx.gbl...
Hmmmm.
> I suppose it just isn't a standard Windows listbox.
You looked at it with Spy++? Seems the next step is to determine *what*,
exactly, it is.
I tend to buy into the Unicode theory. How about converting those
instructions for that?
Sorry... Karl
I don't have anyway to test this (unless you can point me to a commonly
available unicode listbox?), but I wonder how this might work?
Private Declare Function IsWindowUnicode Lib "user32" (ByVal hWnd As
Long) As Long
Dim nCount As Long, i As Long
Dim Buffer() As Byte
Dim TxtLen As Long
' Initialize buffer
ReDim Buffer(1 To 1024) As Byte
' Attempt to read chosen listbox.
nCount = SendMessage(m_hWnd, LB_GETCOUNT, 0&, ByVal 0&)
If nCount <> LB_ERR Then
For i = 0 To nCount - 1
' Ensure adequate buffer
TxtLen = SendMessage(m_hWnd, LB_GETTEXTLEN, i, ByVal 0&)
If UBound(Buffer) < ((TxtLen + 1) * 2) Then
ReDim Buffer(1 To ((TxtLen + 1) * 2)) As Byte
End If
' Read this entry
If TxtLen Then
If SendMessage(m_hWnd, LB_GETTEXT, i, Buffer(1)) <> LB_ERR Then
If IsWindowUnicode(hWnd) Then
Debug.Print Left$(StrConv(Buffer, vbFromUnicode), TxtLen)
Else
Debug.Print Left$(StrConv(Buffer, vbUnicode), TxtLen)
End If
End If
End If
Next i
End If
Thanks... Karl
I am not much familiar with the API, what should I particularly look at with
Spy++?
RBS
"Karl E. Peterson" <ka...@mvps.org> wrote in message
news:ehbBerq9...@TK2MSFTNGP14.phx.gbl...
> I don't have anyway to test this (unless you can point me to a commonly
> available unicode listbox?), but I wonder how this might work?
as I said already, the garbled text "割A `" is typically for an owner drawn
listbox, and I don't know any (common valid) method to get the real text.
Juergen.
When I look this up in Appleman's book I see:
Used for list boxes drawn under program control. Not usable under VB without
third
party support.
Still haven't given up on this though.
RBS
"Juergen Thuemmler" <th...@removethisgmx.de> wrote in message
news:erLcGMr9...@TK2MSFTNGP15.phx.gbl...
As Kevin already has pointed out: "Reading data from a listbox in another
process can be tricky". You don't have access to the memory of the process.
Exactly. And this "third party" is the programmer of this program.
> Still haven't given up on this though.
Well; try to find and ask this programmer, where and how to find the desired
informations ;-)
Juergen.
It doesn't matter whether the list box is owner drawn or not since this
only has a meaning for the drawing of the list box contents. The style that
matters in your case is LBS_HASSTRINGS. If the list doesn't have this
style, you don't have any chance to get the strings - with one exception:
You could try it with optical character recognition...
Little chance with that!
I can though with the Windows API get the index of the item and there is an
API for this program that can be used in VB. Still, it doesn't look I can
get the text of the listbox item.
RBS
"Juergen Thuemmler" <th...@removethisgmx.de> wrote in message
news:eVkGrcr9...@TK2MSFTNGP12.phx.gbl...
RBS
"Thorsten Albers" <albe...@MOVEuni-freiburg.de> wrote in message
news:01c5f6b7$303ed780$8d8ee684@thaldesk...
> It doesn't matter whether the list box is owner drawn or not since this
> only has a meaning for the drawing of the list box contents. The style
> that
> matters in your case is LBS_HASSTRINGS. If the list doesn't have this
> style, you don't have any chance to get the strings - with one exception:
you are right. But I've never seen any listbox which has both
LBS_OWNERDRAWN??? and LBS_HASSTRINGS together, therefore I'd set
LBS_OWNERDRAWN??? = Not LBS_HASSTRINGS.
Juergen.
Public Function AOLGetListByIndex(hWnd As Long, lIndex As Long) As String
'Last edited March 19, 2002
Dim lProcess As Long
Dim ListItemHold As Long
Dim ListPersonHold As Long
Dim ReadBytes As Long
Dim lProcessThread As Long
Dim sPerson As String
'The hWnd should be the handle of the listbox itself, and not the actual app
GetWindowThreadProcessId hWnd, lProcess
lProcessThread = OpenProcess(PROCESS_VM_READ Or STANDARD_RIGHTS_REQUIRED,
False, lProcess)
If lProcessThread Then
Person$ = String$(4, vbNullChar)
ListItemHold = SendMessage(hWnd, LB_GETITEMDATA, ByVal CLng(lIndex),
ByVal 0&)
'You may have to toy with the number in this line,
'I cycled up to 28 before I found the data I needed
ListItemHold = ListItemHold + 28
ReadProcessMemory lProcessThread, ListItemHold, Person$, 4, ReadBytes
RtlMoveMemory ListPersonHold, ByVal sPerson, 4
ListPersonHold = ListPersonHold + 6
'Adjust this buffer as necessary. AOL screen names are only 16
character
'as of this posting, and I set my buffer accordingly.
sPerson = String$(16, vbNullChar)
ReadProcessMemory lProcessThread, ListPersonHold, sPerson, Len(sPerson),
ReadBytes
sPerson= Trim$(Left$(sPerson, InStr(sPerson, vbNullChar) - 1))
CloseHandle lProcessThread
End If
AOLGetListByIndex = Trim(sPerson)
End Function
Hope this helps.
- Kev
"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message
news:eMFnUjr9...@TK2MSFTNGP12.phx.gbl...
Yeah, I hear ya there. It all seemed to get confused when the references to
a "string of question marks" came out. If it's owner-drawn, he's probably
hosed.
RBS
"Kevin Provance" <ca...@tpasoft.com> wrote in message
news:%235W9wtr...@TK2MSFTNGP11.phx.gbl...
Is it possible to convert the garbled text in a function, comparing the
English output and the garbled text, assuming someone could figure out
how to write the decoding function?
Mike
It is very possible that a Listbox both has strings and is owner drawn
- consider something where one just wants to add an Icon before the
string
?BC �h&E x
苺? x
�
蚤v
@.C � v
�? `
(hv
�C `
` C
( C
媊r �? @
x潎 `
83E `
`gv `
X溛
溛
Ov
X苹
RBS
"mscir" <ms...@yahoo.com> wrote in message
news:ptudnbaRTLc...@pghconnect.com...
> Karl E. Peterson wrote:
>> Juergen Thuemmler wrote:
>>
>>>Karl,
>>>>I don't have anyway to test this (unless you can point me to a
>>>>commonly available unicode listbox?), but I wonder how this might
>>>>work?
>>>
>>>as I said already, the garbled text "賃A `" is typically for an owner
Then you don't have a chance unless you try to work out the format of the
data stored along with the list as Kevin has done. But this will only work
a) if the item data of each of the list entries is a pointer to the
respective data, and
b) the data is not to complex.
For a): E.g. with an ownerdrawn list box without strings it is not unusual
that an array of structures is hold in memory and the item data of the list
items just holds the array index. Since you don't know anything about the
array you can't get the contents of one of the array items with the array
index from the item.
For b): If e.g. the item data of each of the list items indeed holds a
pointer to the data, and if the data is e.g. a structure with a pointer to
a second structure which holds the pointer to the string, it will be not
really easy to work out the address of the strings.
Yes, of course, but then you don't get a "garbled" text...
Juergen.
Option Explicit
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" (ByVal hwnd As
Long, _
ByVal wMsg As
Long, _
ByVal wParam As
Long, _
lParam As Any) As
Long
Private Const LB_GETTEXT = &H189
Private Const LB_GETTEXTLEN = &H18A
Private Const LB_GETCOUNT = &H18B
Private Const LB_ERR = (-1)
Private Const LB_GETITEMDATA = &H199
Private Declare Function IsWindowUnicode Lib "user32" (ByVal hwnd As Long)
As Long
Private Declare Function GetWindowThreadProcessId _
Lib "user32" (ByVal hwnd As Long, _
lpdwProcessId As Long) As Long
Private Const PROCESS_VM_READ = 16
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Declare Function OpenProcess _
Lib "Kernel32.dll" (ByVal dwDesiredAccessas As
Long, _
ByVal bInheritHandle As Long,
_
ByVal dwProcId As Long) As
Long
Private Declare Function ReadProcessMemory _
Lib "kernel32" (ByVal hProcess As Long, _
lpBaseAddress As Any, _
lpBuffer As Any, _
ByVal nSize As Long, _
lpNumberOfBytesWritten As Long) As
Long
Private Declare Sub CopyMemory _
Lib "kernel32" _
Alias "RtlMoveMemory" (pDst As Any, _
pSrc As Any, _
ByVal ByteLen As Long)
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long)
As Long
Function AOLGetListByIndex(lhwnd As Long, lIndex As Long) As String
'Last edited March 19, 2002
Dim lProcess As Long
Dim ListItemHold As Long
Dim ListPersonHold As Long
Dim ReadBytes As Long
Dim lProcessThread As Long
Dim sPerson
Dim i As Long
Dim n As Long
Dim lReturn As Long
On Error GoTo ERROROUT
'The hWnd should be the handle of the listbox itself, and not the actual
app
GetWindowThreadProcessId lhwnd, lProcess
lProcessThread = OpenProcess(PROCESS_VM_READ Or
STANDARD_RIGHTS_REQUIRED, False, lProcess)
If lProcessThread Then
For i = 0 To 300
sPerson = String(300, vbNullChar)
ListItemHold = SendMessage(lhwnd, LB_GETITEMDATA, ByVal
CLng(lIndex), ByVal 0&)
If i = 0 Then
'MsgBox ListItemHold, , "ListItemHold"
End If
'You may have to toy with the number in this line,
'I cycled up to 28 before I found the data I needed
ListItemHold = ListItemHold + i
For n = 0 To 300
lReturn = ReadProcessMemory(lProcessThread, ListItemHold,
sPerson, n, ReadBytes)
If Mid$(sPerson, 5, 1) <> vbNullChar Then
MsgBox sPerson
MsgBox lReturn, , "i: " & i & " " & "n: " & n
Exit For
End If
Next
Next
CloseHandle lProcessThread
Exit Function
CopyMemory ListPersonHold, ByVal sPerson, 4
ListPersonHold = ListPersonHold + 6
'Adjust this buffer as necessary. AOL screen names are only 16
character
'as of this posting, and I set my buffer accordingly.
sPerson = String(60, vbNullChar)
ReadProcessMemory lProcessThread, ListPersonHold, sPerson,
Len(sPerson), ReadBytes
sPerson = Trim$(Left$(sPerson, InStr(sPerson, vbNullChar) - 1))
CloseHandle lProcessThread
End If
AOLGetListByIndex = Trim(sPerson)
Exit Function
ERROROUT:
MsgBox Err.Number & _
vbCrLf & _
Err.Description, , ""
On Error GoTo 0
End Function
Sofar haven't got any output yet at MsgBox sPerson
What does ListItemHold do? Could it be that I have to reduce this number
rather than increase it?
Any suggestions what to try next?
RBS
"Kevin Provance" <ca...@tpasoft.com> wrote in message
news:%235W9wtr...@TK2MSFTNGP11.phx.gbl...
>
>It doesn't matter whether the list box is owner drawn or not since this
>only has a meaning for the drawing of the list box contents. The style that
>matters in your case is LBS_HASSTRINGS. If the list doesn't have this
>style, you don't have any chance to get the strings - with one exception:
>You could try it with optical character recognition...
FWIW, here's a twist on that: Drop a VB ListBox (normal - not checkbox
style) control on a form and check it's style. No LBS_HASSTRINGS, but
it implements LB_GETTEXT just the same.
-Tom
MVP - Visual Basic
(please post replies to the newsgroup)
That's because the own window procedure of the VB ListBox handles the
LB_GETTEXT and doesn't let the default window procedure of the window class
"List" handle it.
The reason for this presumably is that the VB ListBox >may have< the
checkbox style.
"If you create the list box with an owner-drawn style but without the
LBS_HASSTRINGS style, the buffer pointed to by the lpszBuffer parameter
will receive the 32-bit value associated with the item (the item data)."
The text is garbled because it isn't text...
Excel, huh?! Why didn't you say so earlier? That's actually common enough,
or so I've heard, that it's likely a coupla us here might just have it
installed and able to take a look at the specific list. Mighta saved a few
posts.
RBS
"Karl E. Peterson" <ka...@mvps.org> wrote in message
news:OjZ2Cet...@TK2MSFTNGP15.phx.gbl...
Ahhhhh. Never mind. <g>
RBS
"Karl E. Peterson" <ka...@mvps.org> wrote in message
news:OkY0Bst...@TK2MSFTNGP12.phx.gbl...
Private Declare Function ReadProcessMemory Lib "Kernel32" (ByVal hProcess As
Long, ByVal lpBaseAddress As Long, ByVal lpBuffer As String, ByVal nSize As
Long, ByRef lpNumberOfBytesWritten As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd
As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "Kernel32" (ByVal dwDesiredAccess
As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "Kernel32" (ByVal hObject As Long)
As Long
Private Declare Sub RtlMoveMemory Lib "Kernel32" (ByRef dest As Any, ByRef
Source As Any, ByVal nBytes As Long)
Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
'Yours is 16? I don't think that is right.
Private Const PROCESS_VM_READ As Long = &H10
Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000
"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message
news:eRUVl9s9...@TK2MSFTNGP14.phx.gbl...
RBS
"Kevin Provance" <ca...@tpasoft.com> wrote in message
news:OFd8XFu9...@TK2MSFTNGP09.phx.gbl...
: 'Yours is 16? I don't think that is right.
: Private Const PROCESS_VM_READ As Long = &H10
&H10 = 16 decimal.
--
Randy Birch
MS MVP Visual Basic
http://vbnet.mvps.org/
----------------------------------------------------------------------------
Read. Decide. Sign the petition to Microsoft.
http://classicvb.org/petition/
----------------------------------------------------------------------------
>The reason for this presumably is that the VB ListBox >may have< the
>checkbox style.
Yeah, something like that. It also coughs up the item text for
LB_GETTEXT for the checkbox / OD style, which means it uses it's
custom handler either way.
Three days of packing to move to a new house...so tired....missed the Hex.
- Kev
"Randy Birch" <rgb_rem...@mvps.org> wrote in message
news:upNjTpu9...@TK2MSFTNGP09.phx.gbl...
I've written a "hackish" example (few Const-Declares and comments) some time
ago, to read out the Columns of a ListView-Control from an external Process
(FileMon from Sysinternals).
The Main-Problem is, that you need to deal correctly with the
ReadProcessMemory/WriteProcessMemory-APIs.
Anyway - here's the link:
http://tinyurl.com/a7b6j
Try, to get this to work first (with FileMon), before you adapt the code to
your problem.
HTH
Olaf
No wonder you are having problems, it is NOT a listbox but a LISTVIEW. a
completely different animal.
None of the code you have been supplied with will work for ListViews,
everybody has been helping you on the asumption that you had a listbox
there. A similar call for a Listview needs to know which column you want to
read from as well as the item index.
The listview control with columns and stuff is part of the Common Controls.
Start this thread again but this time use the word Listview in the title,
I'm sure you will get a response that will sort your problem for you.
Best Regards
Dave O.
"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message
news:%23IjeWms...@TK2MSFTNGP12.phx.gbl...
Dave O.
RBS posted the listbox to have LBS_OWNERDRAWVARIABLE style, so it IS a
listtbox.
Juergen.
RBS
"Dave" <nob...@nowhere.com> wrote in message
news:eZMMwzy...@TK2MSFTNGP10.phx.gbl...
RBS
"Schmidt" <s...@online.de> wrote in message
news:Oy$56uy9F...@tk2msftngp13.phx.gbl...
RBS
"Schmidt" <s...@online.de> wrote in message
news:Oy$56uy9F...@tk2msftngp13.phx.gbl...
>
> As your code is for a listview will it apply to my listbox?
No (if it's really a ListBox), especially the code that deals with the
SubItems.
If the windowclass says it's a "ListBox", than it seems to be "very
ownerdrawn" (7 Columns + probably a homegrown Col-Header) - something that's
usually implemented using a "SysListView32".
Looks like your chances getting this thing to work, are very limited.
Olaf
What leads you to this assumption?
The garbled text is not "only about 5 characters": It is 64 characters
because this is the amount of characters you have dimensioned the string
("listStr = Space$(64)"). If only 5 characters are getting printed, the 6th
character is a Null byte
Since your list box hasn't the listbox class style LBS_HASSTRINGS only the
first 4 of the 5 characters really do have a meaning (= item data of the
respective list item; ""If you create the list box with an owner-drawn
style but without the LBS_HASSTRINGS style, the buffer pointed to by the
lpszBuffer parameter will receive the 32-bit value associated with the item
(the item data)").
Instead of
r = SendMessageStr(lLBhwnd, LB_GETTEXT, i, listStr)
you should use
pData = SendMessage(lLBhwnd, LB_GETITEMDATA, i, 0)
and
Debug.Print Hex$(pData)
> This is an example output for all the listbox items:
> ?BC �> h&E x
> ミ」? x
> 、?
> ーDv
> @.C �> v
> �? `
> (hv
> �C `
> ` C
> ( C
> リトr �...
We know that these garbage strings must be the item data value of the
respective list item; therefore only the first 4 characters do matter
because the item data is a DWORD value.
> ?BC
> h&E
> ミ」?
> 、?
> ーDv
> @.C
> v
> �?
> (hv
> �C
> ` C
> ( C
> リトr
...
The first character is the low byte of the low word of the DWORD item data
value, the 4th character is the high byte of the high word. This high byte
seems to be the same with all list items, assuming that the box character
has the same character code with all items.
Assuming that the control which you have used to display the 'garbage' is
set to MS Sans Serif there are only some box characters: 7Fh to 81h, 8Dh to
90h, and 9Dh to 9Eh.
Such a character code very well could be the high byte of the high word of
a DWORD pointer. I would bet that the character code of the box character
was 7Fh and that these 'garbage' strings indeed are pointers �la
7Fxxxxxx
7Fxxxxxx
7Fxxxxxx
...
addressing memory in a virtual address space of 2 GB (memory allocation
always starts at the highest available address).
To prove that these are pointers get the item data of the list items as
suggested above and post the sequence of some of the hexadecimal values
here in this grooup. Together we should be able to work out if they indeed
are pointers and, if so, to what kind of data they are pointing.
Some hints:
- If the item data consists of relatively low numbers (0 ...) increased
from the one to the next always by the same offset, the presumably are
array index numbers. If so, forget about to get the strings.
- If the item data consists of relatively high numbers like
7xxxxxxx
6xxxxxxx
5xxxxxxx
it is very likely that we have pointers to the list item data.
Check, if the offset from one value to the next is >always the same<. If
so, it is even more likely that we have pointers to the list item data.
At this point it is necessary to know the offset from one value to the
other:
a) If it is 4, the pointers are likely to be pointers to pointers.
b) If it is <> 4, the pointers are likely to be pointers to an array of
structures with each of the pointers pointing to the respective array item
structure.
a)
Item data (pData)
1 7xxxxxxx
2 7xxxxxxx (= 1 + 4)
3 7xxxxxxx (= 2 + 4)
4 7xxxxxxx (= 3 + 4)
b)
Item data (pData)
1 7xxxxxxx
2 7xxxxxxx (= 1 + n <> 4)
3 7xxxxxxx (= 2 + n <> 4)
4 7xxxxxxx (= 3 + n <> 4)
With a):
- Read the value to which the respective item data value seems to point
pNew = 4 Bytes from memory starting at pData
- Try to identify the values of pNew the same way you have tried to
identify the values of pData; if the offset of these is <> 4 proceed as
shown for b)
With b):
If the offset from pData(n) to pData(n + 1) is always the same and <> 4,
the offset presumably gives the size of the structure. So, make a memory
dump of the data to which pData seems to point, lets say for the first 10
list items.
If all assumptions have been correct so far, i.e. if we really are dealing
with an array of structures, with these memory dumps it should be not too
difficult to work out the meaning of at least some of the structure fields.
Again you could try to classify structure fields as pointers by checking
their values (like we have done above) and the offsets from value to value.
If the one or the other field seems to hold a pointer, it presumably is a
string pointer; check it by reading some bytes from the memory to which the
assumed pointer points.
> The listbox has 7 columns, 1 for an icon and 6 with strings.
> The number of charaters in all these 6 strings together can come up to
about
> 300 characters.
Judging from this it is likely that
- the item data of each one of the list items is a pointer to a structure,
and that
- each structure has at least
a) either one string pointer pointing to a string that holds all 6
displayed strings separated by some kind of a separator (Null byte,
tabulator, or the like)
or 6 string pointers pointing to the respective displayed string, and
b) an icon handle
If you want to try this approach, remember that the memory is owned by
another application, i.e. that you can't use CopyMemory() but have to the
way of reading the memory Kevin has shown you.
--
----------------------------------------------------------------------
THORSTEN ALBERS Universit舩 Freiburg
albers@
uni-freiburg.de
----------------------------------------------------------------------
Thanks for that thorough reply.
Will see if I can follow your suggestions and post some output back. I
figured out a way
now to always get the right hwnd of this listbox programmatically, so that
will help.
RBS
"Thorsten Albers" <albe...@MOVEuni-freiburg.de> wrote in message
news:01c5f76a$b649a180$LocalHost@thaldesk...
Sub test()
Dim nCount As Long
Dim i As Long
Dim TxtLen As Long
Dim Buffer As String
Dim hWnd As Long
Dim pData As Long
hWnd = GetMedicationLBhwnd()
nCount = SendMessage(hWnd, LB_GETCOUNT, 0&, ByVal 0&)
If nCount <> LB_ERR Then
For i = 0 To nCount - 1
TxtLen = SendMessage(hWnd, LB_GETTEXTLEN, i, ByVal 0&)
If Len(Buffer) < (TxtLen + 1) Then
Buffer = Space$(TxtLen + 1)
End If
pData = SendMessage(hWnd, LB_GETITEMDATA, i, 0)
Debug.Print Hex$(pData)
Next i
End If
End Sub
I get this output:
34E2978
34E1DD0
175B2E8
175B400
175B748
175B3C8
17593A0
175B320
175B358
175B390
1737F38
175B438
175B470
34E62B8
17263C8
34EAEC0
1737D08
1738050
Will now study your further text.
RBS
"Thorsten Albers" <albe...@MOVEuni-freiburg.de> wrote in message
news:01c5f76a$b649a180$LocalHost@thaldesk...
http://www.jsware.net/jsware/vbcode.php3#acc
--
mayaya...@mindXXspring.com
(Remove Xs for return email.)
RB Smissaert <bartsm...@blueyonder.co.uk> wrote in message
news:OceikAd9...@TK2MSFTNGP12.phx.gbl...
> Trying to get the text of items in a listbox of an external application.
> This code will get me some data, but it is in non-readable form like this:
> 割A `
>
> Private Declare Function SendMessageLong Lib "user32" _
> Alias "SendMessageA" _
> (ByVal hwnd As Long, _
> ByVal wMsg As Long, ByVal wParam
> As Long, _
> ByVal lParam As Long) As Long
>
> Private Declare Function SendMessageStr Lib "user32" _
> Alias "SendMessageA" _
> (ByVal hwnd As Long, _
> ByVal wMsg As Long, ByVal wParam
As
> Long, _
> ByVal lParam As String) As Long
>
> Private Const LB_GETTEXT = &H189
> Private Const LB_GETCOUNT = &H18B
>
> Sub test()
>
> Dim r As Long
> Dim i As Long
> Dim maxItems As Long
> Dim listStr As String
> Dim lLBhwnd As Long
>
> lLBhwnd = 7275646
>
> maxItems = SendMessageLong(lLBhwnd, LB_GETCOUNT, 0, 0)
>
> For i = 0 To maxItems - 1
> listStr = Space$(64)
> r = SendMessageStr(lLBhwnd, LB_GETTEXT, i, listStr)
> If r > 0 Then
> MsgBox Left$(listStr, r)
> End If
> Next
>
> End Sub
>
>
> Would there be a way to get the readable data?
>
>
> RBS
>
>
>
That looks very promising! Go grab my HexDump module, to poke around at
those addresses, and see what's there. (http://vb.mvps.org/samples/HexDump)
RBS
"Karl E. Peterson" <ka...@mvps.org> wrote in message
news:uMLqDT39...@TK2MSFTNGP14.phx.gbl...
55454072 -2984
55451088 -30960360
24490728 280
24491008 840
24491848 -896
24490952 -8232
24482720 8064
24490784 56
24490840 56
24490896 -144472
24346424 144640
24491064 56
24491120 30977608
55468728 -31194864
24273864 31214328
55488192 -31142328
24345864 840
24346704 -24346704
So it doesn't look these are indices of array elements, so that must be
good.
The 2 first elements represent unopened (kind of) folders in this listbox as
are the last 2.
So these are not the strings I am trying to get at.
Maybe the last 2 items in the listbox (also unopened folders) are in fact
55468728
and 55488192 in the list above.
I am not sure now how to get from the above numbers or the hexadecimal
numbers to the
strings I am after.
RBS
"Karl E. Peterson" <ka...@mvps.org> wrote in message
news:uMLqDT39...@TK2MSFTNGP14.phx.gbl...
Sub test()
Dim nCount As Long
Dim i As Long
Dim TxtLen As Long
Dim Buffer As String
Dim hWnd As Long
Dim pData As Long
hWnd = GetMedicationLBhwnd()
nCount = SendMessage(hWnd, LB_GETCOUNT, 0&, ByVal 0&)
If nCount <> LB_ERR Then
For i = 0 To nCount - 1
TxtLen = SendMessage(hWnd, LB_GETTEXTLEN, i, ByVal 0&)
If Len(Buffer) < (TxtLen + 1) Then
Buffer = Space$(TxtLen + 1)
End If
pData = SendMessage(hWnd, LB_GETITEMDATA, i, 0)
Debug.Print HexDump(pData, 256)
Next i
End If
End Sub
lpBuffer = &h175B358 nBytes = 256
0175B358 0000 61 00 76 00 65 00 20 00-62 00 65 00 65 00 6E 00 a.v.e.
.b.e.e.n.
0175B368 0010 20 00 63 00 68 00 61 00-6E 00 67 00 65 00 64 00
.c.h.a.n.g.e.d.
0175B378 0020 20 00 77 00 69 00 74 00-68 00 69 00 6E 00 20 00
.w.i.t.h.i.n. .
0175B388 0030 74 00 68 00 65 00 20 00-6C 00 61 00 73 00 74 00 t.h.e.
.l.a.s.t.
0175B398 0040 20 00 25 00 6C 00 64 00-20 00 64 00 61 00 79 00 .%.l.d.
.d.a.y.
0175B3A8 0050 73 00 3B 00 20 00 64 00-6F 00 65 00 73 00 20 00 s.;.
.d.o.e.s. .
0175B3B8 0060 6E 00 6F 00 74 00 20 00-63 00 6F 00 6E 00 74 00 n.o.t.
.c.o.n.t.
0175B3C8 0070 61 00 69 00 6E 00 20 00-79 00 6F 00 75 00 72 00 a.i.n.
.y.o.u.r.
0175B3D8 0080 20 00 61 00 63 00 63 00-6F 00 75 00 6E 00 74 00
.a.c.c.o.u.n.t.
0175B3E8 0090 20 00 6F 00 72 00 20 00-66 00 75 00 6C 00 6C 00 .o.r.
.f.u.l.l.
0175B3F8 00A0 20 00 6E 00 61 00 6D 00-65 00 3B 00 20 00 63 00
.n.a.m.e.;. .c.
0175B408 00B0 6F 00 6E 00 74 00 61 00-69 00 6E 00 73 00 20 00
o.n.t.a.i.n.s. .
0175B418 00C0 61 00 74 00 20 00 6C 00-65 00 61 00 73 00 74 00 a.t.
.l.e.a.s.t.
0175B428 00D0 20 00 74 00 68 00 72 00-65 00 65 00 20 00 6F 00
.t.h.r.e.e. .o.
0175B438 00E0 66 00 20 00 74 00 68 00-65 00 20 00 66 00 6F 00 f. .t.h.e.
.f.o.
0175B448 00F0 6C 00 6C 00 6F 00 77 00-69 00 6E 00 67 00 20 00
l.l.o.w.i.n.g. .
=================================================================================
=================================================================================
lpBuffer = &h175B390 nBytes = 256
0175B390 0000 6C 00 61 00 73 00 74 00-20 00 25 00 6C 00 64 00 l.a.s.t.
.%.l.d.
0175B3A0 0010 20 00 64 00 61 00 79 00-73 00 3B 00 20 00 64 00
.d.a.y.s.;. .d.
0175B3B0 0020 6F 00 65 00 73 00 20 00-6E 00 6F 00 74 00 20 00 o.e.s.
.n.o.t. .
0175B3C0 0030 63 00 6F 00 6E 00 74 00-61 00 69 00 6E 00 20 00
c.o.n.t.a.i.n. .
0175B3D0 0040 79 00 6F 00 75 00 72 00-20 00 61 00 63 00 63 00 y.o.u.r.
.a.c.c.
0175B3E0 0050 6F 00 75 00 6E 00 74 00-20 00 6F 00 72 00 20 00 o.u.n.t.
.o.r. .
0175B3F0 0060 66 00 75 00 6C 00 6C 00-20 00 6E 00 61 00 6D 00 f.u.l.l.
.n.a.m.
0175B400 0070 65 00 3B 00 20 00 63 00-6F 00 6E 00 74 00 61 00 e.;.
.c.o.n.t.a.
0175B410 0080 69 00 6E 00 73 00 20 00-61 00 74 00 20 00 6C 00 i.n.s.
.a.t. .l.
0175B420 0090 65 00 61 00 73 00 74 00-20 00 74 00 68 00 72 00 e.a.s.t.
.t.h.r.
0175B430 00A0 65 00 65 00 20 00 6F 00-66 00 20 00 74 00 68 00 e.e. .o.f.
.t.h.
0175B440 00B0 65 00 20 00 66 00 6F 00-6C 00 6C 00 6F 00 77 00 e.
.f.o.l.l.o.w.
0175B450 00C0 69 00 6E 00 67 00 20 00-66 00 6F 00 75 00 72 00 i.n.g.
.f.o.u.r.
0175B460 00D0 20 00 63 00 68 00 61 00-72 00 61 00 63 00 74 00
.c.h.a.r.a.c.t.
0175B470 00E0 65 00 72 00 20 00 67 00-72 00 6F 00 75 00 70 00 e.r.
.g.r.o.u.p.
0175B480 00F0 73 00 3A 00 20 00 45 00-6E 00 67 00 6C 00 69 00 s.:.
.E.n.g.l.i.
=================================================================================
=================================================================================
lpBuffer = &h1737F38 nBytes = 256
01737F38 0000 40 40 04 04 04 04 04 04-04 04 04 04 04 04 04 04
@@..............
01737F48 0010 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
01737F58 0020 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
01737F68 0030 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
01737F78 0040 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
01737F88 0050 04 04 04 04 04 04 40 40-40 40 40 40 40 40 40 40
......@@@@@@@@@@
01737F98 0060 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01737FA8 0070 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01737FB8 0080 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01737FC8 0090 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01737FD8 00A0 40 40 40 40 40 40 40 40-40 40 04 04 04 04 04 04
@@@@@@@@@@......
01737FE8 00B0 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
01737FF8 00C0 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
01738008 00D0 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
01738018 00E0 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
01738028 00F0 04 04 04 04 04 04 04 04-04 04 04 04 04 04 40 40
..............@@
=================================================================================
=================================================================================
lpBuffer = &h175B438 nBytes = 256
0175B438 0000 66 00 20 00 74 00 68 00-65 00 20 00 66 00 6F 00 f. .t.h.e.
.f.o.
0175B448 0010 6C 00 6C 00 6F 00 77 00-69 00 6E 00 67 00 20 00
l.l.o.w.i.n.g. .
0175B458 0020 66 00 6F 00 75 00 72 00-20 00 63 00 68 00 61 00 f.o.u.r.
.c.h.a.
0175B468 0030 72 00 61 00 63 00 74 00-65 00 72 00 20 00 67 00
r.a.c.t.e.r. .g.
0175B478 0040 72 00 6F 00 75 00 70 00-73 00 3A 00 20 00 45 00
r.o.u.p.s.:. .E.
0175B488 0050 6E 00 67 00 6C 00 69 00-73 00 68 00 20 00 75 00
n.g.l.i.s.h. .u.
0175B498 0060 70 00 70 00 65 00 72 00-63 00 61 00 73 00 65 00
p.p.e.r.c.a.s.e.
0175B4A8 0070 20 00 63 00 68 00 61 00-72 00 61 00 63 00 74 00
.c.h.a.r.a.c.t.
0175B4B8 0080 65 00 72 00 73 00 20 00-28 00 41 00 20 00 74 00 e.r.s.
.(.A. .t.
0175B4C8 0090 68 00 72 00 6F 00 75 00-67 00 68 00 20 00 5A 00
h.r.o.u.g.h. .Z.
0175B4D8 00A0 29 00 3B 00 20 00 45 00-6E 00 67 00 6C 00 69 00 ).;.
.E.n.g.l.i.
0175B4E8 00B0 73 00 68 00 20 00 6C 00-6F 00 77 00 65 00 72 00 s.h.
.l.o.w.e.r.
0175B4F8 00C0 63 00 61 00 73 00 65 00-20 00 63 00 68 00 61 00 c.a.s.e.
.c.h.a.
0175B508 00D0 72 00 61 00 63 00 74 00-65 00 72 00 73 00 20 00
r.a.c.t.e.r.s. .
0175B518 00E0 28 00 61 00 20 00 74 00-68 00 72 00 6F 00 75 00 (.a.
.t.h.r.o.u.
0175B528 00F0 67 00 68 00 20 00 7A 00-29 00 3B 00 20 00 4E 00 g.h.
.z.).;. .N.
=================================================================================
=================================================================================
lpBuffer = &h175B470 nBytes = 256
0175B470 0000 65 00 72 00 20 00 67 00-72 00 6F 00 75 00 70 00 e.r.
.g.r.o.u.p.
0175B480 0010 73 00 3A 00 20 00 45 00-6E 00 67 00 6C 00 69 00 s.:.
.E.n.g.l.i.
0175B490 0020 73 00 68 00 20 00 75 00-70 00 70 00 65 00 72 00 s.h.
.u.p.p.e.r.
0175B4A0 0030 63 00 61 00 73 00 65 00-20 00 63 00 68 00 61 00 c.a.s.e.
.c.h.a.
0175B4B0 0040 72 00 61 00 63 00 74 00-65 00 72 00 73 00 20 00
r.a.c.t.e.r.s. .
0175B4C0 0050 28 00 41 00 20 00 74 00-68 00 72 00 6F 00 75 00 (.A.
.t.h.r.o.u.
0175B4D0 0060 67 00 68 00 20 00 5A 00-29 00 3B 00 20 00 45 00 g.h.
.Z.).;. .E.
0175B4E0 0070 6E 00 67 00 6C 00 69 00-73 00 68 00 20 00 6C 00
n.g.l.i.s.h. .l.
0175B4F0 0080 6F 00 77 00 65 00 72 00-63 00 61 00 73 00 65 00
o.w.e.r.c.a.s.e.
0175B500 0090 20 00 63 00 68 00 61 00-72 00 61 00 63 00 74 00
.c.h.a.r.a.c.t.
0175B510 00A0 65 00 72 00 73 00 20 00-28 00 61 00 20 00 74 00 e.r.s.
.(.a. .t.
0175B520 00B0 68 00 72 00 6F 00 75 00-67 00 68 00 20 00 7A 00
h.r.o.u.g.h. .z.
0175B530 00C0 29 00 3B 00 20 00 4E 00-75 00 6D 00 65 00 72 00 ).;.
.N.u.m.e.r.
0175B540 00D0 61 00 6C 00 73 00 20 00-28 00 30 00 20 00 74 00 a.l.s.
.(.0. .t.
0175B550 00E0 68 00 72 00 6F 00 75 00-67 00 68 00 20 00 39 00
h.r.o.u.g.h. .9.
0175B560 00F0 29 00 3B 00 20 00 4E 00-6F 00 6E 00 2D 00 61 00 ).;.
.N.o.n.-.a.
=================================================================================
=================================================================================
lpBuffer = &h34E62B8 nBytes = 256
034E62B8 0000 01 00 00 00 01 00 00 00-08 00 00 00 68 6A 4E 03
............hjN.
034E62C8 0010 70 69 4E 03 00 00 00 00-00 00 00 00 00 00 00 00
piN.............
034E62D8 0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
................
034E62E8 0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
................
034E62F8 0040 19 00 00 00 00 00 00 00-FF FF 00 00 00 00 00 00
................
034E6308 0050 00 00 00 00 C8 31 4C 03-80 00 00 00 00 00 00 00
.....1L.........
034E6318 0060 00 00 00 00 00 00 00 00-00 00 00 00 03 00 00 00
................
034E6328 0070 38 1B 48 03 10 00 00 00-00 00 00 00 90 10 48 03
8.H...........H.
034E6338 0080 68 62 4E 03 00 00 00 00-E0 61 4E 03 00 00 00 00
hbN......aN.....
034E6348 0090 FF FF 00 00 00 00 00 00-00 00 00 00 03 00 00 00
................
034E6358 00A0 FF FF FF FF 00 00 00 00-FF FF FF FF FF FF 00 00
................
034E6368 00B0 00 00 00 00 00 00 00 00-14 00 00 00 00 00 00 00
................
034E6378 00C0 FF FF FF FF 00 00 00 00-E8 61 4E 03 45 AE 8A 1C
.........aN.E...
034E6388 00D0 2A 42 80 4A 84 EF C6 22-E2 75 75 CE 00 00 00 00
*B.J...".uu.....
034E6398 00E0 00 00 00 00 00 00 00 00-00 00 00 00 01 00 00 00
................
034E63A8 00F0 6C AF 48 03 00 00 00 00-00 00 00 00 20 08 02 00
l.H......... ...
=================================================================================
=================================================================================
lpBuffer = &h17263C8 nBytes = 256
017263C8 0000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
................
017263D8 0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
................
017263E8 0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
................
017263F8 0030 00 00 00 00 00 00 00 00-29 29 29 14 28 28 28 7B
........))).((({
01726408 0040 25 25 25 D9 31 31 31 FA-49 49 49 FF 6B 6B 6B FF
%%%.111.III.kkk.
01726418 0050 98 98 98 FF C4 C4 C4 FF-E6 E6 E6 FF E6 E6 E6 FF
................
01726428 0060 E6 E6 E6 FF E6 E6 E6 FF-E6 E6 E6 FF E6 E6 E6 FF
................
01726438 0070 E6 E6 E6 FF E6 E6 E6 FF-E6 E6 E6 FF E6 E6 E6 FF
................
01726448 0080 E6 E6 E6 FF E6 E6 E6 FF-E6 E6 E6 FF E6 E6 E6 FF
................
01726458 0090 A3 A3 A3 FF 4A 4A 4A E9-2B 2B 2B 73 00 00 00 09
....JJJ.+++s....
01726468 00A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
................
01726478 00B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
................
01726488 00C0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
................
01726498 00D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
................
017264A8 00E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
................
017264B8 00F0 00 00 00 00 00 00 00 00-33 33 33 30 62 62 62 FF
........3330bbb.
=================================================================================
=================================================================================
lpBuffer = &h34EAEC0 nBytes = 256
034EAEC0 0000 60 84 16 03 FF FF FF FF-FF FF FF FF 08 00 FF FF
`...............
034EAED0 0010 00 00 00 00 74 20 42 61-60 84 18 03 FF FF FF FF ....t
Ba`.......
034EAEE0 0020 FF FF FF FF 03 00 FF FF-00 00 00 00 67 68 74 73
............ghts
034EAEF0 0030 60 84 1A 03 FF FF FF FF-FF FF FF FF 07 00 FF FF
`...............
034EAF00 0040 00 00 00 00 4B 00 54 68-60 84 1C 03 FF FF FF FF
....K.Th`.......
034EAF10 0050 FF FF FF FF 07 00 FF FF-00 00 00 00 64 65 64 20
............ded
034EAF20 0060 60 84 1E 03 FF FF FF FF-FF FF FF FF 03 00 FF FF
`...............
034EAF30 0070 00 00 00 00 20 65 78 70-60 84 20 03 FF FF FF FF .... exp`.
.....
034EAF40 0080 FF FF FF FF 08 00 FF FF-00 00 00 00 61 6E 74 79
............anty
034EAF50 0090 60 84 22 03 FF FF FF FF-FF FF FF FF 08 00 FF FF
`.".............
034EAF60 00A0 00 00 00 00 65 76 65 6E-60 84 24 03 FF FF FF FF
....even`.$.....
034EAF70 00B0 FF FF FF FF 08 00 FF FF-00 00 00 00 65 20 68 65
............e he
034EAF80 00C0 60 84 26 03 FF FF FF FF-FF FF FF FF 08 00 FF FF
`.&.............
034EAF90 00D0 00 00 00 00 6D 61 67 65-0C 11 66 03 60 02 00 00
....mage..f.`...
034EAFA0 00E0 FF FF FF FF 00 00 00 00-FF FF FF FF FF FF FF FF
................
034EAFB0 00F0 00 00 00 00 00 00 00 00-FF FF FF FF 00 00 00 00
................
=================================================================================
=================================================================================
lpBuffer = &h1737D08 nBytes = 256
01737D08 0000 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01737D18 0010 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01737D28 0020 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01737D38 0030 40 40 40 40 40 40 40 40-40 40 04 04 04 04 04 04
@@@@@@@@@@......
01737D48 0040 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
01737D58 0050 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
01737D68 0060 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
01737D78 0070 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
01737D88 0080 04 04 04 04 04 04 04 04-04 04 04 04 04 04 40 40
..............@@
01737D98 0090 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01737DA8 00A0 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01737DB8 00B0 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01737DC8 00C0 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01737DD8 00D0 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01737DE8 00E0 40 40 04 04 04 04 04 04-04 04 04 04 04 04 04 04
@@..............
01737DF8 00F0 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
=================================================================================
=================================================================================
lpBuffer = &h1738050 nBytes = 256
01738050 0000 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01738060 0010 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01738070 0020 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01738080 0030 40 40 40 40 40 40 40 40-40 40 04 04 04 04 04 04
@@@@@@@@@@......
01738090 0040 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
017380A0 0050 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
017380B0 0060 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
017380C0 0070 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
017380D0 0080 04 04 04 04 04 04 04 04-04 04 04 04 04 04 40 40
..............@@
017380E0 0090 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
017380F0 00A0 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01738100 00B0 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01738110 00C0 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01738120 00D0 40 40 40 40 40 40 40 40-40 40 40 40 40 40 40 40
@@@@@@@@@@@@@@@@
01738130 00E0 40 40 04 04 04 04 04 04-04 04 04 04 04 04 04 04
@@..............
01738140 00F0 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04
................
=================================================================================
There is some sense in it, but not sure yet what.
RBS
"Karl E. Peterson" <ka...@mvps.org> wrote in message
news:uMLqDT39...@TK2MSFTNGP14.phx.gbl...
That's my guess.
> I have downloaded your code and added it to my Excel code.
> Which function/Sub do I use on these numbers?
I'd just try looking right at the memory itself. Something like:
Debug.Print HexDump(pData, 128)
See what ya get. Look at the example on that page
(http://vb.mvps.org/samples/HexDump) which is discussed more in the article
I did for VBPJ (linked at the bottom of that page, under "Published"). It's
not unlikely that you could be looking at a memory structure that will need
further deconstruction.
It would be much easier for people if you would post a bit of the text
visible in the list items of the list box as well...
Hmmm, the first works out to:
a.v.e. .b.e.e.n.
.c.h.a.n.g.e.d.
.w.i.t.h.i.n. .
t.h.e. .l.a.s.t.
.%.l.d. .d.a.y.
s.;. .d.o.e.s. .
n.o.t. .c.o.n.t.
a.i.n. .y.o.u.r.
.a.c.c.o.u.n.t.
.o.r. .f.u.l.l.
.n.a.m.e.;. .c.
o.n.t.a.i.n.s. .
a.t. .l.e.a.s.t.
.t.h.r.e.e. .o.
f. .t.h.e. .f.o.
l.l.o.w.i.n.g. .
Or...
"ave been changed within the last %ld days;
does not contain your account or fullname;
contains at least three of the following "
> There is some sense in it, but not sure yet what.
Definitely program text, but is anything like that in the list?
(Recognizing it as Unicode, with the every-other vbNullChar.) And the
others sort of degraded from there. Looks to me like the way those
addresses were derived isn't quite the ticket.
So for example:
01/02/05
FRUSEMIDE 40 mg tablets
two each morning, 100 tablets
10/20
RS
What I got now is an entirely different bit of memory, so as you say I need
some further manipulations
of those numbers before it points to the right bits.
RBS
"Thorsten Albers" <albe...@MOVEuni-freiburg.de> wrote in message
news:01c5f782$ffaf12c0$9c8ee684@thaldesk...
Other then Karl I don't think that this looks very promising. I am in doubt
that these values are pointers - unless your application allocates a very
high amount of memory. Virtual memory addresses start at 7FFFFFFFh (2 GB,
NT).
(And my theory about the box character being a character code like 7Fh has
collapsed since I forgot to take into account that control codes (character
codes 00h to 1Fh) will be mapped to a box character (= no glyph) as well -
and in each line listed the high byte of the high word has a byte value <=
1Fh.)
As you say it: Array index numbers seem to be excluded as well - unless the
array index is a byte or word value packed into the DWORD value (what is
rather unlikely because, as far as I can see, with any combination of bytes
the one or the other value appears more then one time).
Memory handles seem to be excluded too since AFAIK on Window 32 bit a
memory handle is a pointer to the first byte of allocated memory.
Byte
3 2 1 0
> 03 4E 29 78
> 03 4E 1D D0
> 01 75 B2 E8
> 01 75 B4 00
> 01 75 B7 48
> 01 75 B3 C8
> 01 75 93 A0
> 01 75 B3 20
> 01 75 B3 58
> 01 75 B3 90
> 01 73 7F 38
> 01 75 B4 38
> 01 75 B4 70
> 03 4E 62 B8
> 01 72 63 C8
> 03 4E AE C0
> 01 73 7D 08
> 01 73 80 50
Byte 0 looks also a flags value. The low nibble has only 0 or 8, the high
nibble has nearly all combinations of set bits
Byte 1 is ???
Byte 3 also looks like a flags value with bit 0 or bit 0 and bit 1 set
(with these list entries)
Byte 2 looks like an ASCII character code. Would be:
N
N
u
u
u
u
u
u
u
u
s
u
u
N
r
N
s
s
Does that mean anything to you compared to the visible list box entries?
RBS
"Thorsten Albers" <albe...@MOVEuni-freiburg.de> wrote in message
news:01c5f787$7fe84020$9c8ee684@thaldesk...
RBS
"Thorsten Albers" <albe...@MOVEuni-freiburg.de> wrote in message
news:01c5f782$ffaf12c0$9c8ee684@thaldesk...
<00253> 02C50402 S LB_GETCURSEL
<00254> 02C50402 R LB_GETCURSEL index:4
<00255> 02C50402 S LB_GETCOUNT
<00256> 02C50402 R LB_GETCOUNT cItems:5
<00257> 02C50402 S LB_GETITEMDATA index:4
<00258> 02C50402 R LB_GETITEMDATA dwData:017438F0
It does show that at least we are getting the right dwData.
RBS
"Thorsten Albers" <albe...@MOVEuni-freiburg.de> wrote in message
news:01c5f782$ffaf12c0$9c8ee684@thaldesk...
> it.
> The first column holds an icon, then a date, then the drug name, then the
> dosage, then some issue related data, such as 10/20 (10 issues out of 20
> authorisations)
> then an attachement column that isn't used and then finally a string or
> maybe a number
> indicating the person who authorised that drug.
> So for example:
> 01/02/05
> FRUSEMIDE 40 mg tablets
> two each morning, 100 tablets
> 10/20
>
> What I got now is an entirely different bit of memory, so as you say I
need
> some further manipulations
> of those numbers before it points to the right bits.
Oh, such kind of data!
Here's my new bet: The data displayed is stored in a database hold in
memory by the application. The item data is an >identifier< identifying the
database entry displayed by the respective list entry. Maybe the identifier
is the ID of the person whose data is displayed maybe it is a database
record ID. Check if the application uses a file with a common database file
extension (*.mdb, *.dbf, *.dbx, or the like; but a proprietary database
format of course can't be excluded).
And: IMHO there is >no chance< for you to get to the data in memory unless
there is a function exported for this.
I rather doubt that the strings displayed do exist in memory for each list
entry individually. Instead they presumably are string constants drawn
according to values of the respective database record entries.
At least this is the way >I< would code such listbox...
So, what is left is IMHO only optical character recognition. In general it
shouldn't be very difficult if you know the font properties used to display
the list entries. After creating a font with the respective font properties
and selecting it into a device context the properties of which are the same
as that of the device context of the listbox the Windows API function
GetGlyphOutline() provides you with bitmaps of the font's glyphs which
should be the same as used for the text displayed in the listbox, i.e. a
comparison bit by bit should be successfull. Things are a bit more
difficult if the list items are displayed only partially because then you
would have to scroll the list also horizontally by code.
O.k., here is a very dirty other solution of which I don't know if it
really is a solution - it is just an 'online idea':
- Subclass the ListBox; unfortunately AFAIK it is not possible to subclass
a control of a different process in VB; I don't know if it is possible at
all.
- Capture the WM_OWNERDRAW message sent to the ListBox and replace the hDC
member of the DRAWITEMSTRUCT by a handle of of an enhanced meta file.
- After the WM_OWNERDRAW message has been processed by the owner of the
ListBox enumerate the objects of the enhanced meta file with
EnumEnhMetaFile(). If the owner of the ListBox draws the text with
TextOut() or ExtTextOut() you EnumEnhMetaFile() will list a META_TEXTOUT/
META_EXTTEXTOUT object for each of them holding the string that has been
drawn.
- Last and least send the WM_OWNERDRAW message once again to the process
but know with the original device context handle so that it will be drawn
into the device context of the ListBox (and thereby will be displayed).
And: No, I can't provide you with a code snippet for this, simply because I
have never done it...
The database is Interbase and there only could be 2 tables involved for the
bit of the listbox I am interested in.
> O.k., here is a very dirty other solution
That goes a bit too far for me. I am a simple VBA programmer and only do a
bit of Windows API if I have to.
Still not given up though on this.
RBS
"Thorsten Albers" <albe...@MOVEuni-freiburg.de> wrote in message
news:01c5f78d$f84a5e80$058ee684@thaldesk...
As you said I can't use copymemory, so I need to do as Kevin:
Sub test()
Dim nCount As Long
Dim i As Long
Dim TxtLen As Long
Dim Buffer As String
Dim hWnd As Long
Dim pData As Long
Dim lProcess As Long
Dim ReadBytes As Long
Dim lProcessThread As Long
Dim lReturn As Long
Dim strString As String
hWnd = GetMedicationLBhwnd()
'The hWnd should be the handle of the listbox itself, and not the actual
app
GetWindowThreadProcessId hWnd, lProcess
lProcessThread = OpenProcess(PROCESS_VM_READ Or
STANDARD_RIGHTS_REQUIRED, False, lProcess)
strString = String(300, vbNullChar)
nCount = SendMessage(hWnd, LB_GETCOUNT, 0&, ByVal 0&)
If nCount <> LB_ERR Then
For i = 0 To nCount - 1
TxtLen = SendMessage(hWnd, LB_GETTEXTLEN, i, ByVal 0&)
If Len(Buffer) < (TxtLen + 1) Then
Buffer = Space$(TxtLen + 1)
End If
pData = SendMessage(hWnd, LB_GETITEMDATA, i, 0&)
lReturn = ReadProcessMemory(lProcessThread, pData, strString,
300, 300)
Debug.Print strString
Next i
End If
CloseHandle lProcessThread
End Sub
Now I get output that starts to make sense:
¯^o \q \q ∏LO ∏LO ∏LO _ 2200 d o w
\ ¥\q –v` ~(v h-s Y From Conversion [PH] e ICE b R 4/20
S (none) P \q ê∫N ¿€v XΩO - blb.. 4 ^Òr *
2200 πN xoO ' ÿ 4 (?t ~ˇN $ XΩO ∏rt ÿRv Xƒt ! XΩO
¯^o \q \q ~–N ~–N ~–N d o m xiv ‡ s
è daily NE l B a r n s < 4:q ( O[q –yq % d\q zq
" Ã:q ƒ[q O[q ¨O
8iN Y amoxicillin capsules 250mg se se iN ?=v edSet ~ M
N . ne 7800 ovate " ≠t »=s ^6t
¯^o CÙ \q \q pNt pNt pNt t 8fj (9t
« ‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís
‹ ‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís‘?Ís
— ¿ 4 Ø <eq
¯^o IÙ \q \q 0¶u 0¶u 0¶u 8 4:q ' O[q }s
' d\q »ou 1 ~u `<| `<| Ë~u Tq ƒ[q O[q
ÿ<q W 4 ˛t ‡*O N @πv ËrN E Entry_Id IN
(259150,259130,2340618,2389200,2389201,2407253,2901948, , ge
30/03/05 ena
¯^o 9Ù \q \q ∏ot ∏ot ∏ot X u ‡ s UO L
I ‡ªm ‰ªm V
OLq ¸ªm ¿
©"Lq ºm ’
?oLq T%t Ω
G§Lq »≤N A R 3730 Pzs \ (none) leted r
Y \q º s º s ∞‰O V d1a9. D 03 R b 677
¯^o GÙ \q \q @1t @1t @1t ◊ From Conversion
[PH] h 5mg tablets — Everyone …t Ëoj Æ (none) ∞,q ∞'N
´ Dr. Smissaert [RS] tion 09,3864324) g • From Conversion
[DF] •u = ø ê N ` 4 º ê 4 ∏-s
π take
¯^o ¶9 \q \q (1t (1t (1t cte T ∞IO r o l l B a r
P v ~ 4 ê 4 ËJO 0mg rogr , ?¥t ¯.t kt »gt ) u H r t of
Iss & ˝r . et # daily NE Mu ^SN ~<| <s ? ∞ªt ‡3t
h^u < Bs ‹m \‹m –µN 9 ÷v one
¯^o ;Ù \q \q ËNt ËNt ËNt ¨
,v 3/05 NOVOMIX 30 injection 30:70; 100u/ml use as directed 5 3ml
FLEXPEN R 2/20 RS v æ TGq `^r ¯^o JÙ
¸^o ~ O[q _u ÏCq ‰Cq O[q X„u Eq ^Wq O[q _u
O[q ?´N
¯^o =Ù \q \q ^.t ^.t ^.t ∞ "" O[q
–„O ê N 8 v 0 O P ^?O ˆt \N ®”N d\q ‡oO
êÍr ^ˇt ¯ N ®VO ®5t p Ë…O æN »zs pSq ê±u ^ÆN »TO ÿ$t ^¶v ® s PUO ¿2t @iv
hts –\q uv T ABRPZ ugCode Sv - 8Õt ^}s p;t " eq ‰Î
‡ s
¯^o EÙ \q \q 0ùt 0ùt 0ùt ! ' »gj
˚ ˝ ˛ ˇ
˜ ˇ ˘ ˙
˚ ¸
¯^o MÙ \q \q `¶u `¶u `¶u 1 U PÚN
¯^o SÙ \q \q x¶u x¶u x¶u x s %t ¯+t
N -s Medication K Tq ƒ[q O[q …t 0 o F ¯^o
\q \q ∏LO ∏LO ∏LO _ 2200 d o w \ ¥\q –v`
~(v h-s Y From Conversion [PH] e ICE b R 4/20 S (none)
¯^o ∑# \q \q ¶u ¶u ¶u spr 7 \q X?t ∞ŒO u
4 daily NE ?Ís ‘?Ísmg - 0 8§u ÙÈ” puhj. ACVSY ]"
>§1 π…1 eep in cool place,fridgefistula for dialysis1)is se
¯^o % \q \q ~.N ~.N ~.N
* ?»v 2/05 NEOCLARITYN tablets 5mg Condition Resolved
ge
X”O
6 o°r ge
¥
P7N
¯^o Vç< \q \q Ot Ot Ot /ml 4 4:q ' O[q ^yq
' d\q ∏yq
>r Ù-r O
`l p >r m
∑t p º"s >
°| p §yr O
a" p S v From Conversion [MH] 4:q % O[q
’v & d\q HRv P ®>m HˇO <t
¯^o a = \q \q ¯-t ¯-t ¯-t dai > twÁs
`Œ ¶ ¢ twÁs `Œ
~ ¬ twÁs »r} ~ $
twÁs `Œ ‹ +
¯^o \q \q ∞–N ∞–N ∞–N d . hsN ¯2t fl
n n F € Ût 8 v ÿ ∏u ∏S| ∏S| 8∏u
’ ¸ t “ ms ∏Sq edSet Ø f731.
´ 2200 ' ® ∞_t ÿ s `wv ^‰O ÿbr dv <s –7t ê.t X u
¯^o \q \q ÿ?v ÿ?v ÿ?v o m –-r Puu
Q ®∑r Pzq 6t ®;t J .
Not usable yet, but you can see the drug data in there. I will have to play
with the numbers I take such as the 300.
RBS
"Thorsten Albers" <albe...@MOVEuni-freiburg.de> wrote in message
news:01c5f787$7fe84020$9c8ee684@thaldesk...
> THORSTEN ALBERS Universit‰t Freiburg
> albers@
> uni-freiburg.de
> ----------------------------------------------------------------------
>
Not if you keep this up for long! ;-)
RBS
"Karl E. Peterson" <ka...@mvps.org> wrote in message
news:ukA9wb5...@TK2MSFTNGP09.phx.gbl...
RBS
"Karl E. Peterson" <ka...@mvps.org> wrote in message
news:ukA9wb5...@TK2MSFTNGP09.phx.gbl...
Check, if the item data DWORD entry may be is a composition out of the ID
and one or more other (byte) values; e.g.:
Flags ID
03 4E2978
or
Flags ??? ID
03 4E 2978
or something alike...
And, in addition: Is it to be excluded
- that the ID is the database record table index of one of the 2 tales?
- that there is a hidden ID which is unique for every database record? Most
databases I have seen so far do have such an entry which is hidden because
it isn't of interest for the user of the database but is for 'internal' use
only.
Another possibility: Maybe the list items are based on a selection of the
database records (a report or the like); if so, the ID's may be are ID's
based on this selection and are not to be found in the database tables.
If this isn't just coincidence (which would mean that I again was wrong
with saying that these item data values don't seem to be pointers :-(),
then each item data value presumably is a pointer to the beginning of the
respective database record. It is very likely that the database records are
not equal in length - on the contrary the maybe differ signicantly in
length. If the list items are not sorted somehow, the offset from pointer
to pointer should give you the length of the database record.
But instead of working out the full format of the individual record in
memory I would take the following into account: Usually the database record
identifier (which may be the table index number, an ID stored in the table,
of the like) is to be found at or near the beginning of the record data.
So, compare the beginning of the dumped data with the respective table
entries. Since you are a VBA excel programmer (:-)) you maybe are not aware
of the following fact: Usually numbers are stored not in the order with the
lowest digit to the right. Instead they are stored:
Number: 223234545
Hexadecimal representation: 0D4E49F1h
Stored as: F1 49 4E 0D
And you should make hexadecimal dumps of the data which are much better
readable than this character garbage...
- Kev
"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message
news:uXvzzP59...@TK2MSFTNGP15.phx.gbl...
GetWindowThreadProcessId hWnd, lProcess
lProcessThread = OpenProcess(PROCESS_VM_READ Or
STANDARD_RIGHTS_REQUIRED, False, lProcess)
Gives me the right process.
When I look with Spy++ at this listbox there are a ProcessID and a ThreadID
and both these numbers are not
the same as my lProcessThread. I definitely have the right hwnd though.
The other thing that is not right is that although I now only pick one
listbox item:
iIndex = SendMessage(hWnd, LB_GETCURSEL, 0&, ByVal 0&)
I get drug data from other listbox items as well and the the drug of the
listbox item I am getting is not even the first
amongst the obtained data. Also I get data that has nothing to do with the
listbox, although always it is from the
application (Synergy).
This is the whole Sub as it stands now:
Sub test()
Dim hWnd As Long
Dim iIndex As Long
Dim pData As Long
Dim lProcess As Long
Dim lProcessThread As Long
Dim ReadBytes As Long
Dim lReturn As Long
Dim strString As String
hWnd = GetMedicationLBhwnd()
GetWindowThreadProcessId hWnd, lProcess
lProcessThread = OpenProcess(PROCESS_VM_READ Or
STANDARD_RIGHTS_REQUIRED, False, lProcess)
strString = String(10000, vbNullChar)
iIndex = SendMessage(hWnd, LB_GETCURSEL, 0&, ByVal 0&)
pData = SendMessage(hWnd, LB_GETITEMDATA, iIndex, 0&)
lReturn = ReadProcessMemory(lProcessThread, pData, strString, 10000,
ReadBytes)
If lReturn = 1 Then
Debug.Print strString
End If
CloseHandle lProcessThread
End Sub
RBS
"Kevin Provance" <ca...@tpasoft.com> wrote in message
news:enczYO7...@TK2MSFTNGP12.phx.gbl...
RBS
"RB Smissaert" <bartsm...@blueyonder.co.uk> wrote in message
news:%23NezT0%239FH...@tk2msftngp13.phx.gbl...
If this isn't just coincidence (which would mean that I again was wrong
with saying that these item data values don't seem to be pointers :-(),
then each item data value presumably is a pointer to the beginning of the
respective database record. It is very likely that the database records are
not equal in length - on the contrary the maybe differ signicantly in
length. If the list items are not sorted somehow, the offset from pointer
to pointer should give you the length of the database record.
But instead of working out the full format of the individual record in
memory I would take the following into account: Usually the database record
identifier (which may be the table index number, an ID stored in the table,
of the like) is to be found at or near the beginning of the record data.
So, compare the beginning of the dumped data with the respective table
entries. Since you are a VBA excel programmer (:-)) you maybe are not aware
of the following fact: Usually numbers are stored not in the order with the
lowest digit to the right. Instead they are stored:
Number: 223234545
Hexadecimal representation: 0D4E49F1h
Stored as: F1 49 4E 0D
And you should make hexadecimal dumps of the data which are much better
readable than this character garbage...
--
Did you mean coincidence to get some readable data out?
The data in the database has very similar lenghts for the different rows as
there are maximum number of characters for the text items (60 or 200) and
the dates are all in the
form yyyymmdd.
The differences in the numerical pData output for the different items is
just too big to be explained by length
of data in the database.
Another thing that is puzzling is that I can see no logical relation between
the chosen listbox item and the output and
I don't think that doing:
pData = SendMessage(hWnd, LB_GETITEMDATA, ByVal CLng(iIndex), 0&)
Has a direct influence as to what listbox item you get.
Sometimes I get data that just can't be in the listbox such as patient's
address data and also SQL strings, so I am still
far from having an insight in how this all works.
> And you should make hexadecimal dumps of the data
Not sure what you meant with that. What exactly should I make hexadecimal?
Thanks in any case for your assistance with this.
RBS
"Thorsten Albers" <albe...@MOVEuni-freiburg.de> wrote in message
news:01c5f7f5$111898c0$848ee684@thaldesk...
Yes. Either the item data is a pointer to the respective database data or
it is a value which, used as if it were a pointer, by coincidence points
somewhere to the database data. What you have written below (no coherence
of list item and dumped data) lets me assume that in fact >it is a
coincidence<.
> The data in the database has very similar lenghts for the different rows
as
> there are maximum number of characters for the text items (60 or 200) and
> the dates are all in the
> form yyyymmdd.
> The differences in the numerical pData output for the different items is
> just too big to be explained by length of data in the database.
This IMHO makes it even more likely that the item data value >is not< a
pointer to the database data. Otherwise the differences could be explained
only, if the list displays only part of the database data with varring
amounts of undisplayed database records between displayed records.
List item Database record
0 0 displayed
1 not displayed
1 2 displayed
2 3 displayed
4 not displayed
5 not displayed
6 not displayed
3 7 displayed
->
pData(1) - pData(0) = record length * 2
pData(2) - pData(1) = record length * 1
pData(3) - pData(2) = record length * 4
> Another thing that is puzzling is that I can see no logical relation
between
> the chosen listbox item and the output and
> I don't think that doing:
> pData = SendMessage(hWnd, LB_GETITEMDATA, ByVal CLng(iIndex), 0&)
That's a pity; again: IMHO the item data values aren't >pointers< to the
respective database data.
> Has a direct influence as to what listbox item you get.
> Sometimes I get data that just can't be in the listbox such as patient's
> address data and also SQL strings, so I am still
> far from having an insight in how this all works.
Remember what I have said in an earlier posting of mine: As I understand
you, you are doing a database research or report; the result of this is
displayed in the ListBox. If so, the item data presumably will >not< refer
to the original tables of the database but to the table entries of a
temporary table which has been created for the research or report and which
presumably only holds a collection of some of the database records, not of
all.
Database table
ID Contents
1 hwdhu
2 mxssm
3 etztwe
4 uyuxxu
5 qwqxbb
6 982mm3
7 pouioi
8 xxxgsg
-> Show me all table entries with 'x'
-> Temporary table
Temporary ID ID Contents
1 2 mxssm
2 4 uyuxxu
3 5 qwqxbb
4 8 xxxgsg
Here I would expect the 'temporary ID' (table index number or something
alike) to be used as the ListBox item data value, >not< the original ID.
> Not sure what you meant with that. What exactly should I make
hexadecimal?
> Thanks in any case for your assistance with this.
Instead of (just an example)
Y From Conversion
make it a hex dump like
0000: 59 03 12 00 20 46 72 6F 6D 20 43 6F 6E 76 65 72 Y... From Conver
0008: 73 69 6F 6E sion
--
----------------------------------------------------------------------
THORSTEN ALBERS Universit鋞 Freiburg
albers@
uni-freiburg.de
----------------------------------------------------------------------
RBS
"Thorsten Albers" <albe...@MOVEuni-freiburg.de> wrote in message
news:01c5f81b$eac7df60$8a8ee684@thaldesk...
--
mayaya...@mindXXspring.com
(Remove Xs for return email.)
RB Smissaert <bartsm...@blueyonder.co.uk> wrote in message
news:#7OG5HC#FHA....@TK2MSFTNGP12.phx.gbl...
RBS
1) VB listbox: item content is contained in Name element.
2) Win98 Display applet wallpaper list:
item content is contained in Name element.
3) IrfaniView funky checkbox list for selecting
file types: item name is in Name element and
item help string is in Description element.
In each case the content was available, but in the
case of Display Properties, for example, the actual
hWnd for the list box is about 6 or 7 steps down
into the window.
--
mayaya...@mindXXspring.com
(Remove Xs for return email.)
<bart.sm...@gmail.com> wrote in message
news:1133637220.0...@g43g2000cwa.googlegroups.com...
RBS
RBS
"mayayana" <mayaya...@mindXXspring.com> wrote in message
news:9Q0kf.11970$aA2....@newsread2.news.atl.earthlink.net...
> Sorry if this info. is redundant, but I just
> looked at this thread for the first time.
> Awhile back I was working on a screen reader
> for a blind friend and had to work out the
> Active Accessibility code for VB. This
> may be of some help, though I'm not
> sure about listbox text specifically, offhand.
>
> http://www.jsware.net/jsware/vbcode.php3#acc
>
> --
> mayaya...@mindXXspring.com
> (Remove Xs for return email.)
> RB Smissaert <bartsm...@blueyonder.co.uk> wrote in message
> news:OceikAd9...@TK2MSFTNGP12.phx.gbl...
>> Trying to get the text of items in a listbox of an external application.
>> This code will get me some data, but it is in non-readable form like
>> this:
>> 割A `
>>
>> Private Declare Function SendMessageLong Lib "user32" _
>> Alias "SendMessageA" _
>> (ByVal hwnd As Long, _
>> ByVal wMsg As Long, ByVal
>> wParam
>> As Long, _
>> ByVal lParam As Long) As Long
>>
>> Private Declare Function SendMessageStr Lib "user32" _
>> Alias "SendMessageA" _
>> (ByVal hwnd As Long, _
>> ByVal wMsg As Long, ByVal wParam
> As
>> Long, _
>> ByVal lParam As String) As Long
>>
>> Private Const LB_GETTEXT = &H189
>> Private Const LB_GETCOUNT = &H18B
>>
>> Sub test()
>>
>> Dim r As Long
>> Dim i As Long
>> Dim maxItems As Long
>> Dim listStr As String
>> Dim lLBhwnd As Long
>>
>> lLBhwnd = 7275646
>>
>> maxItems = SendMessageLong(lLBhwnd, LB_GETCOUNT, 0, 0)
>>
>> For i = 0 To maxItems - 1
>> listStr = Space$(64)
>> r = SendMessageStr(lLBhwnd, LB_GETTEXT, i, listStr)
>> If r > 0 Then
>> MsgBox Left$(listStr, r)
>> End If
>> Next
>>
>> End Sub
>>
>>
>> Would there be a way to get the readable data?
>>
>>
>> RBS
>>
>>
>>
>
>