views:

28

answers:

2

I'm getting in trouble by hooking window messages. I need to detect window text (caption) changes, so I intercept the WM_SETTEXT message for the interesting windows (I do so because at window creation the window caption is not specified).

Reading the documentation of the WM_SETTEXT documentation, the lParam parameter specify a pointer to the string representing the window text.

The message is forwarded to a .NET application using SendMessage. What I do in the .NET application is:

private static bool ProcessMessage(ref Message msg) {
    ...
    string s = Marshal.PtrToStringAuto(msg.LParam) *
}

where ProcessMessage is the routine handling messages of the .NET form.

What I always get is an empty string, which is not the expected result. I tried other Marshal.PtrToString* methods, but no one has worked.

What am I doing wrong in the conversion of a IntPtr to String?

(*)Note that I cannot debug this code, since it would block the entire system, since all windows messages are intercepted.

A: 

It is probably a pointer to a pointer of chars.

So read the IntPtr, the read the value in IntPtr which is also IntPtr, then use that as you did.

Maybe it works, maybe it doesn't :p

leppie
+1  A: 

LParam is a string pointer, and your code is correct, assuming that it is executed in the same process where WM_SETTEXT message was sent. In another process, this pointer is invalid, and result of using this pointer is undefined.

Alex Farber
Bingo! The .NET code is in another process. I was thinking that the well-known message parameters could be passed between processes.
Luca
AFAIK, only WM_GETTEXT pointer is available in another process. This is special case, internally this message is implemented using memory-mapped file. All other pointers are invalid.
Alex Farber
There's more, it matters whether the window is Unicode or Ansi.
Hans Passant