如何通过互操作从其他应用程序调用outlook2007检查器时解冻

时间:2011-05-11 05:34:30

标签: c# ms-office office-interop

我正在尝试制作一个在Outlook 2007中预览邮件的应用程序。问题是,当我尝试使用电子邮件捕获Inspector时,图形尚未完全加载,我需要向捕获功能。为此,我使用Thread.Sleep。现在我的问题是,即使Inspector是一个Outlook进程,它也会冻结。我很确定这是因为当我在我的应用程序中使用Thread.Sleep(15000)并尝试与Inspector手动交互(移动,选择文本,调整大小)时,它被冻结了。只有在我在应用程序中完成它之后(在捕获过程发生之后)我才能访问它。 这是我的代码:

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();
}

现在,当事件被触发时,会调用以下处理程序:

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);
}

上面使用的2个函数的代码是:

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

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;
}

有什么想法吗?任何帮助深表感谢。提前谢谢。

1 个答案:

答案 0 :(得分:0)

好的,我从MSDN论坛得到了答案。问题是Outlook等待(同步)我的处理程序返回。关键是在处理程序中启动另一个线程,该线程将运行TakeScreen并将Thread.Sleep放在那里。这样我的处理程序将在制作屏幕截图之前返回,因此Inspector将有时间更新/加载图形。