Il metodo sarebbe proprio quello che ti ho descritto. Ecco come potrebbe essere implementato:
delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool EnumWindows(EnumWindowsProc lpfn, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(IntPtr hwnd, out int lpdwProcessId);
[DllImport("user32.dll")]
static extern int GetWindowText(IntPtr hwnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam);
const uint WM_GETTEXT = 0x000D;
const uint WM_COMMAND = 0x0111;
const int IDOK = 1;
private void ApriChat(string contact)
{
Thread thd = new Thread(delegate() { Process.Start("msnim:chat?contact=" + contact); });
thd.Start();
Thread.Sleep(1000);
//Ottiene l'elenco dei processi iexplore
Process[] iexpl = Process.GetProcessesByName("iexplore");
int idProc = 0;
//Cerca la finestra che chiede se avviare la conversazione
EnumWindows(delegate(IntPtr hwnd, IntPtr lParam)
{
//Verifica che la finestra appartenga al processo iexplore.
//Se non è così, passa alla successiva
int id;
GetWindowThreadProcessId(hwnd, out id);
if (Array.FindIndex(iexpl, delegate(Process p) { return p.Id == id; }) == -1)
return true;
//Cerca fra le finestre figlio della finestra cercando il testo
//per verificare se è effettivamente la finestra di richiesta Ok
IntPtr ok = IntPtr.Zero;
IntPtr msg = IntPtr.Zero;
IntPtr szStr = Marshal.AllocHGlobal(1000);
EnumChildWindows(hwnd, delegate(IntPtr child, IntPtr lpUnused)
{
SendMessage(child, WM_GETTEXT, new IntPtr(500), szStr);
string text = Marshal.PtrToStringAnsi(szStr);
if (text.Contains(contact))
msg = child;
else if (string.Compare("ok", text, true) == 0)
ok = child;
return ok == IntPtr.Zero || msg == IntPtr.Zero;
}, IntPtr.Zero);
Marshal.FreeHGlobal(szStr);
//Se non ha trovato la finestra, passa alla successiva
if (ok == IntPtr.Zero || msg == IntPtr.Zero)
return true;
//Se invece l'ha trovata, invia alla finestra l'ok
SendMessage(hwnd, WM_COMMAND, (IntPtr)IDOK, ok);
//Esce dalla ricerca delle finestre
idProc = id;
return false;
}, IntPtr.Zero);
//Chiude l'internet explorer in base all'id trovato
if (idProc != 0)
{
Thread.Sleep(750);
Process proc = Process.GetProcessById(idProc);
proc.WaitForInputIdle();
proc.CloseMainWindow();
}
}
Come ti ho detto, non è un metodo molto ortodosso, penso che ci sia modo di fare il lavoro usando le API di msn, però devo ancora informarmi sull'argomento.
Luca