para lo primero, tienes que guardar la imagen con GetThumbailImage o algo asi... y para lo segundo montarse un sistema de regiones a este estilo
//CODIGO DE LEONIDAS
- public class Ventana 
-         { 
-             public Rectangle RECTANGULO; 
-             public IntPtr HW; 
-             public bool SubVentana = false; 
-             public uint ESTADO; 
-             public bool Visible = true; 
-             public string titulo = ""; 
-             public Ventana(IntPtr hw) 
-             { 
-                 HW = hw; 
-                 titulo = NativeWIN32.GetWindowText(hw); 
-             } 
-             public void PonerPos(NativeWIN32.RECT rect, uint estado) 
-             { 
-                 RECTANGULO  = new-  Rectangle (- rect .Left- , rect .Top- , rect .Right --  rect .Left- , rect .Bottom --  rect .Top);
-                 ESTADO = estado; 
-             } 
-             public Ventana(NativeWIN32.RECT rect, uint estado, IntPtr hw) 
-             { 
-                 RECTANGULO  = new-  Rectangle (- rect .Left- , rect .Top- , rect .Right --  rect .Left- , rect .Bottom --  rect .Top);
-                 HW = hw; 
-                 ESTADO = estado; 
-                 titulo = NativeWIN32.GetWindowText(hw); 
-             } 
-         } 
-   
-   
-   
- public static List<Ventana> CalcularRects() 
-         { 
-             List <- Ventana >-  tsre  = new-  List <- Ventana >();
-             NativeWIN32 .EnumDelegate-  enumfunc  = new-  NativeWIN32 .EnumDelegate(- EnumWindowsProc );
-             bool success = NativeWIN32.EnumDesktopWindows(IntPtr.Zero, enumfunc, IntPtr.Zero); 
-             foreach (IntPtr hw in mhWnd) 
-             { 
-                 //NativeWIN32.RECT result = new NativeWIN32.RECT(); 
-                 //NativeWIN32.GetWindowRect(hw, out result); 
-                 NativeWIN32 .WINDOWINFO-  info  = new-  NativeWIN32 .WINDOWINFO();
-                 info .cbSize = (uint)- Marshal .SizeOf(- info );
-                 NativeWIN32.GetWindowInfo(hw, ref info); 
-                 Ventana v  = new-  Ventana (- info .rcWindow- , info .dwWindowStatus- , hw );
-                 tsre.Add(v); 
-             } 
-             mhWnd.Clear(); 
-             mhWnd = null; 
-             //LAS CHICAS 
-             foreach (IntPtr p in NativeWIN32.GetChildWindows(NativeWIN32.GetForegroundWindow())) 
-             { 
-                 NativeWIN32 .WINDOWINFO-  info  = new-  NativeWIN32 .WINDOWINFO();
-                 info .cbSize = (uint)- Marshal .SizeOf(- info );
-                 NativeWIN32.GetWindowInfo(p, ref info); 
-                 Ventana v  = new-  Ventana (- info .rcWindow- , info .dwWindowStatus- , p );
-                 v.SubVentana = true; 
-                 v.Visible = NativeWIN32.IsWindowVisible(p); 
-                 tsre.Add(v); 
-             } 
-             //---------- 
-             return tsre; 
-         } 
-   
cuando las envias te las guardas a una variable, luego lo lees de nuevo y compruebas los rectangulos cambiados
- public static Rectangle ComparaArrayVentanas(List<Ventana> a1, List<Ventana> a2) 
-         { 
-             if (a1 == null || a2 == null) return Screen.PrimaryScreen.Bounds; 
-             GraphicsPath gp  = new-  GraphicsPath ();
-             gp.FillMode = FillMode.Alternate; 
-             for (int x = 0; x < a1.Count; x++) 
-             { 
-                 if (a1[x].HW == IntPtr.Zero) break; 
-                 bool existe_y_igual = false; 
-                 for (int y = 0; y < a2.Count; y++) 
-                 { 
-                     if (a1[x].HW == IntPtr.Zero) { gp.AddRectangle(a1[x].RECTANGULO); continue; } 
-                     if (a1[x].HW == a2[y].HW) 
-                     { 
-                         if (a1[x].RECTANGULO == a2[y].RECTANGULO && a1[x].ESTADO == a2[y].ESTADO && a1[x].Visible == a2[y].Visible) existe_y_igual = true; 
-                         break; 
-                     } 
-                 } 
-                 if (!existe_y_igual) gp.AddRectangle(a1[x].RECTANGULO); 
-             } 
-             for (int x = 0; x < a2.Count; x++) 
-             { 
-                 if (a2[x].HW == IntPtr.Zero) { gp.AddRectangle(a2[x].RECTANGULO); continue; } 
-                 bool existe_y_igual = false; 
-                 for (int y = 0; y < a1.Count; y++) 
-                     if (a2[x].HW == a1[y].HW) 
-                     { 
-                         if (a2[x].RECTANGULO == a1[y].RECTANGULO && a2[x].ESTADO == a1[y].ESTADO && a2[x].Visible == a1[y].Visible) existe_y_igual = true; 
-                         break; 
-                     } 
-                 if (!existe_y_igual) gp.AddRectangle(a2[x].RECTANGULO); 
-             } 
-             if (gp.PointCount == 0) return Rectangle.Empty; 
-             int t = -1, l = -1, w = -1, h = -1; 
-             RectangleF r = gp.GetBounds(); gp.Dispose(); 
-             t = (int)r.Top; 
-             l = (int)r.Left; 
-             w = (int)r.Width; 
-             h = (int)r.Height; 
-             if (t < 0) t = 0; 
-             if (l < 0) l = 0; 
-             if (w + l + 30 > Screen.PrimaryScreen.Bounds.Width) w = Screen.PrimaryScreen.Bounds.Width - l; 
-             if (h + t + 30 > Screen.PrimaryScreen.Bounds.Height) h = Screen.PrimaryScreen.Bounds.Height - t; 
-             return new-  Rectangle (- l, t, w, h );
 
-         } 
y te devuelve el rectangulo de la pantalla a enviar... asi lo hago yo...luego tienes que cojer el rectangulo activo cuando se pulsa una tecla y cuando se hace un click 
