zoukankan      html  css  js  c++  java
  • IAccessible ( 二 )

    下来会分享如何获取子控件的IAccessible接口,在这个之前先讲点其它的东西:

    获取控件如果使用Findwindow(FindwindowEx)我们需要知道的控件的ClassName和CaptionName,这两个信息可以通过Spy++等工具获取,但我们在测试工具中会常见到Role等很多属性,先看这些信息是从什么地方来的,在microsoft的站点上下载Inspect32.exe运行后如:

    Inspect

     

    上面告诉了我们一个控件的详细信息,现在我们只关心classname, role, name。

    下面开始实现获取子控件IAccessible接口的代码,先看函数定义:

    BOOL Find (
    	IAccessible* paccParent, 
    	LPSTR szName, 
    	LPSTR szRole, 
    	LPSTR szClass, 
    	IAccessible** paccChild, 
    	VARIANT* pvarChild)
    第一个就是父窗体的IAcessible接口,依次分别为:name, role, classname, 子控件接口,类似于ID的东西(后面再解释) >看实现:
    BOOL Find (
    	IAccessible* paccParent, 
    	LPSTR szName, 
    	LPSTR szRole, 
    	LPSTR szClass, 
    	IAccessible** paccChild, 
    	VARIANT* pvarChild)
    {
    
    	HRESULT hr;
    	long numChildren;
    	unsigned long numFetched;
    	VARIANT varChild;
    	int indexCount;
    	IAccessible* pCAcc = NULL;
    	IEnumVARIANT* pEnum = NULL;
    	IDispatch* pDisp = NULL;
    	BOOL found = false;
    	char szObjName[MAX_PATH], szObjRole[MAX_PATH], szObjClass[MAX_PATH], szObjState[MAX_PATH];
    
    	//Get the IEnumVARIANT interface
    	hr = paccParent -> QueryInterface(IID_IEnumVARIANT, (PVOID*) & pEnum);
    
    	if(pEnum)
    		pEnum -> Reset();
    
    	// Get child count
    	paccParent -> get_accChildCount(&numChildren);
    
    	for(indexCount = 1; indexCount <= numChildren && !found; indexCount++)
    	{
    		pCAcc = NULL;
    
    		// Get next child
    		if (pEnum)
    			hr = pEnum -> Next(1, &varChild, &numFetched);	
    		else
    		{
    			varChild.vt = VT_I4;
    			varChild.lVal = indexCount;
    		}
    
    		// Get IDispatch interface for the child
    		if (varChild.vt == VT_I4)
    		{
    			pDisp = NULL;
    			hr = paccParent -> get_accChild(varChild, &pDisp);
    		}
    		else
    			pDisp = varChild.pdispVal;
    
    		// Get IAccessible interface for the child
    		if (pDisp)
    		{
    			hr = pDisp->QueryInterface(IID_IAccessible, (void**)&pCAcc);
    			hr = pDisp->Release();
    		}
    
    		// Get information about the child
    		if(pCAcc)
    		{
    			VariantInit(&varChild);
    			varChild.vt = VT_I4;
    			varChild.lVal = CHILDID_SELF;
    
    			*paccChild = pCAcc;
    		}
    		else
    			*paccChild = paccParent;
    
    		// Skip invisible and unavailable objects and their children
    		GetObjectState(*paccChild, &varChild, szObjState, sizeof(szObjState));
    		if(NULL != strstr(szObjState, "unavailable"))
    		{
    			if(pCAcc)
    				pCAcc->Release();
    			continue;
    		}
    
    		GetObjectName(*paccChild, &varChild, szObjName, sizeof(szObjName));
    		GetObjectRole(*paccChild, &varChild, szObjRole, sizeof(szObjRole));
    		GetObjectClass(*paccChild, szObjClass, sizeof(szObjClass));
    
    		if ((!szName || !strcmp(szName, szObjName)) && (!szRole || !strcmp(szRole, szObjRole)) && (!szClass || !strcmp(szClass, szObjClass)))
    		{
    			found = true;
    			*pvarChild = varChild;
    			break;
    
    		}
    		if(!found && pCAcc)
    		{
    			// Go deeper
    			found = Find(pCAcc, szName, szRole, szClass, paccChild, pvarChild);
    			if(*paccChild != pCAcc)
    				pCAcc->Release();
    		}
    	}
    
    	// Clean up
    	if(pEnum)
    		pEnum -> Release();
    
    	return found;
    }
    看获取控件状态的函数:
    UINT GetObjectState(IAccessible* pacc, VARIANT* pvarChild, LPSTR lpszState, UINT cchState)
    {
    	HRESULT hr;
    	VARIANT varRetVal;
    
    	*lpszState = 0;
    
    	VariantInit(&varRetVal);
    
    	hr = pacc->get_accState(*pvarChild, &varRetVal);
    
    	if (!SUCCEEDED(hr))
    		return(0);
    
    	DWORD dwStateBit;
    	int cChars = 0;
    	if (varRetVal.vt == VT_I4)
    	{
    		// Convert state flags to comma separated list.
    		for (dwStateBit = STATE_SYSTEM_UNAVAILABLE; dwStateBit < STATE_SYSTEM_ALERT_HIGH; dwStateBit <<= 1)
    		{
    			if (varRetVal.lVal & dwStateBit)
    			{
    				cChars += GetStateTextA(dwStateBit, lpszState + cChars, cchState - cChars);
    				*(lpszState + cChars++) = ',';
    			}
    		}
    		if(cChars > 1)
    			*(lpszState + cChars - 1) = '\0';
    	}
    	else if (varRetVal.vt == VT_BSTR)
    	{
    		WideCharToMultiByte(CP_ACP, 0, varRetVal.bstrVal, -1, lpszState,
    			cchState, NULL, NULL);
    	}
    
    	VariantClear(&varRetVal);
    
    	return(lstrlenA(lpszState));
    }
    
    
    
    用来获取一个控件是否可用。 下来看一个例子: 
    
    
    HWND hwnd = ::FindWindowW( NULL,L"Run");
    
    	IAccessible *paccMainWindow = NULL;
    	AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible, (void**)&paccMainWindow);
    
    	long count = 0;
    	paccMainWindow->get_accChildCount(&count);
    
    	IAccessible*	paccControl = NULL;
    	VARIANT			varControl;
    
    	if (Find(paccMainWindow, "Open:", "editable text", "Edit", &paccControl, &varControl))
    	{
    		paccControl->put_accValue(varControl, CComBSTR("123"));
    	}
    	
    
    运行结果:

    123Text

     


    作者:GangWang
    出处:http://www.cnblogs.com/GnagWang/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

     
  • 相关阅读:
    大型运输行业实战_day12_1_权限管理实现
    大型运输行业实战_day11_2_事务理论与实际生产配置事务管理
    大型运输行业实战_day11_1_aop理论与aop实际业务操作
    SpringBoot目录文件结构和官方推荐的目录规范、静态资源访问
    SpringBoot常用的注解
    Spring Boot面试题
    Spring常见面试题总结
    dubbo面试题及答案
    nginx面试题及答案
    Mybatis面试题及答案
  • 原文地址:https://www.cnblogs.com/GnagWang/p/1716449.html
Copyright © 2011-2022 走看看