2010-01-14 6 views
3

Voici mon prototype:PostMessage incapable de passer une chaîne C#

[DllImport("user32.dll", CharSet = CharSet.Auto)] 
    public static extern bool PostMessage(int hhwnd, uint msg, IntPtr wparam, IntPtr lparam); 

Et voici comment je l'utilise:

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

Dans un autre thread que je peux intercepter ce message, mais quand j'essaye d'obtenir bob en utilisant:

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

Je ne comprends pas bob dans str. Je pense que cela doit être dû au fait que j'ai référencé la chaîne "bob" sur la pile d'un thread et que cette référence n'a absolument aucun sens dans la pile d'un thread différent. Mais si c'est le cas, ces pointeurs wparam et lparam ne sont-ils vraiment utilisés que pour les messages passés dans le même thread?

Modifier * Correction: Par fil, je veux dire Process. C'est un problème de passage d'une chaîne entre les processus, pas de threads.

+0

Qu'est-ce que vous essayez d'accomplir, et pourquoi vous essayez d'accomplir de cette façon? –

Répondre

1

Les HGLOBAL ne sont plus globales. Pas depuis win16. Et HWND_BROADCAST semble que vous envoyez le message à un processus différent, sans parler d'un fil différent. Donc, à moins que vous n'utilisiez l'un des messages standard que le système d'exploitation sait comment marshaler, vous devez placer votre chaîne, "bob" dans une zone de mémoire partagée à laquelle différents processus peuvent accéder.

+1

Chris, savez-vous comment faire l'une ou l'autre? Est-ce aussi simple que d'utiliser une méthode Marshal différente? – Nick

+0

Voir la réponse de nobugz pour quelques exemples de méthodes inter processus. Je ne vois pas vraiment ce que vous essayez de faire avec cette méthode, donc c'est difficile de donner des conseils sur ce que le mécanisme ipc serait le mieux. Si vous envoyez des messages de fenêtre pour une raison quelconque, WM_COPYDATA serait pratique, mais jamais diffusé car d'autres applications pourraient le gérer avec leurs propres attentes des données reçues. –

0

Pour répondre à votre dernière question. J'ai essayé la même chose et quand j'ai essayé de convertir lParam en chaîne et en arrière dans la même fenêtre cela fonctionne très doucement, mais pas en passant à une autre fenêtre. J'ai donc essayé d'utiliser SendMessage à la place et cela a très bien fonctionné.

http://boycook.wordpress.com/2008/07/29/c-win32-messaging-with-sendmessage-and-wm_copydata/

J'ai téléchargé cette classe et cela a fonctionné très bien. :)

Utilisez comme ceci:

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

Je ne comprends pas "... ça marche très bien" – JYelton

+0

hmm. doucement ou vous pouvez simplement couper le "très gentil" – chrs

Questions connexes