2012-01-26 23 views
9

Hice un teclado en pantalla con C# Windows Forms. Uso la función Sendkeys.Send() para enviar las teclas. Todas las letras menos la letra i funciona bien. Cuando presiono la letra i en el teclado cuando Microsoft Word es abierta, envía Ctrl +Alt +I y abre el diálogo de impresión. Es lo mismo en Notepad ++ también. Pero funciona bien cuando trato de escribir en el bloc de notas.Envío de la letra 'i' con SendKeys

En mi código, envío las claves con SendKeys.Send(value); donde el valor es el texto del botón que se presiona. Obtengo el texto con el siguiente código:

string s = ((Button)sender).Text; 

¿Algún comentario sobre por qué no funciona correctamente?

Editar: He creado un nuevo proyecto de formularios de Windows con solo un botón y todo el código está debajo. Sigue sin funcionar. Cualquier idea sera apreciada.

public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      SendKeys.Send("i"); 
     } 

     // Prevent form being focused 
     const int WS_EX_NOACTIVATE = 0x8000000; 
     protected override CreateParams CreateParams 
     { 
      get 
      { 
       CreateParams ret = base.CreateParams; 
       ret.ExStyle |= WS_EX_NOACTIVATE; 
       return ret; 
      } 
     } 
    } 

La función anulada es evitar que se enfoque el formulario. Para poder enviar las teclas a la otra aplicación que tiene el foco.

+0

¿Es definitivamente en esta parte del código? ¿Qué es 'value', esto no es una palabra clave? Es posible que, en cierta circunstancia, descubra eso en lugar de utilizar el objeto '((MiClase))' que utiliza '(objeto como MiClase)'. El segundo devolverá null si obj no es un MyClass, en lugar de arrojar una excepción de lanzamiento de clase. – MoonKnight

+0

Lo siento mucho. Sería cadena s en lugar de valor s. El resultado no cambia, incluso lo hago así: Sendkeys.Send ("i"); –

+0

¿Utilizaste un depurador para verificar qué valor está obteniendo 's'? Esto te ayudará a reducir el problema. –

Respuesta

1

dos alternativas:

1- Simula una pulsación de tecla, ver http://msdn2.microsoft.com/en-us/library/system.windows.forms.sendkeys(VS.71).aspx

muestra:

public static void ManagedSendKeys(string keys) 
     { 
      SendKeys.SendWait(keys); 
      SendKeys.Flush(); 
     } 

2- envía una clave para una ventana, al pulsar el botón de x segundos

[DllImport("user32.dll")] 
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo); 
public static void KeyboardEvent(Keys key, IntPtr windowHandler, int delay) 
     { 
      const int KEYEVENTF_EXTENDEDKEY = 0x1; 
      const int KEYEVENTF_KEYUP = 0x2; 
      keybd_event((byte)key, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr)0); 
      Thread.Sleep(delay); 
      keybd_event((byte)key, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr)0); 
     } 
0

No está llamando al método de la API Win32 "SetForegroundWindow". Por lo tanto, es probable que su llamada a "SendKeys" envíe las claves a su aplicación, no a la aplicación de destino como estaba previsto.

He aquí un ejemplo en MSDN:

How to: Simulate Mouse and Keyboard Events in Code

También, aquí está el código del ejemplo:

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

namespace SimulateKeyPress 
{ 
    class Form1 : Form 
    { 
     private Button button1 = new Button(); 

     [STAThread] 
     public static void Main() 
     { 
      Application.EnableVisualStyles(); 
      Application.Run(new Form1()); 
     } 

     public Form1() 
     { 
      button1.Location = new Point(10, 10); 
      button1.TabIndex = 0; 
      button1.Text = "Click to automate Calculator"; 
      button1.AutoSize = true; 
      button1.Click += new EventHandler(button1_Click); 

      this.DoubleClick += new EventHandler(Form1_DoubleClick); 
      this.Controls.Add(button1); 
     } 

     // Get a handle to an application window. 
     [DllImport("USER32.DLL", CharSet = CharSet.Unicode)] 
     public static extern IntPtr FindWindow(string lpClassName, 
      string lpWindowName); 

     // Activate an application window. 
     [DllImport("USER32.DLL")] 
     public static extern bool SetForegroundWindow(IntPtr hWnd); 

     // Send a series of key presses to the Calculator application. 
     private void button1_Click(object sender, EventArgs e) 
     { 
      // Get a handle to the Calculator application. The window class 
      // and window name were obtained using the Spy++ tool. 
      IntPtr calculatorHandle = FindWindow("CalcFrame","Calculator"); 

      // Verify that Calculator is a running process. 
      if (calculatorHandle == IntPtr.Zero) 
      { 
       MessageBox.Show("Calculator is not running."); 
       return; 
      } 

      // Make Calculator the foreground application and send it 
      // a set of calculations. 
      SetForegroundWindow(calculatorHandle); 
      SendKeys.SendWait("111"); 
      SendKeys.SendWait("*"); 
      SendKeys.SendWait("11"); 
      SendKeys.SendWait("="); 
     } 

     // Send a key to the button when the user double-clicks anywhere 
     // on the form. 
     private void Form1_DoubleClick(object sender, EventArgs e) 
     { 
      // Send the enter key to the button, which raises the click 
      // event for the button. This works because the tab stop of 
      // the button is 0. 
      SendKeys.Send("{ENTER}"); 
     } 
    } 
} 
+0

Acabo de hacer mi aplicación no enfocable. Entonces, siempre la última aplicación se enfoca incluso después de hacer clic en mi botón en mi aplicación. ¿Este enfoque es incorrecto? Funciona cuando lo intento en el bloc de notas y en el teclado, pero no funciona en ms word y notepad ++ –