How to capture the tick event of the task checkbox on 'Outlook Today'? VSTO Add-in - vb.net

I'm developing an Outlook Add-in, and currently I have no idea on how to capture the task's checkbox (mark complete) tick event -- particularly on the 'Outlook Today' view. I'd like to override it with my own function.
Refer to the attached image as reference to the checkbox being referred to.
Outlook Today Task

The Outlook Today page is not a typical area that can be integrated with. It is possible though, as it is basically an .html page; see: https://technet.microsoft.com/library/cc750169.aspx. However, this is 20 year-old technology...
If you are mainly interested in trapping changes to that task, then you can trap the Items.ItemAdd event for the Tasks folder and do whatever you like with the modified Task.

The Outlook object model doesn't provide anything for the Outlook Today page. It just lists items from your folders. So, you may consider handling the following events to get the job done:
The ItemChange event of the Items class which is fired when an item in the specified collection is changed.
The PropertyChange event of Outlook items which is fired when an explicit built-in property of an object is changed.
Both events are fired when you mark the task as completed. But in case of the PropertyChange event you need to subscribe to each task item individually which is not really convenient.

Related

Can VBA code run after an application is closed?

I am using the ItemAdd event to watch for new Outlook emails. Does this event work while the application is closed?
Currently, my macro launches upon initial startup using the "Application_Startup()" event, and then initializes a class module containing a sub routine that is trigged with the "ItemAdd" event. If I close Outlook, will this macro still be watching for a new "ItemAdd" event?
Thanks!
No, it will not - the event is fired by the application only, so no application - no event.
Keep in mind that if this is a cached profile, these events will fire on application startup when the cached mailbox (OST) is updated. You can also work around this by processing all unread emails on startup (assuming they stay unread). Or you can persist the MailItem.ReceivedTime property of your last processed message and process all emails newer than that on startup.

VSTO Outlook AddIn: How to handle event when AppointmentItem.Body changes

I tried to catch the event when the AppointmentItem.Body changes. Handling the PropertyChange on the AppointmentItem does not get called when I type in text or save the AppointmentItem. It gets called when I hit the button "Add Participants though".
Best would be to get the Keydown on the body editor?
The Outlook object model may not propagate changes made in the Outlook UI until you switch focus to another field and/or save the item. This is a well-known issue when dealing with the Outlook object model.

Outlook VSTO-AddIn: Prevent Outlook from deleting an appointment

I try to prohibit in certain cases that the user deletes an appointment. Something like this:
User clicks on appointment in calendar
User selects delete
VSTO-Addin checks whether this is allowed and shows a warning dialog in case if not. Outlook does NOT delete the appointment!
Currently I attached to Item_Delete_Add() and I think that one can only handle the deletion but you cannot prevent outlook from actually deleting the appointment. Correct?
You are on the right avenue... The Items.ItemRemove event is fired when an item is deleted from the specified collection. This event does not run when the last item in a Personal Folders file (.pst) is deleted, or if 16 or more items are deleted at once from a PST file, Microsoft Exchange mailbox, or an Exchange public folder. Moreover, you must keep the reference to the source object to know which item is being deleted from a folder. To get this working you must subscribe to the SelectionChange event of the Explorer class. It is fired when the user selects a different or additional Microsoft Outlook item programmatically or by interacting with the user interface. So, you could subscribe to every selected item and know which item exactly is removed.
Another possible way is to handle the AppointmentItem.BeforeDelete event which is fired before an item (which is an instance of the parent object) is deleted. An instance of the item being deleted is passed as a parameter. In order for this event to fire when an email message, distribution list, journal entry, task, contact, or post are deleted through an action, an inspector must be open. The event occurs each time an item is deleted. It also allows to cancel the actions by setting the second parameter - if the event procedure sets this argument to true, the operation is not completed and the item is not deleted.
Yet another approach is to repurpose ribbon controls, see Temporarily Repurpose Commands on the Office Fluent Ribbon for more information.

VSTO:Prevent specific AppointmentItems to be converted to recurring AppointmentItems

I am trying to build a Outlook AddIn. In certain cases I want to know whether the user is trying to convert the current AppointmentItem to a recurring AppointmentItem.
Is it possible to catch this event? Is it possible to prevent the event from happening in certain cases?
thanks
You can catch the AppointmentItem.PropertyChange("IsRecurring") event - it will fire whenever the recurrence pattern is changed. You can then prompt the user and call AppointmentItem.ClearRecurencePattern().
AppointmentItem can be retrieved from Inspector.CurrentItem, and inspector can be retrieved from the Inspectors.NewInspector event.

WithEvents object in Outlook VBA eventually fails to raise event

Okay, looks like someone has encountered this problem before, but I didn't see any further comments or solutions. See the Edit in the accepted answer to this question.
My situation is like this.
I am running Outlook 2013 under Win10 x64 with an Exchange email account. I sometimes run Outlook for several days to a week or more at a time without closing it.
I want to raise an event when a new item is added to the Sent Mail folder. This needs to occur after the Application ItemSend event because, let's say, I want to delete the message after it is sent, which you cannot do from within the ItemSend event handler.
So I have the following code:
Public WithEvents goSent As Outlook.Items
Private Sub Application_Startup()
'Establish the global object for the folder we want to monitor.
Set goSent = Session.GetDefaultFolder(olFolderSentMail).Items
End Sub
Private Sub goSent_ItemAdd(ByVal Item As Object)
'Do stuff here.
End Sub
Everything works beautifully for a day or longer, but eventually the ItemAdd event handler stops firing. If I enter the VBA editor and manually run Application_Startup, then it starts working again.
[Edit:] One other bit of information: The "built-in" events, like Application ItemSend, always seem to fire reliably no matter how long Outlook has been running.
[Edit 2:] This time, I let things go for a day after the event stopped firing. I opened the VBA editor and put a breakpoint in the Application ItemSend procedure. When it stopped, I queried the goSent object and found that (a) it still existed (rather than being Nothing), but (b) it had only the items in it that were there yesterday, presumably at the time it became "untethered" from the Sent Mail items collection. When I submitted a new Set statement in the Immediate window, it immediately began to work again.
[Edit 3:] I noticed that the MSDN documentation says to put event handlers for custom objects--like my ItemAdd event--in class modules. I have mine in ThisOutlookSession, but it was my understanding that ThisOutlookSession is a class module. Is there a problem with that?
Any idea why this would happen and what to do about it? I considered adding an event handler for Application ItemSend and just reassigning the goSent object every time that's fired, but it doesn't address the underlying problem.
[Edit 4:] For a while now, I've had a Set statement in the Application ItemSend handler, and that seems to have mostly taken care of things, even though it's a workaround, not really a solution. It appears to fail when I have delayed delivery on a sent item for an extended time, and I don't send any further messages in the meantime. Then the goSent object disconnects from the Sent Mail collection, and the message is actually sent from the Outbox after that point and before Application ItemSend fires again.
Thanks!
[Edit 5:] Unrelated to original issue: I discovered that my macros fail to accomplish what I want with an Exchange server that is in online mode (i.e., not cached mode) if I have messages in the Outbox with delayed delivery and Outlook is closed when the delivery time passes. In online mode, Exchange itself sends these messages and adds them to the Sent Mail folder on the server, so when Outlook reopens, the messages are already in the Sent Mail collection and no event fires. Which makes sense. See discussion here. Looks like I would need to add something to my Application_Startup macro to look for messages sent since Outlook last closed.
I had similar issue and never found a proper solution. What I did was I wrote a little batch script that closes and opens outlook app, then I set a task in task scheduler to run it every hour outside of my working hours. You can also do it easily in vbs.