2011-05-11 1 views
0

J'essaie de faire une application qui prévisualise les mails dans Outlook 2007. Le problème est que lorsque j'essaie de capturer l'inspecteur avec l'email, les graphiques ne sont pas ' t encore entièrement chargé et j'ai besoin d'ajouter un délai à la fonction de capture. Pour cela j'utilise Thread.Sleep. Maintenant, mon problème est que même si l'inspecteur est un processus Outlook, il se fige aussi. Je suis sûr de cela parce que quand j'utilise Thread.Sleep (15000) dans mon application et que j'essaie d'interagir manuellement avec l'inspecteur (déplacer, sélectionner du texte, redimensionner), il est gelé. Ce n'est qu'après que j'ai terminé avec l'application (juste après le processus de capture) que je peux y accéder. Voici mon code:Comment débloquer outlook2007 inspecteur quand est invoqué à partir d'une autre application via interop

private static void HandleOutlookMail(string EntryIDCollection) 
{ 

    // Get the incoming MailItem based on ID. 
    NameSpace outlookNS = outLookApp.GetNamespace("MAPI"); 
    MAPIFolder mFolder = 
     outLookApp.Session.GetDefaultFolder(OlDefaultFolders.olFolderInbox); 
    newMail = (MailItem) 
     outlookNS.GetItemFromID(EntryIDCollection, mFolder.StoreID); 
    // Now show mail. 
    i = newMail.GetInspector; 
    //Make inspector big enough to show entire email 
    i.Height=2000; 
    //Activate inspector in order to avoid black screen capture 
    ((_Inspector)i).Activate(); 
    // Dispatch event for the screen capture to take place 
    OnNewOutlookMail(); 
} 

Maintenant, quand l'événement est déclenché au-dessus du gestionnaire suivant est appelé:

private void TakeScreen() 
{ 

    IntPtr hwnd = new IntPtr(); 
    Process[] processes = Process.GetProcessesByName("OUTLOOK"); 
    foreach (Process p in processes) 
    { 
     if (p.MainWindowTitle == iOutlook.newMail.GetInspector.Caption) 
     { 
      hwnd = p.MainWindowHandle; 
      Debug.WriteLine("Found " + p.MainWindowTitle); 
      break; 
     } 
    } 
    iOutlook.releaseInspector(); 
    //Give time to Inspector to finish loading - useless since it freezes and doesn't update 
    Thread.Sleep(15000); 
    //Save the image to disk 
    System.Drawing.Image img = (System.Drawing.Image)CaptureWindow(hwnd); 
    img.Save("t.png", ImageFormat.Png); 
    //Because I added the releaseInspector call to try to unfreeze the inspector I can't use: 
    //iOutlook.i.Close(Microsoft.Office.Interop.Outlook.OlInspectorClose.olDiscard); 
} 

Le code pour les 2 fonctions utilisées ci-dessus est:

public static void releaseInspector() 
{ 
    Marshal.ReleaseComObject(i); 
    Marshal.ReleaseComObject(newMail); 
    i = null; 
    newMail = null; 
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
    Debug.WriteLine("Released?"); 
} 

et

public System.Drawing.Bitmap CaptureWindow(IntPtr hWnd) 
{ 
    System.Drawing.Rectangle rctForm = System.Drawing.Rectangle.Empty; 

    using (System.Drawing.Graphics grfx = System.Drawing.Graphics.FromHdc(GetWindowDC(hWnd))) 
    { 
     rctForm = System.Drawing.Rectangle.Round(grfx.VisibleClipBounds); 
    } 

    System.Drawing.Bitmap pImage = new System.Drawing.Bitmap(rctForm.Width, rctForm.Height); 
    System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(pImage); 

    IntPtr hDC = graphics.GetHdc(); 
    //paint control onto graphics using provided options   
    try 
    { 
     PrintWindow(hWnd, hDC, (uint)0); 
    } 
    finally 
    { 
     graphics.ReleaseHdc(hDC); 
    } 
    return pImage; 
} 

Des idées? Toute aide est très appréciée. Merci d'avance.

Répondre

0

Ok, j'ai eu la réponse des forums MSDN. La chose est que Outlook attend (synchrone) pour que mon gestionnaire retourne. La clé était de commencer un autre thread dans le gestionnaire qui pourrait exécuter TakeScreen et mettre le Thread.Sleep là. De cette façon mon gestionnaire reviendrait avant que la capture d'écran ne soit faite et ainsi l'Inspecteur aurait le temps de mettre à jour/charger les graphiques.

Questions connexes