2011-05-11 1 views
0

Outlook 2007에서 메일을 미리보기하는 앱을 만들려고합니다. 이메일을 사용하여 관리자를 캡처하려고하면 그래픽이 표시되지 않습니다. 아직 완전히로드되지 않았으므로 캡처 기능에 지연을 추가해야합니다. 그 때문에 나는 Thread.Sleep을 사용한다. 이제 내 문제는 경위가 Outlook 프로세스이기는하지만 동결도 마찬가지라는 것입니다. Thread.Sleep (15000)을 내 응용 프로그램에서 사용하고 Inspector와 수동으로 상호 작용 (이동, 텍스트 선택, 크기 조절)하려고 할 때 고정되어 있기 때문에 확신합니다. 응용 프로그램에서 완료된 후에 만 ​​(캡처 프로세스가 수행 된 직후에) 액세스 할 수 있습니다. 여기 내 코드입니다 :interop을 통해 다른 앱에서 outlook2007 관리자를 호출 취소하는 방법

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

입니다

:

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

좋아, 나는 MSDN 포럼에서 대답을 얻었다. 문제는 Outlook이 반환 할 내 처리기를 (동 기적으로) 대기한다는 것입니다. 열쇠는 TakeScreen을 실행하고 Thread.Sleep을 거기에 넣는 처리기에서 다른 스레드를 시작하는 것이 었습니다. 이렇게하면 스크린 샷을 만들기 전에 내 핸들러가 돌아와서 Inspector가 그래픽을 업데이트 /로드 할 시간을 갖게됩니다.