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

发布于 2024-11-06 04:57:50 字数 2951 浏览 0 评论 0原文

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

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

什么想法吗?非常感谢任何帮助。提前致谢。

I'm trying to make an app that previews mails in Outlook 2007. The thing is that when I try to capture the Inspector with the email, the graphics aren't yet fully loaded and I need to add a delay to the capture function. For that I use Thread.Sleep. Now my problem is that even though the Inspector is an Outlook process it freezes as well. I'm sure of this because when I use Thread.Sleep(15000) in my app and try to manually interact with the Inspector (move, select text, resize), it's frozen. Only after I'm done with it in the app (just after the capture process took place) I can access it.
Here is my code:

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

Now when the event is fired above the following handler is called:

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

The code for the 2 functions used above is:

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

and

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

Any ideas? Any help is much appreciated. Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

只是一片海 2024-11-13 04:57:50

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

Ok, I got the answer from the MSDN forums. The thing is that Outlook waits (synchronously) for my handler to return. The key was to start another thread in the handler that would run TakeScreen and put the Thread.Sleep there. This way my handler would return before the screenshot is made and so the Inspector would have time to update/ load graphics.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文