IAccessiable的学习和使用
来源:互联网 发布:微视频神器软件 编辑:程序博客网 时间:2024/05/22 00:18
前几天听群里大神讨论IAccessiable借口,于是动念学习一下。打开百度,输入IAccessiable,得到一大堆的词条,仔细看就可以搞懂IAccessiable到底是个什么东东。以下摘自MSDN的一段描述:
The IAccessible interface and all of its exposed members are part of a
managed wrapper for the Component Object Model (COM) IAccessible
interface.
概念啥的一百就出来,但是这个东西到底怎么用呢?还是老办法,看看别人怎么用。以下为我找的一篇博客:
IAccessible ( 二 )
根据这篇博客弄了一个demo编译一下。结果,啊哈,果然有错,有错误不打紧,debug先。
很明显不认识IAccessiable这个类型啊。查阅MADN需要包含头文件,和lib文件
#include <OleAcc.h>
添加完成,再次编译,果然错误少了很多。
查阅代码发现有如下函数调用
GetObjectName(*paccChild, &varChild, szObjName, sizeof(szObjName));GetObjectRole(*paccChild, &varChild, szObjRole, sizeof(szObjRole));GetObjectClass(*paccChild, szObjClass, sizeof(szObjClass));
这三个函数在给定的Demo代码中并没有给出实现。仔细分析代码流程会发现,这三个函数功能其实很简单,就是获取给定子空间的Name, Role 和Class。没有枪没有炮,我们自己造。先造第一个GetObjectName函数原型很容易推断出,返回值我们不妨先不设,因为程序中也没有用到。以下函数原型:
void GetObjectName(IAccessible* child, VARIANT* varChild, char* objName, int len)
那么如何实现这个功能呢。翻阅MSDN我们发现IAccessable接口有这么个函数
HRESULT get_accName( [in] VARIANT varID, [out, retval] BSTR *pszName);
参数返回一个BSTR类型的Name,而我们需要一个char*类型。如何搞?用下微软的_bstr_t转换下。上代码:
void GetObjectName(IAccessible* child, VARIANT* varChild, char* objName, int len){ BSTR strTmp; HRESULT hr = child->get_accName(*varChild, &strTmp); if (S_OK != hr) { return; } _bstr_t str = strTmp; char* tmp = str; strcpy_s(objName, MAX_PATH, tmp);}
调试下,果然成功获取到Name值。
接下来的Class和Role过程大致类似,直接上代码:
void GetObjectRole(IAccessible* child, VARIANT* varChild, char* objRole, int len){ VARIANT pvarRole; DWORD roleId; child->get_accRole(*varChild, &pvarRole); if (varChild->vt != VT_I4) { pvarRole.vt = VT_EMPTY; return /*E_INVALIDARG*/; } roleId = pvarRole.lVal; UINT roleLength; LPTSTR lpszRoleString; // Get the length of the string. roleLength = GetRoleText(roleId, NULL, 0); // Allocate memory for the string. Add one character to // the length you got in the previous call to make room // for the null character. lpszRoleString = (LPTSTR)malloc((roleLength + 1) * sizeof(TCHAR)); if (lpszRoleString != NULL) { // Get the string. GetRoleText(roleId, lpszRoleString, roleLength + 1); } char* tmp = TCHAR2char(lpszRoleString); free(lpszRoleString); strcpy_s(objRole, MAX_PATH, tmp); return /*S_OK*/;}void GetObjectClass(IAccessible* child, char* objClass, int len){ HWND htmp; LPTSTR strClass; strClass = (LPTSTR)malloc(MAX_PATH); ::WindowFromAccessibleObject(child, &htmp); if (0 == ::GetClassName(htmp, strClass, MAX_PATH)) { free(strClass); return; } char* tmp = TCHAR2char(strClass); strcpy_s(objClass, MAX_PATH, tmp); free(strClass);}
其中涉及到一个问题,VS的默认编码是Unicode而我们需要一个char*这个绝对需要转换一下。如何转换呢?百一下得到了一个如下答案:
char* TCHAR2char(TCHAR* tchStr){ int iLen = 2 * wcslen(tchStr); char* chRtn = new char[iLen + 1]; int len = wcstombs(chRtn,tchStr, iLen + 1); return chRtn;}
还需要注意我们用到了_bstr_t和CComBSTR所以需要包含头文件和库文件查阅MSDN需要comsuppw.lib和头文件
#include <atlbase.h>
至此应该能编译通过了,但是回到宿舍,运行在中文环境的VS2015下并不能得到预期的结果。Debug之。发现,GetObjectName中的下列代码
wcstombs(buf, lpString, len);
返回值为-1,这个不科学啊,百度之。得到一个答案。没看明白,但是修改之后确实可以获取成功了。修改之后的代码:
char* TCHAR2char(TCHAR* tchStr){ int iLen = 2 * wcslen(tchStr); char* chRtn = new char[iLen + 1]; _tsetlocale(LC_ALL, _T("")); int len = wcstombs(chRtn,tchStr, iLen + 1); return chRtn;}
当然需要先加上头文件:
#include <locale.h>
大功告成,运行结果果然如预期一样。
- IAccessiable的学习和使用
- cult3d的学习和使用
- auto_ptr 的学习和使用
- 数据结构的使用和学习
- DP的学习和使用
- ExpandableListActivity的学习和使用
- PreferenceActivity的学习和使用
- 注解的学习和使用
- Tab的学习和使用
- jquery的学习和使用
- EditText的学习和使用
- Tab的学习和使用
- ant的学习和使用
- svn的学习和使用
- Tab的学习和使用
- git的使用和学习
- TreeSet的学习和使用
- Tab的学习和使用
- 笔试题(2016.4.7)
- 对象存储
- WTL for Visual Studio 2012 配置详解
- <css 八>border
- C++四则运算代码
- IAccessiable的学习和使用
- Hbase使用
- Android:inputType常用取值
- Problem 1001
- 新学JAVA二三事之字符串输出
- Java中Object有哪些公共类
- DOM基础
- java 集合
- Gaussian mixture model. EM VS variational inference