我正在尝试制作一个在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;
}
有什么想法吗?任何帮助深表感谢。提前谢谢。
答案 0 :(得分:0)
好的,我从MSDN论坛得到了答案。问题是Outlook等待(同步)我的处理程序返回。关键是在处理程序中启动另一个线程,该线程将运行TakeScreen并将Thread.Sleep放在那里。这样我的处理程序将在制作屏幕截图之前返回,因此Inspector将有时间更新/加载图形。