PostMessage无法传递字符串 C#

5
这是我的原型:
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern bool PostMessage(int hhwnd, uint msg, IntPtr wparam, IntPtr lparam);

以下是我如何使用它:

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

在不同的线程中,我可以拦截这条消息,但是当我尝试使用以下语句获取bob时:
string str = Marshal.PtrToStringAuto(m.WParam); // where m = the Message object

我不明白如何将字符串“bob”转换成字符串。

我认为这可能是因为我在一个线程的堆栈上引用了“bob”字符串,而在另一个线程的堆栈上该引用没有任何意义。但如果是这样的话,那么这些wparam和lparam指针只有在传递消息到同一线程时才真正被使用吗?

编辑* 更正:我所说的“线程”实际上是“进程”。这是在进程之间传递字符串的问题,而不是在线程之间。


你想要达成什么目标,为什么要用这种方式来实现它? - John Saunders
2个回答

2
回答你的最后一个问题。我尝试过将lParam转换为字符串并在同一窗口中反向操作,它非常平稳,但是当传递到另一个窗口时就不行了。因此,我尝试使用SendMessage代替,效果很好。
可以像这样使用:http://boycook.wordpress.com/2008/07/29/c-win32-messaging-with-sendmessage-and-wm_copydata/ 我下载了这个类,效果非常好。 :)
    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);
}

1

HGLOBAL 不再是全局的了,自从 win16 以来就不是了。HWND_BROADCAST 看起来像是你正在将消息发送到另一个进程,更别说只是不同的线程了。

因此,除非你使用操作系统知道如何编排的标准消息之一,否则你需要将字符串 "bob" 放在不同进程可以访问的共享内存区域中。


1
Chris,你知道怎么做其中之一吗?是不是只需要使用不同的Marshal方法就可以了? - Nick
看不太懂你想用这个方法做什么,所以很难给出哪种IPC机制最好的建议。如果你因为某些原因正在发送窗口消息,WM_COPYDATA会很方便,但永远不要广播,因为其他应用程序可能会按照自己对接收到的数据的期望进行处理。 - Chris Becke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接