IAccessiable的学习和使用
2016-04-07 22:24
197 查看
前几天听群里大神讨论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文件
添加完成,再次编译,果然错误少了很多。
查阅代码发现有如下函数调用
这三个函数在给定的Demo代码中并没有给出实现。仔细分析代码流程会发现,这三个函数功能其实很简单,就是获取给定子空间的Name, Role 和Class。没有枪没有炮,我们自己造。先造第一个GetObjectName函数原型很容易推断出,返回值我们不妨先不设,因为程序中也没有用到。以下函数原型:
那么如何实现这个功能呢。翻阅MSDN我们发现IAccessable接口有这么个函数
参数返回一个BSTR类型的Name,而我们需要一个char*类型。如何搞?用下微软的_bstr_t转换下。上代码:
调试下,果然成功获取到Name值。
接下来的Class和Role过程大致类似,直接上代码:
其中涉及到一个问题,VS的默认编码是Unicode而我们需要一个char*这个绝对需要转换一下。如何转换呢?百一下得到了一个如下答案:
还需要注意我们用到了_bstr_t和CComBSTR所以需要包含头文件和库文件查阅MSDN需要comsuppw.lib和头文件
至此应该能编译通过了,但是回到宿舍,运行在中文环境的VS2015下并不能得到预期的结果。Debug之。发现,GetObjectName中的下列代码
返回值为-1,这个不科学啊,百度之。得到一个答案。没看明白,但是修改之后确实可以获取成功了。修改之后的代码:
当然需要先加上头文件:
大功告成,运行结果果然如预期一样。
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>
大功告成,运行结果果然如预期一样。
相关文章推荐
- C++ COM编程之QueryInterface函数(二)
- PowerShell入门教程之访问.Net程序集、COM和WMI实例
- C++ COM编程之接口背后的虚函数表
- win2003服务器使用WPS的COM组件的一些问题解决方法
- Uncaught exception com_exception with message Failed to create COM object
- 用JavaScript编写COM组件的步骤
- Python编写的com组件发生R6034错误的原因与解决办法
- 事件查看器 特定权限设置未将 COM 服务器应用程序错误的解决方法
- Windows平台的 PHP 报错 Fatal error: Class COM not found in 的解决方法
- C++ COM编程之QueryInterface函数(一)
- C++中COM组件初始化方法实例分析
- C++ COM编程之什么是组件?
- win2003禁止web等目录执行exe,bat,com的方法
- 汇编基础:COM文件格式
- CLR无法从COM 上下文0x645e18 转换为COM上下文0x645f88...
- 图形系统的特点
- 什么是Visual Graph图形系统
- 图形系统的广泛应用
- 在Visual Graph图形系统中制作按钮
- windowxp无法通过RPC Over HTTP访问证书错误问题