2013-12-03 2 views
11

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

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)); 
    ... 
} 

EDIT

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

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

EDIT 2

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

EDIT 3

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

+0

Вы пытались вызвать 'SetParent (_excelApp.Hwnd, ((HwndSource) HwndSource.FromVisual (this)). Handle)' перед вызовом 'SetWindowLong (...)'? –

+0

@ EfranCobisi: Просто попробовал. Excel 2013 по-прежнему падает. – dotNET

+0

Если вы делаете 'try' /' catch', какую ошибку он дает? –

ответ

11

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

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 сильно поддерживается.

+1

Спасибо за проницательный ответ. Похоже, надстройка будет способом продвижения вперед. Я все еще пытаюсь взломать эту проблему, хотя и добился определенных успехов, но решение нестабильно и есть несколько более мелких проблем. Я подожду большего ввода, прежде чем выбрать этот хороший пост в качестве ответа. Еще раз спасибо. – dotNET

+1

EXCEL addin - это, безусловно, один подход, но я думаю, что также возможно встроить Excel в другое приложение, но, безусловно, не на вашем пути, попробуйте OLE-оболочки для Excel. – zinking

+0

Plz проверить мое второе редактирование выше. – dotNET

Смежные вопросы