1

I have code that auto-zooms the email window pane. It worked until a few days ago after the latest update was made to MS Outlook.

'Install redemption and add "Microsoft Word Object Library" reference and "Redemption Outlook library" reference.
Option Explicit
    Dim WithEvents objInspectors As Outlook.Inspectors
    Dim WithEvents objOpenInspector As Outlook.Inspector
    Dim WithEvents objMailItem As Outlook.MailItem
    Dim WithEvents myOlExp As Outlook.Explorer
    Dim sExplorer As Object
    Dim Document As Object
    Dim Msg
    
    Const MsgZoom = 150
    
Private Sub Application_Startup()
    Set objInspectors = Application.Inspectors
    Set myOlExp = Application.ActiveExplorer
    Set sExplorer = CreateObject("Redemption.SafeExplorer")
End Sub
    
Private Sub Application_Quit()
    Set objOpenInspector = Nothing
    Set objInspectors = Nothing
    Set objMailItem = Nothing
End Sub
    
Private Sub objInspectors_NewInspector(ByVal Inspector As Inspector)
    If Inspector.CurrentItem.Class = olMail Then
        Set objMailItem = Inspector.CurrentItem
        Set objOpenInspector = Inspector
    End If
End Sub

Private Sub objOpenInspector_Close()
    Set objMailItem = Nothing
End Sub
    
Private Sub objOpenInspector_Activate()
    Dim wdDoc As Word.Document
    Set wdDoc = objOpenInspector.WordEditor
    wdDoc.Windows(1).Panes(1).View.Zoom.Percentage = MsgZoom
End Sub
    
Private Sub myOlExp_SelectionChange()
    On Error GoTo ErrHandler:
    Set Msg = Application.ActiveExplorer.Selection(1)
    Application.ActiveExplorer.RemoveFromSelection (Msg)
    Application.ActiveExplorer.AddToSelection (Msg)
    sExplorer.Item = Application.ActiveExplorer
    Set Document = sExplorer.ReadingPane.WordEditor
    Document.Windows.Item(1).View.Zoom.Percentage = MsgZoom
    Exit Sub
    
ErrHandler:
    Exit Sub
    
End Sub

I have to click on the email, then click it again to get the auto-zoom to work. In the past, I clicked on the email once.

I am using Microsoft Outlook 2016 version 1805 (Build 9330.2087)

The code section that cause the problem is in myOlExp_SelectionChange().

Auto-zooming works in debugging mode when I add a breakpoint in myOlExp_SelectionChange() and step through the code.

Community
  • 1
  • 1
user1315789
  • 3,069
  • 6
  • 18
  • 41
  • I have just tested that in my Outlook 2016 (16.0.9226.2156) and it works immediately. – Eugene Astafiev May 28 '18 at 00:51
  • What version and build number of Outlook 2016 do you have installed on the machine? – Eugene Astafiev May 28 '18 at 00:51
  • Eugene, I am using Microsoft Outlook 2016 version 1805 (Build 9330.2087) – user1315789 May 28 '18 at 00:55
  • Looks like I need to get the latest updates. Let you know how it goes with a new build :) – Eugene Astafiev May 28 '18 at 00:58
  • Ok. I am on Outlook 2016 (16.0.9330.2073) x86. It works fine. Try to run the code outside of event handlers under the debugger (F5) in VBA editor. Do you get the same results? – Eugene Astafiev May 28 '18 at 01:10
  • Strange behavior. When I run code in debugger even within event handler, no problems are encountered. THe code runs in `myOlExp_SelectionChange`. Stranger behavior is this. If breakpoint is placed after `sExplorer.Item = Application.ActiveExplorer`, no problem. If breakpoint is placed before `sExplorer.Item = Application.ActiveExplorer`, problem happens. – user1315789 May 28 '18 at 01:40
  • I edited the question to add in some new discovery I made during debugging. – user1315789 May 28 '18 at 02:01
  • Is possible the event now fires before the reading pane is switched to the new item, and you are essentially updating zoom on the previously selected item? – Dmitry Streblechenko May 28 '18 at 03:25
  • You can try to use a timer to fire your code a few milliseconds after SelectionChange event fires, but I don't think a timer object is at all available in VBA. – Dmitry Streblechenko May 28 '18 at 03:26
  • @user1315789 Is that last part supposed to say `Item(1)`? **That will only ever apply to the first email in the folder**, right? Also there's a hardcoded `(1)` earlier in the code, I'm not sure whether that one matters. Al of this "strange behaviour" points at a variable or object not having the value you're expecting. When you break code just before the zoom, check the values of related variables and objects (use the Watch window) – ashleedawg May 28 '18 at 03:57
  • @DmitryStreblechenko - There's no Timer *obect* but there's a Timer *function* that could cause a delay -- but I don't think a timer is the right way to deal with this type of issue. – ashleedawg May 28 '18 at 04:02
  • Timer function is different - it essentially puts the current thread to sleep. What you need is to check is whether running your code later than SelectionChange even is the solution. I suspect that is exactly what happens. – Dmitry Streblechenko May 28 '18 at 06:25

2 Answers2

2

Try to use the following call in the event handler before changing the Zoom level:

Application.DoEvents()

The DoEvents function yields execution so that the operating system can process other events. DoEvents passes control to the operating system. Control is returned after the operating system has finished processing the events in its queue and all keys in the SendKeys queue have been sent. DoEvents is most useful for simple things like allowing a user to cancel a process after it has started, for example a search for a file. For long-running processes, yielding the processor is better accomplished by using a Timer or delegating the task to an ActiveX EXE component. In the latter case, the task can continue completely independent of your application, and the operating system takes care of multitasking and time slicing. Any time you temporarily yield the processor within an event procedure, make sure the procedure is not executed again from a different part of your code before the first call returns; this could cause unpredictable results.

Private Sub myOlExp_SelectionChange()
 DoEvents
 Set Msg = Application.ActiveExplorer.Selection(1)
 Application.ActiveExplorer.RemoveFromSelection (Msg)
 Application.ActiveExplorer.AddToSelection (Msg)
 sExplorer.Item = Application.ActiveExplorer

 Set Document = sExplorer.ReadingPane.WordEditor
 Document.Windows.Item(1).View.Zoom.Percentage = MsgZoom

End Sub

Also you may try to use a timer for introducing a delay before adjusting the Zoom level. You can use the SetTimer and KillTimer Windows API functions. See Outlook VBA - Run a code every half an hour for more information.

user1315789
  • 3,069
  • 6
  • 18
  • 41
Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • You're a genius. So glad StackOverflow has a genius like you to help people like me. It's a wonderful community. Your solution works. I have edited your answer to reflect the code that has been tested to work for me. Thanks a lot! – user1315789 May 29 '18 at 00:30
-1

In outlook 2018 onwards, there is an option to save the zoom (please right click on the zoom percentage in the status bar)

dsp0105
  • 1
  • 1