2016-09-28 1 views
-2

J'ai regardé cette question et répondre àC# je suis incapable d'obtenir SendMessage pour envoyer un message à une fenêtre de bloc-notes

How to send text to Notepad in C#/Win32?

Une légère variation que je pense ne devrait pas question .. Est-ce J'ai un tas de fenêtres de bloc-notes .. Ainsi, pour tester cela, j'ai copié notepad.exe pour être notepadd.exe et ouvert notepadd.exe, de sorte qu'une seule de mes fenêtres bloc-notes est le processus notepadd.exe.

J'ai ce code

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using System.Diagnostics; 

namespace testsendmessage 
{ 

    public partial class Form1 : Form 
    { 
     [DllImport("user32.dll", EntryPoint = "FindWindowEx")] 
     public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 
     [DllImport("User32.dll")] 
     public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam); 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 

     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      Process[] notepads = Process.GetProcessesByName("notepadd"); 
      if (notepads.Length == 0) return; 
      if (notepads[0] != null) 
      { 
       IntPtr child = FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null); 
       SendMessage(child, 0x000C, 0, "abcd"); 
      } 
     } 
    } 
} 

Ce n'est pas toucher la fenêtre du bloc-notes si.

J'ai essayé le débogage et je vois que le tableau a un élément blocs-notes, ce qui est certainement correct.

Et il obtient dans le « si » et il fonctionne SendMessage(child, 0x000C, 0, "abcd");

Mais je ne vois rien qui apparaît dans la fenêtre du bloc-notes

Je ne reçois pas une erreur du code, il est tout simplement rien apparaître dans le bloc-notes fenêtre .. Et je ne comprends pas vraiment beaucoup de trucs winapi, donc je ne suis pas sûr de savoir comment procéder pour essayer de le résoudre? Comme vous pouvez le voir, il atteint cette ligne, et je peux utiliser la fenêtre de la montre pour voir le bloc de processus Bloc-notes, et 'enfant' mais je ne sais pas ce que je devrais regarder pour déterminer pourquoi ce n'est pas envoyer à la fenêtre

enter image description here

Ajouté

Nouveau code basé sur la suggestion de Remy

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using System.Diagnostics; 

namespace testsendmessage 
{ 

    public partial class Form1 : Form 
    { 
     [DllImport("user32.dll", EntryPoint = "FindWindowEx")] 
     public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 

     [DllImport("User32.dll", CharSet = CharSet.Unicode, EntryPoint = "SendMessageW")] 
     public static extern IntPtr SendMessageWStr(IntPtr hWnd, uint uMsg, IntPtr wParam, string lParam); 

     const uint WM_SETTEXT = 0x000C; 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 

     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      Process[] notepads = Process.GetProcessesByName("notepadd"); 
      if (notepads.Length == 0) return; 
      if (notepads[0] != null) 
      { 
       IntPtr child = FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null); 
       SendMessageWStr(child, WM_SETTEXT, IntPtr.Zero, "abcd"); 
      } 

     } 
    } 
} 

Mais j'ai toujours le même problème que la fenêtre du bloc-notes était vide avant de cliquer sur le bouton et est vide après aussi. Il n'envoie pas le texte dans la fenêtre notepadd. En dépit du fait qu'il atteint cette ligne de code qui est destinée à lui envoyer le texte.

plus loin.

Code actuel,

J'ai changé FindWindowEx à FindWindowExW et j'ai changé nouveau IntPtr (0) à IntPtr.Zero et il ne répond toujours pas.

J'ai ouvert notepadd.exe de cmd, je vois la fenêtre là-bas. Et bien sûr notepadd.exe dans le gestionnaire de tâches, mais en cliquant sur le bouton dans mon application n'écrit aucun texte dans cette fenêtre.

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using System.Diagnostics; 

namespace testsendmessage 
{ 

    public partial class Form1 : Form 
    { 
     [DllImport("user32.dll", EntryPoint = "FindWindowExW")] 

     public static extern IntPtr FindWindowExW(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 

     [DllImport("User32.dll", CharSet = CharSet.Unicode, EntryPoint = "SendMessageW")] 
     public static extern IntPtr SendMessageWStr(IntPtr hWnd, uint uMsg, IntPtr wParam, string lParam); 

     const uint WM_SETTEXT = 0x000C; 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 

     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      Process[] notepads = Process.GetProcessesByName("notepadd"); 
      if (notepads.Length == 0) return; 
      if (notepads[0] != null) 
      { 
       IntPtr child = FindWindowExW(notepads[0].MainWindowHandle, IntPtr.Zero, "Edit", null); 
       SendMessageWStr(child, WM_SETTEXT, IntPtr.Zero, "abcd"); 
      } 

     } 
    } 
} 
+0

Quelle est la valeur de retour de 'SendMessage()'? Comme [documenté] (https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms632644.aspx): "* La valeur renvoyée est" TRUE "si le texte est défini," FALSE " (pour un contrôle d'édition), 'LB_ERRSPACE' (pour une zone de liste), ou' CB_ERRSPACE' (pour une zone de liste déroulante) s'il n'y a pas assez d'espace pour définir le texte dans le champ de saisie, c'est 'CB_ERR' si ce message est envoyé à une zone de liste déroulante sans un contrôle d'édition. * " –

+0

@RemyLebeau ce que j'espère pour le moment est un ajustement qui ferait du code que j'ai dans une démo de travail .. Je sais très peu de choses sur le winapi, PInvoke , MarshalAs etc. – barlop

+0

Essayez quelque chose de plus comme ceci: 'const uint WM_SETTEXT = 0x000C; [DllImport ("User32.dll", CharSet = CharSet.Unicode, EntryPoint = "SendMessageW")] public statique extern IntPtr SendMessageWStr (IntPtr hWnd, uint uMsg, intPtr wParam, chaîne lParam); 'et vous pouvez utiliser' SendMessageWStr (enfant, WM_SETTEXT, IntPtr.Zero, "abcd"); ' –

Répondre

0

Beaucoup de crédit à Remy. Après un dépannage, j'ai fini par trouver le code qui fonctionnait, donc c'est un mystère pourquoi je trouvais que ce n'était pas le cas.

Une étape bonne dépannage consiste à essayer de déplacer la fenêtre autour de NirCmd, de sorte que vous savez que vous avez la poignée.

Pour obtenir la poignée de la fenêtre, vous pouvez utiliser WinLister NirSoft ou Winspector

Vous pouvez utiliser des commandes comme NirCmd nircmd win close handle 0x00230632 changement qui 0x00230632 à tout ce que vous trouvez la poignée soit. Ou mieux ne pas le fermer (sinon vous devrez le rouvrir et la nouvelle fenêtre aura un nouveau handle), donc une commande comme nircmd win move handle 0x00B917AE 80 10 100 100 Donc vous savez que le handle est correct, quel que soit le problème avec le code.

Winspector montre aussi l'enfant de la fenêtre du bloc-notes

enter image description here

Pour en revenir au code C#, vous pouvez

sauter l'enfant et essayer d'écrire dans le parent, il doit écrire dans la titre de la fenêtre

Essayez d'utiliser SendMessage pour spécifier une fenêtre directement. Vous écrivez le handle en décimal plutôt qu'en hexadécimal. par exemple. si la poignée est 3479948, alors

par ex. SendMessage(new IntPtr(3479948), WM_SETTEXT, IntPtr.Zero, "abcdee");

Vous pouvez également vérifier que les blocs-notes [0] .MainWindowHandle récupèrent la valeur correcte .. la poignée affichée dans winspector.

Vous pouvez regarder la ligne IntPtr child = FindWindowEx(...), assurez-vous que l''enfant' prend la poignée de l'enfant.

Vous pouvez essayer d'écrire directement avec SendMessage. par exemple. SendMessage(new IntPtr(1234567), WM_SETTEXT, IntPtr.Zero, "abcdee"); // (si winspector montre que la fenêtre enfant est ce handle).