2013-07-19 23 views
5

Ho un progetto che comporta l'apertura di più client di finestre e quindi la simulazione di clic del mouse all'interno di ciascuno di questi processi. Sono stato in grado di inviare con successo un messaggio a più istanze di Blocco note utilizzando l'API Win32 e SendMessage. Il codice che funziona per me è la seguente:Web Automation Mouse Clic

Process[] notepads = Process.GetProcessesByName("notepad"); 
      foreach (Process proc in notepads) 
      { 
        IntPtr handle = proc.Handle; 
        IntPtr child = FindWindowEx(proc.MainWindowHandle, new IntPtr(0), "Edit", null); 
        if (child != null) 
        { 
         MessageBox.Show("Child was found, sending text"); 
         SendMessage(child, 0x000C, 0, "test"); 
        } 
       } 
      } 

Questo invia "test" a ogni istanza ho aperto di Blocco note, non importa quante. Come puoi vedere sto iterando attraverso ogni istanza di un processo e semplicemente eseguendo il ciclo del messaggio. Non è stato affatto difficile ...

L'obiettivo finale non è Blocco note, piuttosto l'estensione Microsoft Awesomium. Ho recuperato l'handle della finestra e quindi il nome della classe figlio (Awesomium), che è Chrome_RenderWidgetHostHWND. Da lì, ho provato a inviare eventi del mouse rifattorizzando i tipi di variabile in Sendmessage per assemblare e lParam leggibile dal sistema. Ecco il codice:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] 
     static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 

Utilizzando alcuni esempi che ho trovato io assemblare il lParam tramite questo:

int x = 834; 
int y = 493; 
IntPtr lParam = (IntPtr)((y << 16) | x); 
IntPtr wParam = IntPtr.Zero; 

Sto usando i ganci del mouse Globale per rilevare eventi stampa a tutte le finestre figlio, e quando ho premi il mio pulsante per scorrere il processo e fai clic, non viene inviato nulla. So che sto facendo qualcosa di stupido che sta facendo sì che i clic del mouse non vengano inviati. In ogni caso, ecco la struttura finale del codice che ho. Qualsiasi consiglio o consiglio sarebbe apprezzato. Grazie.

private void button2_Click(object sender, EventArgs e) 
    { 
     Process[] notepads = Process.GetProcessesByName("client"); 
     foreach (Process proc in notepads) 
     { 
       IntPtr handle = proc.Handle; 
       string mine = Convert.ToString(proc); 
       MessageBox.Show(mine); 
       IntPtr child = FindWindowEx(proc.MainWindowHandle, new IntPtr(0), "Chrome_RenderWidgetHostHWND", null); 
       if (child != null) 
       { 
       int x = 834; 
       int y = 493; 
       IntPtr lParam = (IntPtr)((y << 16) | x); 
       IntPtr wParam = IntPtr.Zero; 
       SendMessage(child, 0x201, wParam, lParam); 
       SendMessage(child, 0x202, wParam, lParam); 
       } 
      } 
     } 
+0

Realizzando diversi difetti con il mio codice, alla fine ho scavato in profondità in WinInspector e recuperato tutti i comandi necessari per avviare un clic del mouse. Sono un tale noob. Per chiunque in futuro, ecco i messaggi necessari per attivare un clic su Awesomium utilizzando Win32, molto probabilmente è lo stesso per tutti. WM_PARENTNOTIFY, WM_MOUSEACVTIVATE, WM_LBUTTONDOWN. La serie di questi tre comandi comunicherà al genitore che l'utente ha attivato il mouse, quindi esegue un breve urto, quindi alla fine preme il pulsante sinistro. Spero che questo aiuti qualcuno. – user2578424

+3

Dovresti dare una risposta e poi accettarla. – Xcelled194

risposta

1

Oppure si potrebbe usare SendInput invece, che funziona correttamente in presenza di ganci del mouse; la tua soluzione (di inviare messaggi direttamente) non lo farà.

Ancora più importante, se il processo rifiuta l'attivazione (ad esempio, se il target restituisce 0 da WM_MOUSEACTIVATE), WM_LBUTTONDOWN non verrà inviato.