Déclencher le système d’exploitation pour copier (ctrl + c ou Ctrl-x) par programmation

Je travaille sur un programme pour déclencher des coupes et des pâtes

Pastes Je n’ai aucun problème avec (je viderai juste une chaîne dans le presse-papier)

Cut and or Copys s’avèrent un peu plus difficiles

Le programme que je possède est flou et dispose de plusieurs touches d’access rapide enregistrées avec les touches CTRL + ALT + 2 CTRL + ALT + 3, etc.

Que je veux utiliser pour déclencher Windows pour copier tout ce qui est mis en évidence dans la fenêtre qui est ciblée

J’ai essayé de faire un sendkeys

SendKeys.Send("^c"); 

mais cela semble fonctionner une ou deux fois si du tout cesse alors de fonctionner.

existe-t-il un meilleur moyen de déclencher des fenêtres pour gérer le contenu mis en évidence sur une autre fenêtre?

Pour ce faire, vous pouvez utiliser la fonction Win32 SendInput . Avec SendInput , vous devez simuler à la fois les événements d’ SendInput et de SendInput la clé pour que la touche complète puisse être enregistrée. Pour simuler CTRL + C , vous devez faire:

  • Touche CTRL vers le bas
  • Touche C enfoncée
  • C clé
  • Touche CTRL

pinvoke.net a quelques exemples d’utilisation de SendInput . Un problème à prendre en compte est si la touche est déjà pressée. Vous pouvez utiliser GetAsyncKeyState pour simuler uniquement un événement d’arrêt de clé si la clé n’est pas déjà éteinte.

Vous trouverez ci-dessous un exemple de code permettant de simuler CTRL + C. Avec le code ci-dessous, vous pouvez simplement appeler Keyboard.SimulateKeyStroke('c', ctrl: true); Notez que cela fonctionne comme si l’utilisateur appuyait littéralement sur CTRL + C , de sorte que l’application active se comportera comme elle le fait toujours lorsqu’un tel événement se produit (c’est-à-dire que rien ne sera copié avec cette méthode).

Edit: Voir le commentaire de David ci-dessous concernant le traitement en lots de l’entrée envoyée. Le code ci-dessous doit envoyer la séquence entière des événements d’entrée via un seul appel à SendInput pour éviter d’être entrelacé (et mal interprété) avec des événements de saisie utilisateur réels.

 using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading; namespace SimulateKeys { static class Keyboard { public static void SimulateKeyStroke(char key, bool ctrl = false, bool alt = false, bool shift = false) { List keys = new List(); if (ctrl) keys.Add(VK_CONTROL); if (alt) keys.Add(VK_MENU); if (shift) keys.Add(VK_SHIFT); keys.Add(char.ToUpper(key)); INPUT input = new INPUT(); input.type = INPUT_KEYBOARD; int inputSize = Marshal.SizeOf(input); for (int i = 0; i < keys.Count; ++i) { input.mkhi.ki.wVk = keys[i]; bool isKeyDown = (GetAsyncKeyState(keys[i]) & 0x10000) != 0; if (!isKeyDown) SendInput(1, ref input, inputSize); } input.mkhi.ki.dwFlags = KEYEVENTF_KEYUP; for (int i = keys.Count - 1; i >= 0; --i) { input.mkhi.ki.wVk = keys[i]; SendInput(1, ref input, inputSize); } } [DllImport("user32.dll")] static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize); [DllImport("user32.dll")] static extern short GetAsyncKeyState(ushort vKey); struct MOUSEINPUT { public int dx; public int dy; public uint mouseData; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } struct HARDWAREINPUT { public int uMsg; public short wParamL; public short wParamH; } [StructLayout(LayoutKind.Explicit)] struct MOUSEKEYBDHARDWAREINPUT { [FieldOffset(0)] public MOUSEINPUT mi; [FieldOffset(0)] public KEYBDINPUT ki; [FieldOffset(0)] public HARDWAREINPUT hi; } struct INPUT { public int type; public MOUSEKEYBDHARDWAREINPUT mkhi; } const int INPUT_KEYBOARD = 1; const uint KEYEVENTF_KEYUP = 0x0002; const ushort VK_SHIFT = 0x10; const ushort VK_CONTROL = 0x11; const ushort VK_MENU = 0x12; } class Program { static void Main(ssortingng[] args) { Thread.Sleep(3000); Keyboard.SimulateKeyStroke('c', ctrl: true); } } } 

Si vous pouvez obtenir le texte sélectionné à partir de la fenêtre ciblée (peut-être un problème plus facile à résoudre), il est préférable d’utiliser la méthode SetText de la classe System.Windows.Forms.Clipboard .