1

I'm trying to subclass an unmanaged statusbar window from my managed COM server using a class inherited from NativeWindow, and am running into a wall trying to make sense of how to properly marshal the contents of an lParam.

http://msdn.microsoft.com/en-us/library/bb760757%28VS.85%29.aspx says that the contents of this lParam is of type (LPARAM)(LPINT) aWidths, and that the contents of this variable is actually a "pointer to an integer array."

I can't figure out a way to marshal this correctly. The goal is to read the lParam, add our value to the array, and then send the new message via base.wndProc(ref m).

It'd be nice if I could just int[] array = (int[])m.*lParam or somesuch, but life isn't so simple (and I don't get to use unsafe code). I've clumsily tried to force the marshaller to give me something via Marshal.PtrToStructure() but knew this was doomed from the start as the C-array isn't a struct and the struct I tried to make is obviously not blittable.

Right now we are letting the original call go through and then making additional WinAPI calls to get the array, format it, and then resend it before the statusbar can repaint. This is working well, but not well enough.

Any ideas?

Thanks!

Tom

PS- I've had a lot of trouble grokking how lParams are used in C#, the documentation is quite confusing :-/

3
  • What's wrong with the answer of @serge_gubenko to stackoverflow.com/questions/1864123 ? Commented Jan 8, 2010 at 8:24
  • Actually, I'd forgotten about the contents of the code in that answer. Thanks for bringing it up again. Commented Jan 8, 2010 at 17:33
  • That being said, the answer to that question ended up being something completely different.... the controls that needed to be drawn were being drawn out of the visible area. Oops :-) Commented Jan 8, 2010 at 17:35

1 Answer 1

3

Following the "dtb"'s comment, you can borrow some code from this SO entry.

The LPARAM you must supply is a pointer to the first element of the array. Then all you have to do is:

int[] parts = new int[]{ 1, 2, 3, 4 };
int nParts = parts.Length;
IntPtr pointer = Marshal.AllocHGlobal(nParts * Marshal.SizeOf(typeof(int)));
for (int i = 0; i < nParts; i++) {
    Marshal.WriteInt32(pointer, i * Marshal.SizeOf(typeof(int), parts[i]));
}
// Call SendMessage with WPARAM = nParts and LPARAM = Pointer
Marshal.FreeHGlobal(pointer);
Sign up to request clarification or add additional context in comments.

2 Comments

You are missing a bracket i think i * Marshal.SizeOf(typeof(int)
This should be fixed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.