PostMessage не может передать строку C # - PullRequest
3 голосов
/ 14 января 2010

Вот мой прототип:

    [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" в стеке одного потока, и эта ссылка абсолютно не имеет значения в стеке другого потока. Но если это так, действительно ли эти указатели wparam и lparam действительно используются только для сообщений, передаваемых в одном потоке?

Редактировать * Исправление: Под потоком я подразумеваю Процесс. Это проблема передачи строки между процессами, а не потоками.

Ответы [ 2 ]

1 голос
/ 14 января 2010

HGLOBAL больше не являются глобальными. Не начиная с win16. И HWND_BROADCAST выглядит так, как будто вы отправляете сообщение другому процессу, не говоря уже о другом потоке.

Итак, если вы не используете одно из стандартных сообщений, которые ОС знает, как выполнить маршалинг, вам нужно поместить строку «bob» в область общей памяти, к которой могут обращаться разные процессы.

0 голосов
/ 31 января 2012

Чтобы ответить на ваш последний вопрос. Я пробовал то же самое, и когда я пытался преобразовать 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 = msg.getWindowId(null, "The title of the form you want to send a message to");
    int result = msg.sendWindowsStringMessage(hWnd, 0, msg)
    //Or for an integer message
    result = msg.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);
}
...