2010-01-14 4 views
3

Вот мой прототип:PostMessage не в состоянии передать строку C#

[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); 

В другом потоке я могу перехватить это сообщение, но когда я пытаюсь получить обратную связь с помощью:

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

Я не получаю bob на ул.

Я думаю, что это связано с тем, что я ссылался на строку «bob» в стеке одного потока, и эта ссылка не имеет абсолютно никакого значения в стеке другого потока. Но если это так, эти указатели wparam и lparam действительно используются только для сообщений, передаваемых в одном потоке?

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

+0

Что вы пытаетесь достичь, и почему вы пытаетесь выполнить его таким образом? –

ответ

1

HGLOBALs arn't, в любом случае, глобальный. Не с победы16. И HWND_BROADCAST выглядит так, будто вы отправляете сообщение в другой процесс, не говоря уже о другом потоке.

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

+1

Крис, ты знаешь, как это сделать? Это так же просто, как использование другого метода маршала? – Nick

+0

см. Ответ nobugz для некоторых примеров методов межпроцессного процесса. Я действительно не вижу, что вы пытаетесь сделать с этим методом, поэтому трудно дать совет о том, какой механизм ipc будет лучше. Если вы отправляете оконные сообщения по какой-либо причине, WM_COPYDATA будет удобен, но никогда не будет транслироваться, поскольку другие приложения могут обрабатывать его своими ожиданиями полученных данных. –

0

Чтобы ответить на ваш последний вопрос. Я пробовал то же самое, и когда я пытался преобразовать 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); 
} 
+1

Я не понимаю, «... он работает очень нежно» – JYelton

+0

hmm. мягко или вы можете просто вырезать «очень нежные», – chrs

 Смежные вопросы

  • Нет связанных вопросов^_^