Autozoom email window using myOlExp_SelectionChange with single click - vba

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.

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.

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

Related

Outlook VBA Code stops firing after some time

The code below works perfectly:
Option Explicit
Dim myOlApp As New Outlook.Application
Public WithEvents myOlInspectors As Outlook.Inspectors
Private Sub Application_Startup()
Initialize_handler
End Sub
Public Sub Initialize_handler()
Set myOlInspectors = myOlApp.Inspectors
End Sub
Private Sub myOlInspectors_NewInspector(ByVal Inspector As Outlook.Inspector)
Dim msg As Outlook.MailItem
If Inspector.CurrentItem.Class = olMail Then
Set msg = Inspector.CurrentItem
If msg.Size = 0 Then
'MsgBox "New message" ' TEST LINE
msg.CC = "email#email.com"
End If
End If
End Sub
However, after a few hours of works. It suddenly stops firing (and I don't get any error).
Is there something I missunderstand about the code?
Is there something about Outlook.Inspectors, that makes it stop launching for some reason?
Your event method may fail if no item is currently open.
To add a CC recipient, you should do something like
Set myRecipient = msg.Recipients.Add("email#email.com")
myRecipient.Type = olCC
Documentation
Most probably the event is fired properly, but you have got an error in the code at runtime. The NewInspector event is not the best place for getting the CurrentItem property:
Private Sub myOlInspectors_NewInspector(ByVal Inspector As Outlook.Inspector)
Dim msg As Outlook.MailItem
If Inspector.CurrentItem.Class = olMail Then
Set msg = Inspector.CurrentItem
If msg.Size = 0 Then
'MsgBox "New message" ' TEST LINE
msg.CC = "email#email.com"
End If
End If
Especially the following line of code could raise an error at runtime:
If Inspector.CurrentItem.Class = olMail Then
Instead, consider using the first Inspector`s Activate event which is fired when an inspector becomes the active window, either as a result of user action or through program code. So, in the first Activate event you could get item's properties without a problem.
Also you may consider adding On Error statement to the code so you could be aware why the event "is not fired".

How can I create a warning message in Outlook when attaching certain file types?

I have a tendency to, out of habit, send firmware files over email and new policy demands we do otherwise.
How can I generate a pop-up message in Outlook to remind me to place these files on the network rather than sending them through email, based on file extension (.S usually)?
The challenge here is getting the handle of the new item (untitled email) while using the Outlook UI rather than creating a new item via VBA. You need to first set the inspectors collection to a user-defined object, which will eventually contain the parent (new inspector) of our new item (untitled email). That can be done by an application level event such as Startup.
Then, we can use a NewInspector event to see if the new inspector contains a new message or not; if so, we set it to a module level MailItem object that we have defined on top.
Now, we are set to use a BeforeAttachment event to check the extension of the file that is being attached, if the extension is a banned extension, it will prompt a message and will cancel attaching.
You can still improve this by making extension comparison better and more accurate or copying the file with banned extensions to the location you want without making you to do that manually or even opening the folder you need to place the files there using windows explorer.
to place the code: ALT + F11, double click on ThisOutlookSession, paste the code and CTRL + S to save
I hope this helped! :)
Option Explicit
Dim WithEvents myItem As Outlook.MailItem
Private WithEvents myOlInspectors As Outlook.Inspectors
Private Sub Application_Startup()
Set myOlInspectors = Application.Inspectors
End Sub
Private Sub myOlInspectors_NewInspector(ByVal Inspector As Outlook.Inspector)
Dim msg As Outlook.MailItem
If Inspector.CurrentItem.Class = olMail Then
Set msg = Inspector.CurrentItem
If msg.Size = 0 Then
'MsgBox "New message" 'uncomment to test this routine
Set myItem = msg
End If
End If
End Sub
Private Sub myItem_BeforeAttachmentAdd(ByVal myAttachment As Attachment, Cancel As Boolean)
Dim sExtension As String
Dim sBannedExtension As String
Dim arr As Variant
sBannedExtension = "xlsx,frm,docx,jpg,png"
arr = Split(myAttachment.FileName, ".")
sExtension = arr(UBound(arr))
If InStr(UCase(sBannedExtension), UCase(sExtension)) > 0 Then
MsgBox "Sorry, you cannot send a file with a(n)" & sExtension & " extension as an attachment according to the new policy."
Cancel = True
End If
End Sub

Close event not working when opening and closing multiple Task-items

I got the following situation.
Open an outlook task
The open event is executed
Open a second outlook task
The open event is executed
Close the first task
No close event is executed !!!
Close the second task
The close event is executed
Does anybody have a clue what is happening here ?
Did I do some bad programming ? I have placed my code below.
Thank you in advance.
Kind regards,
Wamor
Public WithEvents objInspectors As Outlook.Inspectors
Public WithEvents objJournal As Outlook.JournalItem
Public WithEvents objTask As Outlook.TaskItem
Dim objOldTask As Outlook.TaskItem
Private Sub Application_Startup()
Set objInspectors = Outlook.Inspectors
Set objTask = Nothing
Set objJournal = Nothing
Set objOldTask = Nothing
End Sub
Private Sub objInspectors_NewInspector(ByVal Inspector As Inspector)
If TypeOf Inspector.CurrentItem Is TaskItem Then
Set objTask = Inspector.CurrentItem
End If
If TypeOf Inspector.CurrentItem Is JournalItem Then
Set objJournal = Inspector.CurrentItem
End If
End Sub
Private Sub objTask_Open(Cancel As Boolean)
MsgBox "TaskItem open event"
End Sub
Private Sub objTask_close(Cancel As Boolean)
MsgBox "TaskItem close event"
End Sub
Of course - you have multiple open objects but only a single variable to store a reference to them.
The standard way of dealing with problems like this is to have a wrapper class that has Inspector and the Item (two items - TaskItem and JournalItem in your case) as variables. TaskOpen and TaskClose event handlers will be methods on that wrapper class.
When NewInspector event fires, create an instance of your wrapper class and populate its properties. Add the wrapper class to a global list.
When close event fires, remove the wrapper class from the list.

MailItem.Reply Event not working as expected

I want to write a script that changes the format of the mail, when I am replying to a text- or rtf-mail, using Outlook 2013. To have something to begin with. I used the reply event described in the MS dev centre. Unfortunately the example does not work as I expect it to. For testing, I put in a simple message box that should pop up after clicking the reply button. I never see that message box. What did I do wrong?
Public WithEvents myItem As MailItem
Sub Initialize_Handler()
Set myItem = Application.ActiveInspector.CurrentItem
End Sub
Private Sub myItem_Reply(ByVal Response As Object, Cancel As Boolean)
'Set Response.SaveSentMessageFolder = myItem.Parent
MsgBox "I never see this message box :("
End Sub
Do you click Reply in the Explorer or Inspector? Your code will only run if you click Reply button in an Inspector.
To use the method promoted by Microsoft you need this code in ThisOutlookSession. It would be needed if the event code is not in this special class module.
Private Sub Application_Startup()
Initialize_handler
End Sub
The method described in the answer from Max, where code is in Application_Startup rather than Initialize_handler, can be used if all code is in ThisOutookSession.
you have to put this into "ThisOutlookSession" - only there it will work!
Option Explicit
Private WithEvents objInspectors As Outlook.Inspectors
Private Sub Application_Startup()
Set objInspectors = Outlook.Inspectors
end Sub
Private Sub objInspectors_NewInspector(ByVal Inspector As Inspector)
If Inspector.CurrentItem.Class = olMail Then
Set newItem = Inspector.CurrentItem
End If
Set Inspector = Nothing
End Sub
Public Sub newItem_Open(Cancel As Boolean)
newItem.BodyFormat = olFormatHTML
If newItem.Sent = True Then Exit Sub
End Sub
This will work on any new mail-item, I do not know how to make this work only for replys. You could check the subject, if there is an subject already it will be an reply.

While itemadd event works in my outlook it doesn't work in friends pc

I have code which works in my system but not in my friend's PC. Both use the same Outlook version.
Here is the snippet.
Private WithEvents olInboxItems As Items
Private Sub start_Click()
Dim objNS As nameSpace
Set objNS = Application.Session
' instantiate objects declared WithEvents
Call accessInbox(inbox) // my own function
Set olInboxItems = inbox.Items
'Set objNS = Nothing
Me.Hide
End Sub
Private Sub olInboxItems_ItemAdd(ByVal Item As Object)
On Error Resume Next
MsgBox "a Message recieved"
'Call download(Item)
Call multiSubjectDownload(Item) //my own function
End Sub
What may be the problem?
Are there settings that differ which prevent the code detecting new mail in inbox?
i found the error i was n't referring to inbox. so event was not firing because my item event was on inbox :)