«Читать» событие для Mailitem в Outlook 2007 VSTO VB.NET - PullRequest
0 голосов
/ 16 ноября 2011

Хорошо, это немного сложно ...

Я программирую надстройку для MS Outlook 2007, используя VS 2010 и VSTO, а также VB.NET.Моя цель - побудить пользователя распечатать электронные письма, которые они получают с определенных адресов электронной почты.(Это можно сделать с помощью простого MsgBox.)

В частности, я бы хотел, чтобы пользователь подсказывал, когда он закончит читать электронную почту .Моя концепция заключается в том, что он должен работать аналогично функциональности «Чтение квитанций» в Outlook.(Вы знаете, эти надоедливые вещи ... "Отправитель запросил квитанцию, что вы прочитали это письмо, бла-бла" )

Итак, пользователь читает письмо, а затем, когдаони закрывают Инспектора (или изменяют фокус на другой элемент, если они находятся в представлении Проводника), всплывающее окно MsgBox.Я заметил, что время для этого совпадает, когда электронное письмо становится «прочитанным».

Я гонялся за этим по Google, MSDN и учебным сайтам в течение нескольких дней, вот что я нашел:

Раунд 1: Объект Mailitem имеет свойство UnRead, а также событие PropertyChange.Я могу использовать AddHandler для PropertyChange для каждого Mailitem в папке «Входящие», связывая их в одну подпрограмму, которая проверяет аргумент события PropertyChange, чтобы убедиться, что это UnRead.Кажется вполне работоспособным, за исключением того, что PropertyChange не передает идентификатор вызывающего объекта, поэтому у меня нет возможности узнать, что электронная почта в папке «Входящие» только что потеряла «непрочитанный» статус.

Фактически, ни одно из событий Mailitem, кажется, не передает свою идентичность, возможно, потому, что кто-то (я полагаю, MS) предполагает, что у вас есть прямой указатель на объект Mailitem.Так что этот маршрут, похоже, не работает.

Раунд 2: Я могу взять все почтовые элементы в папке «Входящие» в коллекцию, а затем ограничить их только непрочитанными.

Dim inbox As Outlook.MAPIFolder = Nothing
Dim WithEvents unreadItems As Outlook.Items

inbox = Me.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox)
unreadItems = inbox.Items.Restrict("[Unread]=true")

Поскольку unreadItems был Dimmed WithEvents, я мог бы написать подпрограмму для обработки unreadItems.ItemRemove, которая бы работала нормально.Но событие ItemRemove не имеет аргумента объекта!Doh!

Раунд 3: Допустим, я поступаю наоборот: я получаю содержимое папки входящих сообщений и ограничиваюсь [Unread] = false, затем использую событие .ItemAdd.Это будет работать до некоторой степени, за исключением того, что теоретически он будет вызывать всякий раз, когда элемент «[Unread] = false» был выгружен пользователем в папку «Входящие» из любой папки, а не просто переход из группы «Непрочитано» в «Читать» в папке «Входящие».Так что, если я не понимаю что-то здесь, это тоже не вариант.

Раунд 4: Теперь, я также подумал о том, чтобы просто затемнить коллекцию элементов Inbox WithEvents и выйти из нее.Событие ItemChange, но это событие на самом деле не указывает, что изменилось в объекте, так что не нужно костей.


В заключение, я чертовски озадачен.Я очень близок к тому, чтобы отступить от своей цели.Хромой альтернативой является оповещение пользователя, когда он получает электронное письмо с одного из указанных адресов (потому что я считаю, что событие Application.NewMail не доставит мне хлопот).Но тогда мне придется просто предупредить пользователя - я не буду предлагать им напечатать письмо, которое они еще даже не прочитали.

Эта альтернатива нежелательна, и я решил, что представлю свою проблемудля проверки и предложения.

-Matt

PS Я собираюсь делать приложения для iPad с Objective-C, где я сам создаю большую часть иерархии объектов ... это странноприходится иметь дело с COM-объектами, имеющими такие ограничения.

1 Ответ

3 голосов
/ 16 ноября 2011

Я не совсем уверен, как вы хотите, чтобы ваш пользовательский интерфейс вел себя, потому что не совсем понятно, когда пользователь закончил читать его электронную почту .Один из способов взглянуть на это состоит в том, что они сделаны, когда посмотрели на него, то есть окно инспектора показало почту, и пользователь переключается на другое.Чтобы поймать это, вам, вероятно, лучше всего наблюдать за событиями от инспектора, а не от почтовых отправлений.Другой способ взглянуть на это состоит в том, что письмо читается всякий раз, когда оно помечается как прочитанное.Имейте в виду, что пользователь может фактически отключить опцию, чтобы пометить элементы как прочитанные автоматически!Это можно сделать в Сервис-> Параметры-> Другое-> Панель чтения, например:

enter image description here

Кроме того, пользователь может выбрать элементы и пометить их как прочитанные вручную, поэтомувам нужно подумать о том, что вы хотите сделать в этом случае.

Если вы хотите следить за изменением свойства «чтение» MailItem, вы очень близки в первом раунде. Что нужно добавитьв том, что вы не должны связывать все свои обработчики с одной подпрограммой в одном экземпляре объекта.Вместо этого вы можете создать свой собственный класс, что-то вроде этого (код C #):

class ItemWatcher
{
    // The Outlook mailitem to watch for
    private Microsoft.Office.Interop.Outlook.MailItem itemBeingWatched = null;

    public ItemWatcher(Microsoft.Office.Interop.Outlook.MailItem item, Form1 parentForm)
    {
        itemBeingWatched = item;
        itemBeingWatched.PropertyChange += new Microsoft.Office.Interop.Outlook.ItemEvents_10_PropertyChangeEventHandler(itemBeingWatched_PropertyChange);
    }

    void itemBeingWatched_PropertyChange(string Name)
    {
        // Respond to property <Name> in the object itemBeingWatched having changed
    }
}

Затем вам нужно создать коллекцию ваших классов ItemWatcher и настроить их на просмотр ваших писем.
Обратите внимание, чтовам также нужно следить за элементами, которые необходимо добавить / удалить из вашей коллекции просматриваемых элементов, когда приходит новое письмо или удаляется / перемещается старая почта.

...