Я пытаюсь воспроизвести поведение, которое я наблюдаю в JScript, на C #. Я использую IDispatch для перечисления членов и вызова их для объектов с поздним связыванием. Я полный новичок в C ++ и знаю о COM достаточно, чтобы быть очень опасным. Вот мои вопросы:
- Всегда ли DISPID_VALUE равен нулю (0)? (Кажется, да)
- Когда при вызове COM-объектов мне следует обращаться к члену DISPID_VALUE? (что-то вроде, когда сам интерфейс индексируется или вызывается ...?)
- Есть ли какие-то правила / подсказки, когда вызывать .Item?
- Почему в приведенном ниже примере BindingFlags.SetProperty работает с .Cells (x, x) (в отличие от BindingFlags.InvokeMethod)? Он вызывает _Default (x, x)? Пункт (x, x)? Откуда он знает, как это сделать? Как я могу узнать, куда он звонит?
- Есть ли хорошая документация по вызову COM-объектов IDispatch с поздним связыванием?
В приведенном ниже примере в ячейке 1,1 электронной таблицы Excel задано значение некоторого текста и выделено жирным шрифтом.
Рассмотрим следующий WSH JScript:
var objExcel = new ActiveXObject("Excel.Application");
objExcel.Workbooks.Add();
objExcel.Visible = true;
objExcel.Cells(1,1).Value = "some test value";
objExcel.Cells(1,1).Font.Bold = true;
Этот код C # дает тот же результат (да, извините, он очень подробный):
Type axType = Type.GetTypeFromProgID("Excel.Application");
object objExcel = Activator.CreateInstance(axType);
object workbooks = objExcel.GetType().InvokeMember("Workbooks", System.Reflection.BindingFlags.GetProperty, null, objExcel, null);
objExcel.GetType().InvokeMember("Visible", System.Reflection.BindingFlags.SetProperty, null, objExcel, new object[] { true });
workbooks.GetType().InvokeMember("Add", System.Reflection.BindingFlags.InvokeMethod, null, workbooks, new object[] { true });
object cell = objExcel.GetType().InvokeMember("Cells", System.Reflection.BindingFlags.GetProperty, null, objExcel, new object[] { 1, 1 });
cell.GetType().InvokeMember("Value", System.Reflection.BindingFlags.SetProperty, null, cell, new object[] { "some test value" });
object font = cell.GetType().InvokeMember("Font", System.Reflection.BindingFlags.GetProperty, null, cell, null);
font.GetType().InvokeMember("Bold", System.Reflection.BindingFlags.SetProperty, null, font, new object[] { true });
Когда у меня появляется время, я планирую попытаться узнать больше об этом, если JScript вызовет класс C # COM, который я бы создал с ведением журнала / отладкой.