积极答复者
请教,C#下操作COM组件的几个问题

问题
-
最近正在学习MS Active Accessibility技术,本意是想做一个类似AccExplorer32这样的工具,在网络上找了一下相关的资料,发现了如下的页面:
http://vckbase.com/index.php/wv/651 (MS Active Accessibility 接口技术编程尝试)
根据这个教程给出的资料学习了一下,然后尝试以C#来写例子,发现一些问题,想请教一下各位大大:
Native Code
BOOL FindChild (IAccessible* paccParent,
LPSTR szName, LPSTR szRole,
LPSTR szClass,
IAccessible** paccChild,
VARIANT* pvarChild)
{
HRESULT hr;
long numChildren;
unsigned long numFetched;
VARIANT varChild;
int index;
IAccessible* pCAcc = NULL;
IEnumVARIANT* pEnum = NULL;
IDispatch* pDisp = NULL;
BOOL found = false;
char szObjName[256], szObjRole[256], szObjClass[256], szObjState[256];//得到父亲支持的IEnumVARIANT接口
hr = paccParent -> QueryInterface(IID_IEnumVARIANT, (PVOID*) & pEnum);if(pEnum)
pEnum -> Reset();//取得父亲拥有的可访问的子的数目
paccParent -> get_accChildCount(&numChildren);//搜索并比较每一个子ID,找到名字、角色、类与输入相一致的。
for(index = 1; index <= numChildren && !found; index++)
{
pCAcc = NULL;
// 如果支持IEnumVARIANT接口,得到下一个子ID
//以及其对应的 IDispatch 接口
if (pEnum)
hr = pEnum -> Next(1, &varChild, &numFetched);
else
{...
}
Managed Code
private bool FindChild(object paccParent, string szName, string szRole, string szClass, ref Accessibility.IAccessible paccChild, ref object pvarChild)
{
int hr = 0;
int numChildren = 0;
IntPtr numFetched = default(IntPtr);
object[] oChild = null;
int index = 0;
Accessibility.IAccessible pCAcc = null;
IntPtr pUnk = default(IntPtr);
IntPtr pInt = default(IntPtr);
IEnumVARIANT pEnum = null;
pUnk = Marshal.GetIUnknownForObject(paccParent);
hr = Marshal.QueryInterface(pUnk, ref Headers.IEnum_GUID, out pInt);
pEnum = (IEnumVARIANT)Marshal.GetObjectForIUnknown(pInt);
Marshal.Release(pUnk);
if (pEnum == null)
{
pEnum.Reset();
}numChildren = ((Accessibility.IAccessible)paccParent).accChildCount;
for (index = 0; index <= numChildren; index++)
{if (pEnum != null)
{
hr = pEnum.Next(1, oChild, numFetched); <--调试时中断于此,错误提示为:“其他信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”
}
else
{
......}
请问一下哪里有问题呢?
另外就是C++中的VARIANT类型翻译成C#下的话根据MSDN提供的信息对应Object类型,但想了很久都没明白,望大大们不惜赐教。
最后就是.NET下操作COM的书籍也请推荐一下,无论说VB还是C#的都可以。
答案
-
C#一般用UIA(UI Automatic)至于MSAA一般不怎么用。
object patObj; AutomationElement root = AutomationElement.FromHandle(base.Handle); AutomationElement edit = root.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit)); if (edit.TryGetCurrentPattern(ValuePattern.Pattern, out patObj)) { ValuePattern vpEdit; if ((vpEdit = patObj as ValuePattern) != null) vpEdit.SetValue("hello worlds"); }
全部回复
-
C#一般用UIA(UI Automatic)至于MSAA一般不怎么用。
object patObj; AutomationElement root = AutomationElement.FromHandle(base.Handle); AutomationElement edit = root.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit)); if (edit.TryGetCurrentPattern(ValuePattern.Pattern, out patObj)) { ValuePattern vpEdit; if ((vpEdit = patObj as ValuePattern) != null) vpEdit.SetValue("hello worlds"); }
-
C#一般用UIA(UI Automatic)至于MSAA一般不怎么用。
object patObj; AutomationElement root = AutomationElement.FromHandle(base.Handle); AutomationElement edit = root.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit)); if (edit.TryGetCurrentPattern(ValuePattern.Pattern, out patObj)) { ValuePattern vpEdit; if ((vpEdit = patObj as ValuePattern) != null) vpEdit.SetValue("hello worlds"); }
非常感谢您的回答。
UIA或许是.NET下最好的解决方法,但是我现在更想学习C#与COM的互操作,既然找不到解决的办法,那就算了。