none
Modifying email body from with ItemSend causes Outlook flickering in inline mode ("popped out" mode works great) RRS feed

  • Question

  • Hi,

    I have code that modifies the email body from inside the ItemSend event. This works great when doing "New Mail" and sending, but when doing Reply in inline mode (not "popped out"), then the Outlook message area flickers quickly after the user has clicked Send. The reason is that the email body is modified from within my code and that Outlook tries to redraw it somehow before it is actually sent. I need to get rid of this short flickering.

    Any clue how to do this?

    I am guessing it is very difficult but who knows. By the way I am running Outlook 2016.

    Wednesday, December 21, 2016 9:16 PM

All replies

  • Hello,

    You may cancel the default action, open the item in a new inspector window (Display) and then call the Send method anew.


    profile for Eugene Astafiev at Stack Overflow, Q&A for professional and enthusiast programmers

    Wednesday, December 21, 2016 9:28 PM
  • Hi Dingoshark,

    you only mentioned the issue in your post.

    but from only description it is difficult to suggest you something.

    so I suggest you to post your code here so that we can try to test it on our side and try to give you suggestion for that.

    Regards

    Deepak


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, December 22, 2016 5:25 AM
    Moderator
  • Please see VBA code below that illustrates the problem. You will need to run the initialize function once manually. Note that the flickering only happens in inline mode (not popped out) in Outlook 2016 (not sure about 2013) when the disclaimer text is added to the body. If you remove modifying the body, no flickering occurs.

    Public WithEvents myOlApp As Outlook.Application 
     
    Public Sub Initialize_handler()
    Set myOlApp = Outlook.Application
    End Sub 
     
    Private Sub myOlApp_ItemSend(ByVal Item As Object, Cancel As Boolean)
    
    Dim prompt As String
    Dim objMailItem As Outlook.MailItem
     
    prompt = "Are you sure you want to send " & Item.Subject & "?"
    
    If MsgBox(prompt, vbYesNo + vbQuestion, "Sample") = vbNo Then
    
    Cancel = True
    
    Else
        If TypeOf Item Is MailItem Then
               Set objMailItem = Item
               objMailItem.Body = objMailItem.Body + vbCrLf + "-----------------MyDisclaimerText-----------------"
        End If
    End If
     
    End Sub

    Do you see the same issue? I see it at all instances of Outlook 2016.

    • Edited by Dingoshark Tuesday, December 27, 2016 10:35 PM
    Tuesday, December 27, 2016 10:34 PM
  • The issue is caused by the MsgBox call. If you try to remove such statements from the code you will not get any flickering any longer. 

    profile for Eugene Astafiev at Stack Overflow, Q&A for professional and enthusiast programmers

    Wednesday, December 28, 2016 7:19 PM
  • Thank you very much. That is interesting information. Problem is that I need the MessageBox as it is critical to the function of the add-in. Any other idea on how to prevent the issue? Maybe insert a Sleep somewhere? Or add a new "AddDisclaimer" listener function to ItemSend from within the first ItemSend listener? The second listener function would only add the disclaimer and will not have the messagebox logic.

    • Edited by Dingoshark Wednesday, December 28, 2016 9:35 PM
    Wednesday, December 28, 2016 8:34 PM
  • Hi Dingoshark,

    you had mentioned that message box is necessary to use for you.

    here I think that you have other code in your addin because here you just posted a code that have messagebox.

    you can try to modify the body first and then try to show the confirmation box.

    if user cancel then revert the changes done by modification.

    Regards

    Deepak


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, December 29, 2016 5:06 AM
    Moderator
  • To solve the issue you faced with you just need to specify the parent window handle for the message box. But VBA doesn't provide anything for that. In Windows applications (or managed) you could do so, but not in VBA. So, I'd suggest developing an add-in instead. See Walkthrough: Creating Your First VSTO Add-In for Outlook for more information.  

    As a workaround you may try handling the Send event of the MailItem class instead for displaying a message box. 


    profile for Eugene Astafiev at Stack Overflow, Q&A for professional and enthusiast programmers


    Thursday, December 29, 2016 6:43 PM
  • I have a managed add-in. The VBA was only for illustration.

    Which parent window should I use? I already tried the ActiveExplorer window, see below. But still see the flickering.

    Outlook.Explorer currentObject = null;
    try
    {
    	currentObject = AddinModule.CurrentInstance.OutlookApp.ActiveExplorer();
    	OfficeWin32Window wnd = new OfficeWin32Window(currentObject);
    	result = form.ShowDialog(wnd);
    }
    catch (Exception exception)
    {
    	MessageBox.Show(exception.Message, "Failed to open window");
    }
    finally
    {
    	if (currentObject != null) Marshal.ReleaseComObject(currentObject);
    }



    Thursday, December 29, 2016 7:38 PM
  • I don't see the OfficeWin32Window class implementation. But basically you need to cast an instance of the Explorer class to the IOleWindow interface to get a handle. Then you can use it for the message box. 

    profile for Eugene Astafiev at Stack Overflow, Q&A for professional and enthusiast programmers

    Thursday, December 29, 2016 7:56 PM
  • I think that is exactly what the code is doing but still it does not seem to help. Below is implementation.

    	public class OfficeWin32Window : IWin32Window
    	{
    
    		///<summary>
    		/// The <b>FindWindow</b> method finds a window by it's classname and caption.
    		///</summary>
    		///<param name="lpClassName">The classname of the window (use Spy++)</param>
    		///<param name="lpWindowName">The Caption of the window.</param>
    		///<returns>Returns a valid window handle or 0.</returns>
    		[DllImport("user32")]
    		public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
    		#region IWin32Window Members
    
    		///<summary>
    		/// This holds the window handle for the found Window.
    		///</summary>
    		IntPtr _windowHandle = IntPtr.Zero;
    
    		///<summary>
    		/// The <b>Handle</b> of the Outlook WindowObject.
    		///</summary>
    		public IntPtr Handle
    		{
    			get { return _windowHandle; }
    		}
    
    		#endregion
    
    		///<summary>
    		/// The <b>OfficeWin32Window</b> class could be used to get the parent IWin32Window for Windows.Forms and MessageBoxes.
    		///</summary>
    		///<param name="windowObject">The current WindowObject.</param>
    		public OfficeWin32Window(object windowObject)
    		{
    			string caption = windowObject.GetType().InvokeMember("Caption", System.Reflection.BindingFlags.GetProperty, null, windowObject, null).ToString();
    
    			// try to get the HWND ptr from the windowObject / could be an Inspector window or an explorer window
    			_windowHandle = FindWindow("rctrl_renwnd32\0", caption);
    		}
    	}
    }
    

    Thursday, December 29, 2016 8:08 PM