473,385 Members | 1,356 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,385 software developers and data experts.

SendMessage WM_COPYDATA

I am trying to send a WM_COPYDATA message to another application in C#,
..NET 2.0.

The other application receives the message, but only seems to see the
first character of the string, does anybody have any ideas?

I have copied the code below.

class WIN32 {

//SendMessage
[System.Runtime.InteropServices.DllImport("user32.d ll")]
public static extern int SendMessage(System.IntPtr hwnd, int
msg, int wparam, int lparam);
//Copy Data Structure
public struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public int lpData;
}

public static int VarPtr(object e)
{
System.Runtime.InteropServices.GCHandle GC =
System.Runtime.InteropServices.GCHandle.Alloc(e,
System.Runtime.InteropServices.GCHandleType.Pinned );
int gc = GC.AddrOfPinnedObject().ToInt32();
GC.Free();
return gc;
}

}

public class SendTheMessage {

public SendTheMessage(string str, System.IntPtr handle,
System.IntPtr iHandle, System.UInt32 signature) {
Win32.COPYDATASTRUCT cds;

cds.dwData = Convert.ToInt32(signature);
str = str + '\0';
cds.cbData = 3;
cds.lpData = Win32.VarPtr(str);

Win32.SendMessage(handle, Win32.WM_COPYDATA,
0, Win32.VarPtr(cds));
}

}

Jun 3 '06 #1
4 15562
> class WIN32 {

Is Win32 {

public class SendTheMessage {

public SendTheMessage(string str, System.IntPtr handle,
System.IntPtr iHandle, System.UInt32 signature) {
Win32.COPYDATASTRUCT cds;

cds.dwData = Convert.ToInt32(signature);
str = str + '\0';
cds.cbData = 3;


is str.Length (and tried str.Length * 2 ). It's only 3 here from
testing!

Jun 3 '06 #2
>The other application receives the message, but only seems to see the
first character of the string, does anybody have any ideas?
How does the recieving code look like?

//SendMessage
[System.Runtime.InteropServices.DllImport("user32.d ll")]
public static extern int SendMessage(System.IntPtr hwnd, int
msg, int wparam, int lparam);
This is better declared as

[System.Runtime.InteropServices.DllImport("user32.d ll",
CharSet=CharSet.Auto)]
public static extern IntPtr SendMessage(System.IntPtr hwnd, int msg,
IntPtr wparam, ref COPYDATASTRUCT lparam);

//Copy Data Structure
public struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public int lpData;
}
lpData and dwData should be IntPtrs.

public static int VarPtr(object e)
{
System.Runtime.InteropServices.GCHandle GC =
System.Runtime.InteropServices.GCHandle.Alloc(e ,
System.Runtime.InteropServices.GCHandleType.Pinne d);
int gc = GC.AddrOfPinnedObject().ToInt32();
GC.Free();
return gc;
}


This is completely broken. If a garbage collection happens after the
GC.Free call, your pointer is invalid. Use one of the
Marshal.StringTo* methods to copy the string to a native buffer
instead, and assign the result to cds.lpData.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Jun 3 '06 #3
Mattias Sjögren wrote:
The other application receives the message, but only seems to see the
first character of the string, does anybody have any ideas?
How does the recieving code look like?


I dont know, this is in a closed source application. Applications
written in other languages seem to have no problem communicating with
it, so it must be an error in my C# code.

//Copy Data Structure
public struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public int lpData;
}


lpData and dwData should be IntPtrs.


Yes, I have changed that. They were originally, but changed a lot to
retry. I have changed the last paramenter of SendMessage to an IntPtr
public static int VarPtr(object e)
{
System.Runtime.InteropServices.GCHandle GC =
System.Runtime.InteropServices.GCHandle.Alloc(e ,
System.Runtime.InteropServices.GCHandleType.Pinne d);
int gc = GC.AddrOfPinnedObject().ToInt32();
GC.Free();
return gc;
}


This is completely broken. If a garbage collection happens after the
GC.Free call, your pointer is invalid. Use one of the
Marshal.StringTo* methods to copy the string to a native buffer
instead, and assign the result to cds.lpData.


Thanks. I copied that somewhere off the internet, which I knew would
be a bad idea.

I have changed that method to look like this now, but the same result
occurs, the receiving application is only receiving the first 1
character.

I also tried:
cds.lpData =
System.Runtime.InteropServices.Marshal.StringToCoT askMemAnsi(str);

Because this is the reverse of what I do in my overridden wndproc:

string str =
System.Runtime.InteropServices.Marshal.PtrToString Ansi(cds.lpData);

this str, in wndproc, always contains the full string the application
sent me.

--- Updated Function Code ---
Win32.COPYDATASTRUCT cds;

cds.dwData = new System.IntPtr(sig);
str = str + '\0';
cds.cbData = str.Length;
cds.lpData =
System.Runtime.InteropServices.Marshal.AllocCoTask Mem(str.Length);

System.Runtime.InteropServices.Marshal.Copy(str.To CharArray(), 0,
cds.lpData, str.Length);

System.IntPtr iPtr =
System.Runtime.InteropServices.Marshal.AllocCoTask Mem(System.Runtime.InteropServices.Marshal.SizeOf( cds));
System.Runtime.InteropServices.Marshal.StructureTo Ptr(cds,
iPtr, true);

Win32.SendMessage(handle, Win32.WM_COPYDATA, iHandle,
iPtr);

//I would add some code here to Free the Memory

Jun 3 '06 #4
> I also tried:
cds.lpData =
System.Runtime.InteropServices.Marshal.StringToCoT askMemAnsi(str);

Because this is the reverse of what I do in my overridden wndproc:

string str =
System.Runtime.InteropServices.Marshal.PtrToString Ansi(cds.lpData);


This actually did work. I forgot to comment the line below it which
was doing what my old code did.

Thanks Mattias your post got me on right track to making it all work.
For anybody that cares, here
is the code:
Win32.COPYDATASTRUCT cds;

cds.dwData = new System.IntPtr(sig);
str = str + '\0';
cds.cbData = str.Length + 1;
cds.lpData =
System.Runtime.InteropServices.Marshal.AllocCoTask Mem(str.Length);

cds.lpData =
System.Runtime.InteropServices.Marshal.StringToCoT askMemAnsi(str);

System.IntPtr iPtr =
System.Runtime.InteropServices.Marshal.AllocCoTask Mem(System.Runtime.InteropServices.Marshal.SizeOf( cds));
System.Runtime.InteropServices.Marshal.StructureTo Ptr(cds,
iPtr, true);

Win32.SendMessage(handle, Win32.WM_COPYDATA, iHandle,
iPtr);
System.Runtime.InteropServices.Marshal.FreeCoTaskM em(cds.lpData);
System.Runtime.InteropServices.Marshal.FreeCoTaskM em(iPtr);

Jun 3 '06 #5

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

Similar topics

8
by: g.franzkowiak | last post by:
Hello everybody, I've tryed to use an interprocess communication via SendMessage on Windows. Unfortunately, nothing goes on ...
2
by: Erik | last post by:
I am having trouble getting this to work so hopefully someone can provide some insite. I have a structure that I store in a CopyDataStruct which is then send to another application via...
2
by: James Burrow | last post by:
Hi, I am trying to write a 2 .net programs that can communicate via windows messages. I have achieved this but only just passing ints. When i try and pass a string, i get junk out. I guess this...
0
by: Augie | last post by:
Dear All, I came across this piece of code to send a message. I have this setup and running... getting all the WM_COPYDATA messages on the client side. However I can't see the contexts of the...
1
by: Daniel Halan | last post by:
Hello, I want to send a SendMessage(hwnd,...) to an another application containing eighter a "String" or a PIDL... I know that the pointer lives in its own process so the other app will have...
1
by: alexwhitman | last post by:
Hi, I'm trying to port a c++ class to c# and in the c++ class I have a struct defined as: struct SNARLSTRUCT { SNARL_COMMANDS cmd; long id; long timeout; long lngData2; char title;
1
by: Thomas Kehl | last post by:
Hello. I use the fallowing Functions to send Message from one Application to another. This is working correct on a 32bit System. But on a 64Bit System, the Target-Application will no received...
14
by: Kerem Gümrükcü | last post by:
Hi, i want to emulate a (synchronous) BroadCastSystemMessage with EnumWindows and SendMessage. I dont want to use the BroadcastSystemMessage because it needs the SE_TCB_NAME Privilege (you...
1
by: xMetalDetectorx | last post by:
I have two C# Applications. The first application has to send 2 strings to the other application. The first string is just a simple string "abc", while the 2nd string contains a path...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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: 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...

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.