5

Here is my prototype:

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern bool PostMessage(int hhwnd, uint msg, IntPtr wparam, IntPtr lparam);

And here is how I'm using it:

PostMessage(HWND_BROADCAST, msg, Marshal.StringToHGlobalAuto("bob"), IntPtr.Zero);

In a different thread I can intercept this message, but when I try to get bob back using:

string str = Marshal.PtrToStringAuto(m.WParam); // where m = the Message object

I don't get bob in str.

I'm thinking this has got to be due to the fact that I referenced the "bob" string on one thread's stack and that reference has absolutely no meaning in a different thread's stack. But if that's the case, are these wparam and lparam pointers only really used for messages being passed in the same thread?

Edit* Correction: By thread I mean Process. This is a problem of passing a string between processes, not threads.

Nick
  • 2,913
  • 12
  • 40
  • 52

2 Answers2

2

To answer your last question. I have tried the same and when I tried to convert lParam to string and backwards in the same window it works very gentled, but not when passing to another window. So I tried to use SendMessage instead and that worked great.

http://boycook.wordpress.com/2008/07/29/c-win32-messaging-with-sendmessage-and-wm_copydata/

I downloaded this class and that worked very well. :)

Use like this:

    public void SendMsg(string msg)
{
    MessageHelper msgHelper = new MessageHelper();
    int hWnd = msgHelper.getWindowId(null, "The title of the form you want to send a message to");
    int result = msgHelper.sendWindowsStringMessage(hWnd, 0, msg);
    //Or for an integer message
    result = msgHelper.sendWindowsMessage(hWnd, MessageHelper.WM_USER, 123, 456);
}

//In your form window where you want to receive the message

protected override void WndProc(ref Message m)
{
    switch (m.Msg)
    {
        case MessageHelper.WM_USER:
            MessageBox.Show("Message recieved: " + m.WParam + " - " + m.LParam);
            break;
        case MessageHelper.WM_COPYDATA:
            MessageHelper.COPYDATASTRUCT mystr = new MessageHelper.COPYDATASTRUCT();
            Type mytype = mystr.GetType();
            mystr = (COPYDATASTRUCT)m.GetLParam(mytype);
            MessageBox.Show(mystr.lpData);
            break;
    }
    base.WndProc(ref m);
}
F.zehra
  • 87
  • 8
chrs
  • 5,906
  • 10
  • 43
  • 74
1

HGLOBALs arn't, in any way, global anymore. Not since win16. And HWND_BROADCAST looks like you are sending the message to a different process, never mind just a different thread.

So, unless you either use one of the standard messages that the OS knows how to marshal, you need to place your string, "bob" in a shared memory area that different processes can access.

Chris Becke
  • 34,244
  • 12
  • 79
  • 148
  • 1
    Chris, do you know how to do either one of those? Is it as simple as using a different Marshal method? – Nick Jan 14 '10 at 19:00
  • see nobugz's answer for some examples of inter process methods. I don't really see what you are trying to do with this method, so its hard to give advice on what ipc mechanism would be best. If you are sending window messages for whatever reason, WM_COPYDATA would be convenient, but never broadcast as other apps might be handling it with their own expectations of the data received. – Chris Becke Jan 14 '10 at 20:29