Envoyer CTRL-S de message d'une fenêtre

Je veux enregistrer un TextPad fenêtre à l'aide de code C#; je peux trouver la poignée de la fenêtre, mais ne savez pas comment envoyer CTRL - S à cette fenêtre. Je veux utiliser P/Invoke API pour atteindre cet objectif. Aussi, que TextPad fenêtre sera inactif, parce que ma demande sera actif à ce moment.

[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hwnd, int msg, int wParam, int lParam);

Envoyer Ctrl+Jusqu'à une fenêtre

J'ai regardé cette discussion qui est très similaire à mon problème. Je comprends logiquement que j'ai à faire 4 envoyer des messages comme ci-dessous

  • KeyDown touche CTRL
  • KeyDown touche S
  • KeyUp touche S
  • KeyUp touche CTRL

Je ne suis pas sûr de savoir comment envoyer les bons paramètres à la SendMessage. Pour fermer la fenêtre-je utiliser

SendMessage(hWnd, 0x0010, 0, 0);

Je l'ai obtenu à partir de la bibliothèque MSDN.

Pouvez vous s'il vous plaît me diriger vers un lien qui me dit que le code hexadécimal pour les touches du clavier et explique ce que les deux derniers paramètres représentent?

mise à JOUR - 1

Avec spy++ je trouve que ces événements générés avec I appuyez sur CTRL-S sur la fenêtre du bloc-notes

1. WM_KEYDOWN nVirtKey:VK_Control, 
2. WM_KEYDOWN nVirtKey:'S' .. certains autres messates .. 
3. WM_KEYUP nVirtKey:VK_Control. 
4. WM_KEYUP nVirtKey:'S'. 

mise à JOUR - 2


       private IntPtr startnotepad() {
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.FileName = @"notepad.exe";
            String fileName = baseDirectory + textbox1.Text;
            psi.Arguments = @"""" + fileName + @"""";
            psi.WindowStyle = ProcessWindowStyle.Minimized;
            Process p = Process.Start(psi); 
            return p.MainWindowHandle;
        }

        private void SaveNotepad(IntPtr handle)
        {
            IntPtr handle = GetWindow(handle, 5); //get the keyboard focus handle
            //verified the handle with Spy ++.
            SendMessage(handle, 0x0100, 0x11, 0); //keydown ctrl
            SendMessage(handle, 0x0100, 0x53, 0); //keydown S
            //SendMessage(handle, 0x0101, 0x11, 0); --- I tried keeping "Keyup Ctrl" here as well.
            SendMessage(handle, 0x0101, 0x53, 0); //keyup s
            SendMessage(handle, 0x0101, 0x11, 0); //keyup ctrl            
        }

Ce code ne fonctionne pas (sauver une partie de celui-ci), même si je suis capable de voir le WM_KEYDOWN - CTRL .. WM_KEYDOWN - 'S' .. KEYUP 'S' et KEYUP CTRL être envoyé à la fenêtre de droite dans spy++. Quelqu'un peut-il commenter ce qui est mal avec ce code? Ou des suggestions, si je suis en train de faire quelque chose de vraiment stupide.

mise à JOUR 3

Je devrais être à l'aide de PostMessage au lieu de SendMessage @Hans suggéré dans ses commentaires.


 [DllImport("user32.dll")]
 public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);  

        private void Save(IntPtr mainWindowHandle)
        {               
            IntPtr handle = GetWindow(mainWindowHandle, 5); //getChild window
            IntPtr CTRL_KEY = new IntPtr(0x11);
            uint KEY_DOWN = 0x0100;
            uint KEY_UP = 0x0101;
            IntPtr S_KEY = new IntPtr(0x53);

            //SetForegroundWindow(p.MainWindowHandle);
            PostMessage(handle, KEY_DOWN, CTRL_KEY, IntPtr.Zero);
            PostMessage(handle, KEY_DOWN, S_KEY, IntPtr.Zero);
            PostMessage(handle, KEY_UP, S_KEY, IntPtr.Zero);
            PostMessage(handle, KEY_UP, CTRL_KEY, IntPtr.Zero);                      
        } 

Le code ci-dessus au lieu de CTRL+S envoie les touches CTRL et S à la fenêtre du bloc-notes. Donc, je peux voir les deux "S" qui se jette sur le bloc-notes. En regardant le vrai message généré lorsque nous appuyer sur CTRL+S, je vois que le dernier paramètre de mon Postmessage est faux. Il doit être quelque chose comme (pour la TOUCHE UP touche " CTRL "C01F0001")

Pouvez-vous svp me dire comment faire pour passer cette hexadécimal comme dernier paramètre de postmessage?


//does not work
PostMessage(handle, KEY_UP, CTRL_KEY, new IntPtr(0xC01F0001);


Mise à jour 4 : je pense que nous ne pouvons pas envoyer des "hot key" messages à une fenêtre réduite. à l'aide de Message.



Ce code ci-dessous fonctionne avec SendInput: mais il fera apparaître la fenêtre, qui sorte un mar le but. De toute façon, je voulais juste mettre à jour ce fil.


 private void Save_Notepad(IntPtr mainWindowHandle) {
            //SetActiveWindow(mainWindowHandle);
            //SetFocus(GetWindow(mainWindowHandle, 5));
            ShowWindow(mainWindowHandle, 1); //show window 
            SetForegroundWindow(mainWindowHandle);
            //SetActiveWindow(mainWindowHandle);
            //SetFocus(GetWindow(mainWindowHandle, 5));
            //IntPtr returnvalue = SetFocus(mainWindowHandle);
            uint intReturn;
            INPUT structInput;
            structInput = new INPUT();
            structInput.type = 1;//keyboard input
            //key down
            structInput.ki.wScan = 0x1D;
            structInput.ki.time = 0;
            structInput.ki.dwFlags = 0;
            //key down Ctrl
            structInput.ki.wVk = 0x11;  //0x1D; //
            intReturn = SendInput(1, ref structInput, Marshal.SizeOf(new INPUT()));
            //key down S
            structInput.ki.wScan = 0x1F;
            structInput.ki.wVk = 0x53; //0x41;//0x53;  //0x1F;//
            intReturn = SendInput(1, ref structInput, Marshal.SizeOf(new INPUT()));
            //key up 
            structInput.ki.dwFlags = 0x0002; //key up
            //key up S
            intReturn = SendInput(1, ref structInput, Marshal.SizeOf(typeof(INPUT)));
            //key up CTRL
            structInput.ki.wVk = 0x11;  //0x1D; //
            intReturn = SendInput(1, ref structInput, Marshal.SizeOf(new INPUT()));
            //ShowWindow(mainWindowHandle, 2); //minimize it again 
        }

Après un CTRL + S je peux réduire la fenêtre, mais alors il va créer un flash.
Quelqu'un peut-il suggérer si je peux obtenir cette fonctionnalité, sans le "FLASH" (au moins)?

mise à JOUR 5 : à l'aide de WM_SYSCOMMAND


IntPtr handle = GetWindow(mainWindowHandle, 5);
//send Alt F message to Notepad.
//http://msdn.microsoft.com/en-us/library/ms646360(v=VS.85).aspx
//I can see this is working.
PostMessage(handle, 0x0112, 0xF100, 'f');  //send WM_SYSCOMMAND
//how to send s on this window ??
//I have tried things which I have learned so far. 

J'ai juste besoin d'envoyer des messages pour le fichier de menu qui apparaîtra comme un résultat de WM_SYSCOMMAND. Quelqu'un peut-il m'indiquer une documentation à la façon de le faire?


PostMessage(handle, KEY_DOWN, S_KEY, 0x1F0001); //POST does not work
//tried with mainwindowhandle as well
PostMessage(handle, 0x111, 'S', 0); //WM_COMMAND does not work
PostMessage(handle, 0x0112, 0xF100, 's');  //WM_SYSCOMMAND does not work (and does not make sence either)

dernière mise à Jour

Je n'étais pas en mesure d'envoyer ^S message à une fenêtre réduite. Je suis à l'aide de sendkeys(^s) tous les 2 à 3 secondes lorsque le focus est sur un éditeur.

-- Karephul

Quel est le problème avec SendKeys?
Je veux dire, votre mise à jour 4 est très belle et tout, mais n'est-il pas en une seule ligne .NET SendKeys?
Qui plus est, Hans a souligné que vous pouvez simplement envoyer un WM_COMMAND qui permettra d'éviter l'affichage de la fenêtre si elle est réduite au minimum
Tout d'abord je voulais une solution pour envoyer des messages alors que la fenêtre est réduite .. j'ai commencé avec SendMessage, puis PostMessage et que Hans a suggéré SendInput. Comme vous l'avez suggéré "SendKeys" ressemble vraiment à une meilleure solution à ma mise à Jour 4. Mise à jour 4 n'est pas la solution que je cherchais, mais si je dois me calmer, je vais passer à SendKeys ..
WM_COMMAND, pouvez-vous svp m'indiquer quelques-documentation de l'API de référence ou comment l'utiliser pour envoyer des accerlerator clés? Je vais vraiment l'apprécier.

OriginalL'auteur karephul | 2011-02-28