我试图复制我在 C# 中的 JScript 中观察到的行为。我正在使用 IDispatch 枚举成员并在后期绑定对象上调用它们。我是一个完整的 C++ 菜鸟,并且对 COM 的了解足够多,以至于非常危险。这是我的问题:
- DISPID_VALUE 是否始终为零 (0)?(似乎是的)
- 调用 COM 对象时,我应该何时调用 DISPID_VALUE 成员?(例如,当接口本身被索引或调用时......?)
- 何时调用 .Item 是否有任何规则/提示?
- 为什么在下面的示例中,BindingFlags.SetProperty 对 .Cells(x, x) 起作用(而不是 BindingFlags.InvokeMethod)?它是在调用 _Default(x, x) 吗?项目(x,x)?它怎么知道这样做?我怎样才能知道它在调用哪个?
- 是否有一些关于调用后期绑定的 IDispatch COM 对象的好文档?
在下面的示例中,Excel 电子表格的单元格 1,1 将值设置为某些文本并“加粗”。
考虑以下 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 类。