By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,862 Members | 1,767 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,862 IT Pros & Developers. It's quick & easy.

Interop SendMessage : How to pass Structure to be filled bySendMessage

P: n/a
Hi,

I already post a similar question last week without success.

Ok I want to get the current text selection in a RICHEDIT control..
This can be easily done in C++ with EM_EXGETSEL message. I really
need to do the same thing in C#.

How can I put the structure in memory to be able to call SendMessage
and get the expected results in the structure.

Im playing with the following code but the target application always
crash.
For using the following example you need to start WordPad.exe (not
notepad), manually get the handle of the RichEdit control with Spy++
and replace the handle parameter in the sendmessage

initial condition : Type and select some text in WordPad

The following code must return Starting and ending position of
selected text in WordPad.

using System;
using System.Collections;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Diagnostics;

//..
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hwnd, int msg, IntPtr
wparam, IntPtr lparam);
private const int WM_USER = 1024;
private const int EM_EXGETSEL = WM_USER + 52;

[StructLayout(LayoutKind.Sequential)]
public struct CharRange
{
public int From;
public int To;
public CharRange(int from, int to)
{
this.From = from;
this.To = to;
}
}
//..
CharRange ChrRange= new CharRange();
IntPtr ChrRangePtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(ChrRange));
Marshal.StructureToPtr(ChrRange,ChrRangePtr, false);
SendMessage(Handle,EM_EXGETSEL,IntPtr.Zero,ChrRang ePtr);
Marshal.PtrToStructure(ChrRangePtr,ChrRange);
MessageBox.Show("From="+ChrRange.From.ToString()+" ,
to="+ChrRange.To.ToString());

Is anybody know how to correctly code the structure pointer marshaling
part??? How to make this simple example working?

Please help me if you can.. :(
Jul 24 '08 #1
Share this Question
Share on Google+
3 Replies


P: n/a
On Jul 25, 2:30*am, michelqa <miche...@yahoo.cawrote:
Hi,

I already post a similar question last week without success.

Ok I want to get the current text selection in a RICHEDIT control..
This can be easily done in C++ with EM_EXGETSEL message. *I really
need to do the same thing in C#.

How can I put the structure in memory to be able to call SendMessage
and get the expected results in the structure.

Im playing with the following code but the target application always
crash.
For using the following example you need to start WordPad.exe (not
notepad), manually get the handle of the RichEdit control with Spy++
and replace the handle parameter in the sendmessage

initial condition : Type and select some text in WordPad

The following code must return Starting and ending position of
selected text in WordPad.

using System;
using System.Collections;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Diagnostics;

//..
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hwnd, int msg, IntPtr
wparam, IntPtr lparam);

private const int WM_USER = 1024;
private const int EM_EXGETSEL * * * * * * *= WM_USER + *52;

[StructLayout(LayoutKind.Sequential)]
public struct CharRange
{
* * * * public int From;
* * * * public int To;
* * * * * * * * public CharRange(int from, int to)
* * * * {
* * * * * * * * this.From = from;
* * * * * * * * this.To = to;
* * * * }}

//..
CharRange ChrRange= new CharRange();
IntPtr ChrRangePtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(ChrRange));
Marshal.StructureToPtr(ChrRange,ChrRangePtr, false);
SendMessage(Handle,EM_EXGETSEL,IntPtr.Zero,ChrRang ePtr);
Marshal.PtrToStructure(ChrRangePtr,ChrRange);
MessageBox.Show("From="+ChrRange.From.ToString()+" ,
to="+ChrRange.To.ToString());

Is anybody know how to correctly code the structure pointer marshaling
part??? *How to make this simple example working?
At the first glance your declarations are okay. The problem seems to
be this:

Marshal.PtrToStructure(ChrRangePtr,ChrRange);

It doesn't work like that. The signature of this method is:

public static void PtrToStructure(
IntPtr ptr,
Object structure
);

It is actually quite misleading, but the second argument named
"structure" actually is of type object - so when you pass a struct
(i.e. a value type) to it, it gets boxed first, and the method
operates on that boxed copy. In fact, this method tries to detect
this, as described in MSDN:

"Exceptions: ArgumentException when structure layout is not
sequential or explicit or structure is a boxed value type."

What you need to do is to use the second overload, like this:

ChrRange = (CharRange)PtrToStructure(ChrRangePtr,
typeof(CharRanger));

See if that helps.

Also, don't forget to free the memory block you've allocated - GC
won't do it for you.
Jul 25 '08 #2

P: n/a
CharRange ChrRange= new CharRange();
IntPtr ChrRangePtr =
Marshal.AllocCoTaskMem(Marshal.SizeOf(ChrRange));
Marshal.StructureToPtr(ChrRange,ChrRangePtr, false);
Win32.SendMessage(Handle,
(int)Win32.WindowsMessages.EM_EXGETSEL,IntPtr.Zero ,ChrRangePtr);
ChrRange =
(CharRange)Marshal.PtrToStructure(ChrRangePtr,type of(CharRange));
MessageBox.Show("From="+ChrRange.From.ToString()+" ,
to="+ChrRange.To.ToString());
Marshal.FreeCoTaskMem(ChrRangePtr);

the target application is still crashing when executing SendMessage :
The memory could not be 'written'

What is wrong with my ChrRangePtr???

Note: In my test the target application is WordPad.exe and Handle is
the RichEdit Handle

Jul 25 '08 #3

P: n/a
I Found the answer here : http://www.codeproject.com/KB/thread..._memsteal.aspx

Aug 11 '08 #4

This discussion thread is closed

Replies have been disabled for this discussion.