PostMessage 无法传递字符串 C#

发布于 2024-08-17 17:10:10 字数 676 浏览 12 评论 0原文

这是我的原型:

    [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 指针是否只真正用于在同一线程中传递消息?

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浴红衣 2024-08-24 17:10:10

回答你的最后一个问题。我也尝试过同样的操作,当我尝试将 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);
}

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);
}
波浪屿的海角声 2024-08-24 17:10:10

无论如何,HGLOBAL 都不再是全球性的了。 win16以后就没有了。 HWND_BROADCAST 看起来就像您正在将消息发送到不同的进程,而不必介意只是不同的线程。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文