2012-01-26 13 views
9

Ho creato una tastiera su schermo con C# Windows Forms. Io uso la funzione Sendkeys.Send() per inviare le sequenze di tasti. Tutte le lettere tranne la lettera i funzionano bene. Quando premo la lettera di i sulla tastiera quando Microsoft Word è aperto, invia Ctrl +Alt +I e si apre la finestra di dialogo di stampa. È lo stesso anche in Notepad ++. Ma funziona bene quando provo a digitare il blocco note.Invio lettera 'i' con SendKeys

Nel mio codice invio le chiavi con SendKeys.Send(value); dove valore è il testo del pulsante che viene premuto. Ricevo il testo con il seguente codice:

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

Qualche commento sul motivo per cui non funziona correttamente?

Modifica: Ho creato un nuovo progetto di finestre con un solo pulsante e l'intero codice è sotto. Continua a non funzionare. Qualsiasi idea sarebbe apprezzata.

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 funzione di sostituzione è di impedire che il modulo sia focalizzato. In modo che io possa inviare le sequenze di tasti all'altra applicazione che ha il focus.

+0

E 'sicuramente in questa parte del codice? Qual è il valore? Questa non è una parola chiave? In qualche circostanza si potrebbe trovare che piuttosto che lanciare con l'oggetto '((MyClass) 'che esegue il casting usando' (oggetto come MyClass) '. Il secondo restituirà null se obj non è una MyClass, piuttosto che lanciare un'eccezione cast di classe. – MoonKnight

+0

Mi dispiace tanto. sarebbe stringa s invece di valore s.Il risultato non cambia anche io lo faccio in questo modo: Sendkeys.Send ("i"); –

+0

Hai usato un debugger per verificare quale valore 's' sta ottenendo? Questo ti aiuterà a restringere il problema. –

risposta

1

due alternative:

1- Simula pressione di un tasto, vedere http://msdn2.microsoft.com/en-us/library/system.windows.forms.sendkeys(VS.71).aspx

Esempio:

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

2- Invia una chiave a una finestra, premere il pulsante per x secondi

[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

Non si chiama il metodo API Win32 "SetForegroundWindow". Pertanto, è probabile che la tua chiamata "SendKeys" invii le chiavi alla tua app, non all'app target come previsto.

Ecco un esempio su MSDN:

How to: Simulate Mouse and Keyboard Events in Code

Inoltre, ecco il codice dall'esempio:

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

Ho appena reso la mia applicazione non focalizzabile. Quindi, sempre l'ultima applicazione è focalizzata anche dopo aver fatto clic sul mio pulsante sulla mia applicazione. Questo approccio è sbagliato? Funziona quando lo provo su blocco note e wordpad ma non funziona su ms word e notepad ++ –

Problemi correlati