Ошибка Excel 2013

Я пытаюсь встроить Excel 2013 в приложение WPF. Проблема в том, что когда я вызываю SetWindowLongPtr в следующем коде, Excel 2013 сбой немедленно. Я выкопал его и обнаружил, что если я прокомментирую стиль WS.CHILD, он отлично работает, но лист Excel становится только для чтения, чего я не хочу. Тот же код отлично работает с Excel 2010.

Excel.Application _excelApp;
IntPtr _wrappedApplicationHandle;
Int64 lngStyle;
Int64 lExStyle;    

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    _excelApp = new Excel.Application()
    {
        Visible = true,
        DisplayFormulaBar = true,
    };

    _wrappedApplicationHandle = new IntPtr( _excelApp.Hwnd);

    lngStyle = GetWindowLongPtr(_wrappedApplicationHandle, (int)GWL.STYLE).ToInt64();
    lngStyle &= ~(int)WS.CAPTION;
    lngStyle &= ~(int)WS.SIZEBOX;
    lngStyle |= (int)WS.MAXIMIZE;
    lngStyle |= (int)WS.CHILD; //<< crashes with this line
    lngStyle |= (int)WS.CLIPSIBLINGS;
    lngStyle |= (int)WS.CLIPCHILDREN;

    SetWindowLongPtr(new HandleRef(_excelApp, _wrappedApplicationHandle), 
                        (int)GWL.STYLE, 
                        new IntPtr(lngStyle));
    ...
}

ИЗМЕНИТЬ

Дополнительная информация, как я копаю. Я попробовал обернуть вышеуказанный код в блок try/catch, чтобы узнать, что произойдет. Он никогда не достигает блока catch. Excel 2013 сбой с печально известным "Приложение перестало работать. Отправьте отчет на MS". Я уже включил все исключения Win32/COM/С++ в Visual Studio (через Отладка меню > Исключения), но это тоже не помогает. В диалоговом окне ошибки есть кнопка Отладка. Если я нажму на эту кнопку и откройте отладчик, то я вижу сообщение msgid: "0xC0000005: местоположение чтения нарушения доступа 0x0000000000000000."

Я также обнаружил, что комментирование строки WS.CHILD в приведенном выше коде не делает строго рабочий лист только для чтения. Он просто блокирует общий ввод клавиатуры/мыши от доступа к рабочему листу. Но некоторые клавиши, такие как клавиша контекстного меню на клавиатуре, до сих пор доступны, и отображается контекстное меню (щелчок правой кнопкой мыши не работает). Точно так же я могу взаимодействовать с лентой Office с помощью мыши. Кажется, что только область рабочего листа (сетка с белым фоном) не получает ввод клавиатуры/мыши.

РЕДАКТИРОВАТЬ 2

Я только что напомнил, что (по-видимому), в отличие от того, что объяснил Ханс Пассант в своем сообщении ниже, VS2010 содержит экземпляр Excel сам по себе при создании проекта Excel VSTO Workbook. Хотя у меня нет VS2013 (Full) со мной и не могу подтвердить, я подозреваю, что VS2013 будет делать то же самое с проектами Excel VSTO Excel 2013. Учитывая, что VS2010 и выше все сами приложения WPF, как это соответствует изображению?

РЕДАКТИРОВАТЬ 3

Эта теория частных интерфейсов, предложенная @acelent (см. комментарий ниже), выглядит правильно. Я заглянул в экземпляр Excel, содержащий VS2010, и обнаружил, что появилось новое окно с именем class= EXCELI, которого нет, когда мы обычно открываем Excel (обычная иерархия окон - XLMAIN (приложение) > XLDESK (рабочая область область) > EXCEL7 (рабочая книга)). Кроме того, эта книга больше не доступна в качестве объекта ActiveX, которая раньше была в тех случаях, когда была доступна библиотека Office Web Components (последняя поставляется в Office 2003). Таким образом, в целом, мы, похоже, находимся в тупике, и я собираюсь предложить @Hans ответить на моего клиента, если кто-то не придумает фактический рабочий метод в ближайшие несколько часов.

Ответ 1

Вам нужно отказаться от этого, вы не можете заставить его работать надежно.

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

У Windows есть поддержка appcompat для SetParent(), требуемая, потому что это обычно делалось в программах Windows 3.x. Понятие процессов с отдельными адресными пространствами полностью отсутствовало в этой версии Windows, поэтому в то время это не было проблемой. Вероятность того, что это на самом деле работает должным образом через 20 лет, пропорциональна тому, как ведет себя процесс, как приложение Windows 3.x. Он работает нормально для консольного окна или простого приложения, такого как Блокнот. Приложения Office 2013 значительно превосходят простые и 3.x. У вас проблемы с вводом, безусловно, является отличительной чертой этого. Вы можете поработать с AttachThreadInput(), чтобы попытаться решить проблему, но вы, скорее всего, просто приступите к следующей проблеме, в том числе к ее неприятной привычке вызывать тупик, когда вы отладки.

Встраивание приложений Office, которые были широко поддерживаемыми функциями в Office, Microsoft преднамеренно разработали для их встраивания. Основная технология называлась OLE Linking and Embedding. Однако эта технология сильно устарела. Поддержка была умышленно убрана из .NET Framework. Office 2003 была последней версией, которая все еще поддерживала ее. Проблема началась в 2007 году, и она была полностью отменена в 2010 году. Она не вернется.

Путь вперед здесь является абсолютно противоположным. Не вставляйте приложение Office, а приложение Office вставляет вас. Написание надстроек для программ Office сильно поддерживается.