#c #com #ole #idispatch
#c #com #ole #idispatch
Вопрос:
Я программист на C, но я новичок в программировании на Windows и COM.
Для следующего кода C #:
//Change the font of the selected text in the running PowerPoint.
Application app = Marshal.GetActiveObject("Powerpoint.Application");
app.ActiveWindow.Selection.TextRange.Font = ...;
Я знаю, как написать соответствующий OLE-код на C. Кратко резюмируя:
- Вызовите GetActiveObject, чтобы получить неизвестный интерфейс приложения;
- Вызовите IUnknown_QueryInterface, чтобы получить IDispatch приложения;
- Вызовите IDispatch_GetIDsOfNames и IDispatch_Invoke с помощью DISPATCH_PROPERTYGET, чтобы получить именованное свойство текущего IDispatch.
- Повторяйте шаги со 2 по шаг 4, пока мы не дойдем до второго самого внутреннего свойства (то есть TextRange в приведенном выше примере).
- Вызовите IDispatch_GetIDsOfNames и IDispatch_Invoke с помощью DISPATCH_PROPERTYPUT, чтобы установить значение самого внутреннего свойства (то есть шрифта в приведенном выше примере).
здесь возникает вопрос: что, если свойство является «массивом»? Например, учитывая следующий код C #:
Application app = Marshal.GetActiveObject("Illustrator.Application");
foreach (object textFrame in app.ActiveDocument.TextFrames)
...;
Приведенный выше код C # выполняет итерацию каждого текстового фрейма из «массива» текстовых фреймов, я понятия не имею о соответствующем коде C для «итерации» такого свойства в C. Я искал в Интернете и ссылках на разработки Microsoft, но не смог получить никакой подсказки.
Как мне получить элементы из свойства «array» с помощью C?
Комментарии:
1. Это не массив. docs.microsoft.com/en-us/windows/win32/api/oaidl /…
2. Используете ли вы Visual Studio? С в порядке? Вы действительно хотите перечислять или сканировать каждый элемент по индексу, это нормально?
3. @SimonMourier Я использую MSYS Clang, я обычный программист Linux и временно работал над Windows. Проблема была решена с помощью xMRi
4. Вы можете взглянуть на библиотеку типов с помощью инструмента OleView из Windows SDK. Библиотека типов для illustrator находится по адресу C:Program FilesAdobe Adobe Illustrator 2021 Plug-ins ExtensionsScriptingSupport.aip (адаптируйте к вашему контексту). Он расскажет вам, что
Document
реализует тип. Вам не обязательно использовать _NewEnum , вы также можете использоватьlong Count()
TextFrame* Item(VARIANT key)
методы and, которые обычно немного проще из C / C и позволяют получить прямой доступ к элементу, используя его индекс.5. @SimonMourier Благодарю вас за информацию об инструменте и альтернативном решении. Этот инструмент, который вы рекомендовали, также может помочь в будущем развитии.
Ответ №1:
Текстовый фрейм может не быть массивом. Я полагаю, что это счетчик. Но проверьте возвращаемый тип в отладчике.
Или вам нужно показать нам файл типа lib или idl для используемого вами интерфейса.
В случае, если это итератор, объект TextFrames имеет свойство _NewEnum. Это имеет интерфейс IEnumVARIANT … обычно onNext вызывается до тех пор, пока onNext не вернет S_FALSE .
ИТАК, что здесь происходит, так это то, что ForEach asks вызывает свойство _NewEnum объекта TextFrames. Он может вызывать OnReset или OnClose, а затем вызывать onNext для каждого члена…
Если это массив, вы получаете ВАРИАНТ, содержащий SAFEARRAY.
Комментарии:
1. Спасибо за ваше информативное руководство. У меня есть ВАРИАНТ, vt которого равен VT_DISPATCH, поэтому он выглядит как перечислитель, как вы и предлагали. Но есть еще один шаг для решения проблемы. Я вызвал IDispatch_GetIDsOfNames(textFramesVar.pdispVal, amp;IID_NULL, (LPOLESTR[1]){L»_NewEnum»}, 1, LOCALE_USER_DEFAULT, amp;dispId); GetIDsOfNames просто не удалось (и использование GetIDsOfNames для получения идентификатора _NewEnum звучит неправильно для моего инстинкта). Является ли получение SDK, запрос интерфейса и затем вызов Get__NewEnum единственным способом получить свойство _NewEnum? Спасибо.
2. DISPID_NEWENUM — это константа… и исправлено для всех счетчиков.
3. Ссылка: docs.microsoft.com/en-us/previous-versions/windows/desktop/…
4. @xMRi Отлично, это работает! Спасибо за помощь.