Hi, I new to ASM programming, and I am having a bit of trouble using the SendMessage API. My code simply grabs the Title and URL of the currently active Internet Explorer window using the SendMessage API call. The problem is, that I can get it to grab the Title, or the URL, but not both. It will do one or the other depending on which one is done first, and then mess up on the second call. Here is the part of the code I am having trouble with.

invoke SendMessage, IEFrameHwnd, WM_GETTEXTLENGTH, 0, 0
mov ctxtLength, eax
add ctxtLength, 1
mov captionText, LENGTHOF ctxtLength
invoke SendMessage, IEFrameHwnd, WM_GETTEXT, ctxtLength, addr captionText
invoke MessageBox, NULL, addr captionText, addr AppName, MB_OK


invoke SendMessage, editHwnd, WM_GETTEXTLENGTH, 0, 0
mov utxtLength, eax
add utxtLength, 1
mov urlText, LENGTHOF utxtLength
invoke SendMessage, editHwnd, WM_GETTEXT, utxtLength, addr urlText
invoke MessageBox, NULL, addr urlText, addr AppName, MB_OK

The rest of the code sets up variable, etc. and get handles or the varius controls of the IE Window. Can anyone see what I am doing wrong with the above. (Above will grab the title and then mess up with the url, but if I put the url code first, it will get the URL, and not the Title)

Anyway, here is the full code, in case you need it.

; #########################################################################

.386
.model flat, stdcall
option casemap :none ; case sensitive

; #########################################################################

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

; #########################################################################
.data
ClassIEFrame db "IEFrame", 0
ClassWorkerW db "WorkerW", 0
ClassWorkerA db "WorkerA", 0
ClassReBarWindow32 db "ReBarWindow32", 0
ClassComboBoxEx32 db "ComboBoxEx32", 0
ClassComboBox db "ComboBox", 0
ClassEdit db "Edit", 0
AppName db "IE URL Viewer", 0
ErrorMSG db "No instances of Internet Explorer running!", 0

.data?
OsVer OSVERSIONINFO {}
captionText db ?
urlText db ?
ctxtLength dd ?
utxtLength dd ?
editHwnd HWND ?
IEFrameHwnd HWND ?
retval dd ?

.code
start:
mov OsVer.dwOSVersionInfoSize, SIZEOF OSVERSIONINFO
invoke GetVersionEx, addr OsVer
invoke FindWindow, addr ClassIEFrame, NULL
.if eax!=NULL
mov IEFrameHwnd, eax
.if OsVer.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS
invoke FindWindowEx, eax, 0, addr ClassWorkerA, NULL
.endif
.if OsVer.dwPlatformId==VER_PLATFORM_WIN32_NT
invoke FindWindowEx, eax, 0, addr ClassWorkerW, NULL
.endif
invoke FindWindowEx, eax, 0, addr ClassReBarWindow32, NULL
invoke FindWindowEx, eax, 0, addr ClassComboBoxEx32, NULL
invoke FindWindowEx, eax, 0, addr ClassComboBox, NULL
invoke FindWindowEx, eax, 0, addr ClassEdit, NULL
mov editHwnd, eax

invoke SendMessage, IEFrameHwnd, WM_GETTEXTLENGTH, 0, 0
mov ctxtLength, eax
add ctxtLength, 1
mov captionText, LENGTHOF ctxtLength
invoke SendMessage, IEFrameHwnd, WM_GETTEXT, ctxtLength, addr captionText
invoke MessageBox, NULL, addr captionText, addr AppName, MB_OK


invoke SendMessage, editHwnd, WM_GETTEXTLENGTH, 0, 0
mov utxtLength, eax
add utxtLength, 1
mov urlText, LENGTHOF utxtLength
invoke SendMessage, editHwnd, WM_GETTEXT, utxtLength, addr urlText
invoke MessageBox, NULL, addr urlText, addr AppName, MB_OK

.else
invoke MessageBox, NULL, addr ErrorMSG, addr AppName, MB_OK+MB_ICONERROR
.endif
invoke ExitProcess, 0
end start
Posted on 2002-04-29 08:43:55 by RussG
You've pointed the program at the address of a variable called captionText, which is a single byte long, the program then attempts to write several bytes starting at this position.
A string longer than 10 bytes will corrupt editHwnd, and a string longer than 14 bytes will corrupt IEFrameHwnd.

So the second SendMessage will be to a bogus (or at least unpredictable) window handle.

You should allocate more space to the caption buffer to start with:


captionBuffer db 20 DUP (?) ; for a buffer 20 bytes long


And secondly check to see if the string you are trying to get is longer than the buffer and compensate accordingly.

Mirno
Posted on 2002-04-29 10:17:43 by Mirno
If you're grabbing a URL or something you'd better make that buffer larger than 20 bytes. ;)
Posted on 2002-04-29 11:36:18 by iblis
or use the value returrned by WM_GETTEXTLENGHTH to dynamically allocate some memory
Posted on 2002-04-29 12:06:39 by Kudos
Thnaks for the info...
Can you explain how to set the buffer size from the result of the WM_GetTextLength...
I thought that is what I was doing with the:

mov ctxtLength, eax
add ctxtLength, 1
mov captionText, LENGTHOF ctxtLength

and

mov utxtLength, eax
add utxtLength, 1
mov urlText, LENGTHOF utxtLength

Doesn't the LENGTHOF operator set the buffer size to that of the text length returned by WM_GetTExtLength?
Posted on 2002-04-29 13:25:14 by RussG
ok if you want to set the buffer size first declare a pointer
ptrBuffer dd ?
...
invoke GetProcessHeap
invoke HeapAlloc, eax, HEAP_ZERO_MEMORY, utxtLength
mov ptrBuffer, eax


Don't forget to use HeapFree when you have finnished with this memory
Posted on 2002-04-29 13:34:21 by Kudos
LENGTHOF is not opcode it is operator for preprocessing.
It doesn't change anything using params that are changed in runtime.
LENGTHOF returns a number wich is known in DESIGN time.
Number of length of predefined structure.
Size between to starting points of next to each other strings etc.
Only things that you can calculate youself in design time, and they
are constant.
Posted on 2002-04-29 13:36:52 by The Svin