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

我没有在 str 中得到 bob。

我认为这一定是因为我在一个线程的堆栈上引用了“bob”字符串,并且该引用在另一个线程的堆栈中绝对没有意义。但如果是这样的话,这些 wparam 和 lparam 指针真的只用于在同一个线程中传递的消息吗?

编辑* 更正:通过线程我的意思是进程。这是在进程而不是线程之间传递字符串的问题。

4

2 回答 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);
}
于 2012-01-31T10:03:28.267 回答
1

HGLOBAL 无论如何都不再是全球性的了。从win16开始没有。并且 HWND_BROADCAST 看起来您正在将消息发送到不同的进程,更不用说只是一个不同的线程。

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

于 2010-01-14T18:58:24.807 回答