I initially started using IMAP through outlook with version 2003. If you've used it for IMAP, or attempted to, then I'm sure you've felt my pain. Outlook 2007 should have been the fix for their terrible IMAP implementation, but alas, it was not.
I spent some time digging around online to find a way to make Outlook handle deleting emails a little more appropriately for an IMAP account. Most of the solutions involved incorporating a macro into the toolbar and from there having to highlight the emails to be 'deleted' and clicking an additional button. (see this and this) This solution was not acceptable since an untrained user will not know to do this. I needed something better.
I've never specifically written any VBA previously, but I have used Visual Basic frequently in the past, so I figured I would at least have an understanding of the language. I spent some time digging around the MSDN for object reference and getting myself familiar with inspectors and explorers.
I ended up adding inspectors to almost everything and watching as the events fired. At first it seemed like the MailItem's 'BeforeDelete' was my answer, but that only handled emails that you opened in it's own window and not any other time. What I ended up discovering is that a folder would fire the 'BeforeItemMove' even when an item was deleted, whether it was with the delete key or the toolbar button. The difference is that the MoveTo would be Nothing, instead of a destination folder. By trapping this event and passing it with my own function, the deleted emails can be moved to a trash folder of my own specification.
Of course the downside of this is that Outlook simply marks messages for deletion and shows them with a strikethrough. There are a few ways this can be handled. I've chosen to simply have outlook hide the items marked for deletion, and the folders auto-purge when changing (defined in the account settings). This meets all of my needs and is transparent to the user.
So basically this is what the code does: When you start Outlook, the script will create references so that it can watch as events happen. When you do something that would cause an item to be deleted (press delete, click the X on the toolbar) it will check to see if we have a folder named 'Trash' under the root folder, and if so, it will move the email to that folder.
Update February 7th, 2010: Received several emails of people having problems using the specified code, changed code to look for folder named "Deleted Items" which is the default Outlook trash folder name. Was previously using IMAP Trash default.
Update June 1st, 2009: Added check for Trash folder items so you can actually delete something that's in the trash
Outlook will need to be restarted after adding this code
To use this code, copy and paste it into 'ThisOutlookSession' in the VBA editor. (Tools/Macro/Visual Basic Editor) See the screenshots below for help.
You can either copy/paste this code or download outlookimapfix.txt
Public WithEvents myItem As MailItem 'for trapping deletion of opened mail Public WithEvents myInspector As Inspectors 'for trapping new windows Public WithEvents myExplorer As Explorer 'for folder reference Public WithEvents myFolder As Folder 'for trapping mail deletion in main outlook window Public myNameSpace As NameSpace 'Parent folder Private Sub Application_Startup() Set myInspector = Application.Inspectors Set myExplorer = Application.ActiveExplorer Set myFolder = myExplorer.CurrentFolder Set myNameSpace = Application.GetNamespace("MAPI") End Sub Private Sub myExplorer_BeforeFolderSwitch(ByVal NewFolder As Object, Cancel As Boolean) Set myFolder = NewFolder End Sub Private Sub myFolder_BeforeItemMove(ByVal item As Object, ByVal MoveTo As MAPIFolder, Cancel As Boolean) If TypeName(item) = "MailItem" Then 'only trap mail items Dim lMI As MailItem Set lMI = item If MoveTo Is Nothing And lMI.Parent <> "Deleted Items" Then 'Item was deleted moveIMAPItem lMI Cancel = True 'bypass normal deletion function End If End If End Sub Private Sub myInspector_NewInspector(ByVal Inspector As Inspector) If Inspector.CurrentItem.Class = olMail Then Set myItem = Inspector.CurrentItem 'New window for reading mail End Sub Private Sub myItem_BeforeDelete(ByVal item As Object, Cancel As Boolean) If TypeName(myItem) = "MailItem" Then 'only trap mail items moveIMAPItem item Cancel = True 'bypass normal deletion End If End Sub Private Sub moveIMAPItem(ByVal item As Object) Dim lMI As MailItem Dim fParent As Folder Dim parentFolder As Folder Dim trashFolder As Folder Set lMI = item Set fParent = myExplorer.CurrentFolder Do Until fParent.Parent = myNameSpace 'Root folder Set fParent = fParent.Parent Loop Set parentFolder = fParent If parentFolder.Folders("Deleted Items") Is Nothing Then 'Deleted Items folder doesn't exist MsgBox "Unable to find folder named 'Deleted Items'", vbOKOnly + vbInformation, "IMAP Delete" 'Inform user and exit routine Exit Sub End If Set trashFolder = parentFolder.Folders("Deleted Items") 'Set destination lMI.Move trashFolder 'move email End Sub