473,387 Members | 1,548 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Marshaling a string (and struct) for call to SendMessage

I am attempting to set the text on a richedit control in another application
using EM_SETTEXTEX:
http://msdn.microsoft.com/library/de..._settextex.asp

I have the following:

[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int
lParam);

[StructLayout(LayoutKind.Sequential)]
public struct SETEXTEX
{
public uint flags;
public uint codepage;
};
private void SetRichEditText(IntPtr hWnd, string text)
{
SETEXTEX setextex = new SETEXTEX();
setextex.codepage = 0;
setextex.flags = 0;
IntPtr ptr =
System.Runtime.InteropServices.Marshal.AllocCoTask Mem(System.Runtime.Interop
Services.Marshal.SizeOf(setextex.GetType()));
System.Runtime.InteropServices.Marshal.StructureTo Ptr(setextex, ptr,
true);
IntPtr sPtr = System.Runtime.InteropServices.Marshal.StringToBST R(text);
Win32API.SendMessage(hWnd, Messages.WM_USER+97, ptr.ToInt32(),
sPtr.ToInt32());
System.Runtime.InteropServices.Marshal.FreeCoTaskM em(ptr);
System.Runtime.InteropServices.Marshal.FreeBSTR(sP tr);
}

This code, while running without error, gives garbage in the richedit
control. If I change the StringToBSTR to StringToCoTaskMemAnsi or
StringToCoTaskMemAuto, then the other program crashes upon calling
SendMessage. Any ideas on what I'm doing wrong here?

--
Adam Clauss
ca*****@tamu.edu
Nov 16 '05 #1
5 5829
Adam,

You will have to find another way to marshal the string across the
process boundary. When you allocate memory in the local process, the
address that is returned is valid only in the local process. When you
transmit that value across the process boundary (which is what SendMessage
does, it only sends the pointer values, not the values the pointers point
to), the pointer is invalidated, because it is now in a different virtual
address space.

If you want to share some values, you will have to use another
mechanism, such as remoting, sockets, pipes, shared files, etc, etc.
Basically, you need some way of actually sending the bits that you want, and
not pointers to them.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Adam Clauss" <ca*****@tamu.edu> wrote in message
news:eM**************@TK2MSFTNGP10.phx.gbl...
I am attempting to set the text on a richedit control in another application using EM_SETTEXTEX:
http://msdn.microsoft.com/library/de..._settextex.asp
I have the following:

[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

[StructLayout(LayoutKind.Sequential)]
public struct SETEXTEX
{
public uint flags;
public uint codepage;
};
private void SetRichEditText(IntPtr hWnd, string text)
{
SETEXTEX setextex = new SETEXTEX();
setextex.codepage = 0;
setextex.flags = 0;
IntPtr ptr =
System.Runtime.InteropServices.Marshal.AllocCoTask Mem(System.Runtime.Interop Services.Marshal.SizeOf(setextex.GetType()));
System.Runtime.InteropServices.Marshal.StructureTo Ptr(setextex, ptr,
true);
IntPtr sPtr = System.Runtime.InteropServices.Marshal.StringToBST R(text); Win32API.SendMessage(hWnd, Messages.WM_USER+97, ptr.ToInt32(),
sPtr.ToInt32());
System.Runtime.InteropServices.Marshal.FreeCoTaskM em(ptr);
System.Runtime.InteropServices.Marshal.FreeBSTR(sP tr);
}

This code, while running without error, gives garbage in the richedit
control. If I change the StringToBSTR to StringToCoTaskMemAnsi or
StringToCoTaskMemAuto, then the other program crashes upon calling
SendMessage. Any ideas on what I'm doing wrong here?

--
Adam Clauss
ca*****@tamu.edu

Nov 16 '05 #2
Thats... not good. Is there no way to do this through SendMessage? I do not have control over the other app (its actually an
Windows Installer - I am trying to fill some info in on one of the pages). Since I obviously can't modify the installer itself, I
don't think I can use any of the other methods you mentioned can I?

--
Adam Clauss
ca*****@tamu.edu
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in message news:OI**************@TK2MSFTNGP12.phx.gbl...
Adam,

You will have to find another way to marshal the string across the
process boundary. When you allocate memory in the local process, the
address that is returned is valid only in the local process. When you
transmit that value across the process boundary (which is what SendMessage
does, it only sends the pointer values, not the values the pointers point
to), the pointer is invalidated, because it is now in a different virtual
address space.

If you want to share some values, you will have to use another
mechanism, such as remoting, sockets, pipes, shared files, etc, etc.
Basically, you need some way of actually sending the bits that you want, and
not pointers to them.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Adam Clauss" <ca*****@tamu.edu> wrote in message
news:eM**************@TK2MSFTNGP10.phx.gbl...
I am attempting to set the text on a richedit control in another

application
using EM_SETTEXTEX:

http://msdn.microsoft.com/library/de..._settextex.asp

I have the following:

[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam,

int
lParam);

[StructLayout(LayoutKind.Sequential)]
public struct SETEXTEX
{
public uint flags;
public uint codepage;
};
private void SetRichEditText(IntPtr hWnd, string text)
{
SETEXTEX setextex = new SETEXTEX();
setextex.codepage = 0;
setextex.flags = 0;
IntPtr ptr =

System.Runtime.InteropServices.Marshal.AllocCoTask Mem(System.Runtime.Interop
Services.Marshal.SizeOf(setextex.GetType()));
System.Runtime.InteropServices.Marshal.StructureTo Ptr(setextex, ptr,
true);
IntPtr sPtr =

System.Runtime.InteropServices.Marshal.StringToBST R(text);
Win32API.SendMessage(hWnd, Messages.WM_USER+97, ptr.ToInt32(),
sPtr.ToInt32());
System.Runtime.InteropServices.Marshal.FreeCoTaskM em(ptr);
System.Runtime.InteropServices.Marshal.FreeBSTR(sP tr);
}

This code, while running without error, gives garbage in the richedit
control. If I change the StringToBSTR to StringToCoTaskMemAnsi or
StringToCoTaskMemAuto, then the other program crashes upon calling
SendMessage. Any ideas on what I'm doing wrong here?

--
Adam Clauss
ca*****@tamu.edu


Nov 16 '05 #3
Hi Adam,

"Adam Clauss" <ca*****@tamu.edu> wrote in message
news:eQ**************@TK2MSFTNGP10.phx.gbl...
Thats... not good. Is there no way to do this through SendMessage? I do not have control over the other app (its actually an Windows Installer - I am trying to fill some info in on one of the pages). Since I obviously can't modify the installer itself, I don't think I can use any of the other methods you mentioned can I?


Just an FYI, if the installation package is an ".msi" file then you
*could* change it. Whether it is practical to do so is another matter, of
course. Windows Installer installation packages are actually stand-alone
databases (rather like Access .mdb files) with a specific set of tables.
There is a COM API for modifying the contents of the tables (Microsoft
Windows Installer Object Library: %windir%\system32\msi.dll).

Regards,
Daniel
Nov 16 '05 #4
Interesting, I'll have to look into that. It could greatly speed up some of what I am doing.

In the meantime, the workaround I just got working (not pretty, nor efficient, but it works) is to just repeatedly send WM_CHAR
messages to the richedit. Seems to have done the job. Fortunately, the strings I am sending are not too long.

--
Adam Clauss
ca*****@tamu.edu
"Daniel Pratt" <ko******************@hotmail.com> wrote in message news:%2****************@TK2MSFTNGP11.phx.gbl...
Hi Adam,

"Adam Clauss" <ca*****@tamu.edu> wrote in message
news:eQ**************@TK2MSFTNGP10.phx.gbl...
Thats... not good. Is there no way to do this through SendMessage? I do

not have control over the other app (its actually an
Windows Installer - I am trying to fill some info in on one of the pages).

Since I obviously can't modify the installer itself, I
don't think I can use any of the other methods you mentioned can I?


Just an FYI, if the installation package is an ".msi" file then you
*could* change it. Whether it is practical to do so is another matter, of
course. Windows Installer installation packages are actually stand-alone
databases (rather like Access .mdb files) with a specific set of tables.
There is a COM API for modifying the contents of the tables (Microsoft
Windows Installer Object Library: %windir%\system32\msi.dll).

Regards,
Daniel

Nov 16 '05 #5
"Adam Clauss" <ca*****@tamu.edu> wrote in message
news:OF**************@TK2MSFTNGP11.phx.gbl...
Interesting, I'll have to look into that. It could greatly speed up some of what I am doing.
In the meantime, the workaround I just got working (not pretty, nor efficient, but it works) is to just repeatedly send WM_CHAR messages to the richedit. Seems to have done the job. Fortunately, the strings I am sending are not too long.

Hi Adam,

Have a look at the WM_SETTEXT and (EM_SETTEXTEX for RTF) messages. And if
you want to replace part of the existing text, check the EM_SETSEL and
EM_REPLACESEL.

Another way of sending a string to this richedit would be to copy it to the
Clipboard and then send the WM_PASTE message to the window. But I do not
recommend this way, because your string may get corrupted by other apps or
user activities.

Regards,

Stoil

--
Adam Clauss
ca*****@tamu.edu
"Daniel Pratt" <ko******************@hotmail.com> wrote in message

news:%2****************@TK2MSFTNGP11.phx.gbl...
Hi Adam,

"Adam Clauss" <ca*****@tamu.edu> wrote in message
news:eQ**************@TK2MSFTNGP10.phx.gbl...
Thats... not good. Is there no way to do this through SendMessage? I
do not have control over the other app (its actually an
Windows Installer - I am trying to fill some info in on one of the
pages). Since I obviously can't modify the installer itself, I
don't think I can use any of the other methods you mentioned can I?


Just an FYI, if the installation package is an ".msi" file then you
*could* change it. Whether it is practical to do so is another matter, of course. Windows Installer installation packages are actually stand-alone
databases (rather like Access .mdb files) with a specific set of tables.
There is a COM API for modifying the contents of the tables (Microsoft
Windows Installer Object Library: %windir%\system32\msi.dll).

Regards,
Daniel



Nov 16 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Webdiyer | last post by:
I want to integrate SecurID two-factor authentication system of the RSASecurity.inc into our asp.net application,but I get into trouble when trying to call the API functions of the ACE Agent,I got...
5
by: VM | last post by:
What's marshalling? I've had to use it extensively for a project but I don't know what it means. I tried to look for a definition in the Internet but I couldn't find anything that would explain...
2
by: Pas de Spam | last post by:
Hi, I have some problem in marshaling array of structure. I have to exchange a structure of data with a C++ program. This structure data contains a field which is an array of a custom type. I...
2
by: Ryan Ross | last post by:
Hello, I need some help with the SendMessage method. I've imported it into C# with the following statement: public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, long wparam, int...
0
by: weixian_shen | last post by:
I'm trying to call my DLL written in C, and got the error: Cannot marshal field 'b' of type 'mystruct': There is no marshaling support for this type. The 2 functions in the DLL are: void...
8
by: Just Me | last post by:
I have SendMessage declared with the last two parameters as ByVal IntPtr I need to call it with an Integer value and a Byte array pointer. The Integer is while the Byte array is I could...
23
by: Ben Voigt | last post by:
I have a POD type with a private destructor. There are a whole hierarchy of derived POD types, all meant to be freed using a public member function Destroy in the base class. I get warning C4624....
6
by: Aston Martin | last post by:
Hi All, ********************** My Situation ********************** I am working on project that involves passing a structure to unmanaged code from .Net world (well using C#). Perhaps an example...
5
by: michelqa | last post by:
Hi, I need to call a lot of different native SendMessage to retreive informations from non managed application. Some win32 messages use struct pointer for lparam....how to create and...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.