Возврат Outlook.Items из DLL в MFC, а затем повторение элементов в MFC

Это моя текущая функция, которая является частью моей C# DLL, которая использует взаимодействие с Outlook:

public long PurgePTSCalendar(bool bPurgeAll)
{
    long lCount = 0;
    int iLastPercent = 0;

    if (!IsValid())
        return 0;

    try
    {
        // Get the MAPI namespace object (not sure exactly what this is)
        Outlook.NameSpace oMAPI = _OutlookApp.GetNamespace("MAPI");
        if (oMAPI == null)
            return 0;

        // Now get the default Outlook calendar folder
        Outlook.MAPIFolder oFolder = oMAPI.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
        if (oFolder == null)
            return 0;

        // Ensure it is a calendar folder.  This test is not strictly required.
        if (oFolder.DefaultItemType != Outlook.OlItemType.olAppointmentItem)
            return 0;

        // Get the collect of items from the calendar folder
        Outlook.Items oFolderItems = oFolder.Items;
        if (oFolderItems == null)
            return 0;

        Outlook.Items oItemsToPurge = null;

        // Do we want to purge all entries?
        if (bPurgeAll)
        {
            // Yes, purge all.
            oItemsToPurge = oFolderItems;
        }
        else
        {
            // No, we only want to purge records from today onwards
            // We must get a restricted list
            oFolderItems.Sort("Start");

            // Filter from today onwards (not any start / end 
            // date from a meeting or other item).
            String strStartDate = DateTime.Now.Date.ToShortDateString();
            string strFilter = "[Start] >=\"" + strStartDate + " 12:00 AM\"";
            oItemsToPurge = oFolderItems.Restrict(strFilter);
        }

        if (oItemsToPurge == null)
            return lCount;

        int iNumItems = oItemsToPurge.Count;

        for (int iItem = iNumItems; iItem >= 1; iItem--)
        {
            object oItem = oItemsToPurge[iItem];
            Outlook.AppointmentItem oEvent = (oItem as Outlook.AppointmentItem);

            int iPercent = ((iNumItems - iItem) + 1) * 100 / iNumItems;
            if (iPercent >= iLastPercent + 5 || iPercent == 100)
            {
                iLastPercent = iPercent;
                // Do Progress
            }

            if (oEvent != null)
            {
                // Get category for this item
                string strCat = oEvent.Categories;

                // Can we delete it?
                if (strCat == "xxx")
                {
                    oEvent.Delete();
                    lCount++;
                }
                Marshal.ReleaseComObject(oEvent);
            }
            Marshal.ReleaseComObject(oItem);
        }
        Marshal.ReleaseComObject(oItemsToPurge);
        Marshal.ReleaseComObject(oFolderItems);
        Marshal.ReleaseComObject(oFolder);
        Marshal.ReleaseComObject(oMAPI);
    }
    catch (Exception e)
    {
        MessageBox.Show(e.ToString());
    }

    return lCount;
}

Он вызывается в моем исполняемом файле MFC следующим образом:

long COutlookManagerEx::PurgePTSCalendar(bool bPurgeAll)
{
    __int64 lCount = 0;

    if (IsValid())
    {
        VARIANT_BOOL vbPurgeAll = VARIANT_FALSE;
        if (bPurgeAll)
            vbPurgeAll = VARIANT_TRUE;

        throw_if_fail(m_pInterface->PurgePTSCalendar(vbPurgeAll, &lCount));
    }

    return static_cast<long>(lCount);
}

Это работает без проблем. Просто ему не хватает мониторинга прогресса. Я пытался понять (через другой вопрос Я спросил) об обновлении индикатора выполнения в моем CDialog из DLL, но, к сожалению, я не понимаю инструкций, которые я прочитал в ссылках, приведенных в ответе.

В результате я пытаюсь упростить вещи. Может ли моя DLL вернуть объект oItemsToPurge? А потом из MFC мы зацикливаем этот объект и выполняем удаления оттуда?

Если бы я мог повторить список из MFC, а затем сделать вызов для удаления, когда я пошел, я мог бы обновить свой индикатор выполнения...


person Andrew Truckle    schedule 07.05.2019    source источник
comment
Практически все интерфейсы автоматизации основаны на COM. Возможна передача COM-объектов через границы DLL (хотя я не знаю, как это будет выглядеть на стороне С#). Вероятно, вы могли бы упростить свою конечную цель, вообще не используя сборку C#, если это возможно. Используя несколько недавнюю библиотеку COM (например, C++/WinRT) превратит ваш COM-код C++ в нечто такое же простое для чтения и записи, как C#. И вы получаете детерминированное время жизни в качестве бонуса.   -  person IInspectable    schedule 07.05.2019
comment
@IInspectable Означает ли это, что мое приложение Visual C++ MFC само может автоматизировать Outlook?   -  person Andrew Truckle    schedule 08.05.2019
comment
@IInspectable Я также подумал, что было бы проще всего передать функцию обратного вызова в DLL в качестве параметра, и тогда функция будет просто вызвана. Я предполагаю, что это может сработать, но не придумал, как это сделать.   -  person Andrew Truckle    schedule 08.05.2019
comment
Интерфейс автоматизации офиса основан на COM. COM не зависит от языка. Вы, безусловно, можете создать экземпляр сервера Office COM из приложения MFC. Вы можете возможно также передать какой-то делегат в сборку C# в качестве обратного вызова. Тем не менее, пересечение границы времени выполнения довольно сложно, и самым простым/надежным подходом будет использование COM для этого. Похоже, вам так или иначе придется использовать COM.   -  person IInspectable    schedule 08.05.2019