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
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 minimumTout 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
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas utiliser la fonction SendMessage (ou PostMessage, la bonne) pour simuler l'état de la modificateurs de touches comme CTRL. Vous devez utiliser SendInput().
Une combinaison de touches Ctrl+S n'est pas untypically traduit dans un message WM_COMMAND. Utiliser l'outil Spy++ pour voir ce qui se passe lorsque vous tapez Ctrl+S à la main. Si vous voyez WM_COMMAND alors vous êtes d'or, vous peut utiliser SendMessage() pour envoyer le message. Bien sûr, ce ne fonctionne que sur un processus spécifique.
Mettez ceci dans votre question, non pas dans un commentaire. Je ne vois pas WM_COMMAND, utilisez SendInput().
J'ai pensé WM_KEYDOWN était un type de WM_COMMAND. Je vais regarder dans SendInput() - qui ressemble à quelque chose que je peux faire sur une fenêtre Active uniquement. Je veux envoyer un CTRL S pour une fenêtre Active .. de sorte que l'utilisateur ne se rendent pas compte que son bloc-notes de l'enregistrement des données.
Le bloc-notes t utiliser WM_COMMAND, regardez le cadre de la fenêtre. Cela, c'est une très bonne façon de faire de l'utilisateur accidentellement enregistrer le fichier et de ne jamais être en mesure de trouver de nouveau. Ctrl+S apporte l'enregistrer en tant que boîte de dialogue pour la 1ère fois, très mauvais lorsque l'utilisateur est occupé à taper.
Nous essayons de contrôler seulement quelques le bloc-notes de windows, qui va être créé et ouvert pour l'utilisateur [cela permettra d'éviter enregistrer en tant que boîte de dialogue] aussi, Ctrl-S ne pas fermer la fenêtre, de sorte que nous sommes bons. Donc, vous pensez que API sendmessage() devrait fonctionner ? si oui, alors j'ai juste besoin de savoir handle de fenêtre pour envoyer ces messages à [focus clavier poignée]
OriginalL'auteur Hans Passant
J'avais besoin de faire exactement ce que vous devez faire, appeler un Ctrl+S dans un peu de fond de la fenêtre, après une journée de recherche, il semble y avoir de nombreuses façons d'y parvenir.
Par exemple, appuyez sur Alt + F puis un "S", vous pouvez appeler le:
Le Alt-F le cadre de travaux sur des fenêtres d'arrière-plan, tandis que le lancement de la " S " n'.
Une autre façon de le faire est avec WM_COMMAND et WM_MENUSELECT, MF_MOUSESELECT:
Enfin et un peu ironiquement les simples solution est d'appeler WM_COMMAND avec le menuItemID:
La 0x0003 (enregistrer dans le bloc-notes) est déterminé par l'application et la structure de menu, vous pouvez obtenir ce code par l'écoute de WM_COMMAND à spy++ sur la fenêtre pendant que vous utilisez le combo combinaison de touches ou, appuyez sur le bouton de la souris sur la commande de menu.
Il semble qu'il est également possible d'utiliser WM_SYSKEYUP/BAS et WM_MENUCOMMAND, aussi les touches Ctrl-C, Ctrl-V ont défini les valeurs et peut être passé comme un personnage, mais uniquement pour les applications qui écoutent ces caractères codés en dur...
Merci pour le point de départ.
Désolé, ça fait un moment, semble que j'avais à l'aide d'un accélérateur de 0x20000000 décalage. msdn.microsoft.com/en-us/library/windows/desktop/... msdn.microsoft.com/en-us/library/windows/desktop/...
Pourriez-vous nous expliquer comment vous avez composé le "0xF100" partie de ALT+F?, donc, on pourrait avoir l'idée sur la façon de composer d'autres composite frappes comme par exemple CTRL+P ou tout autre. quelqu'un pourrait m'expliquer cela?.
Salut 0xF100 est la touche menu (alt), 0x0046 est la valeur hexadécimale de la touche F. msdn.microsoft.com/en-us/library/windows/desktop/...
OriginalL'auteur critic