实例介绍
【实例截图】
【核心代码】
#include <stdio.h> #include <Windows.h> #include <tchar.h> #include <oleacc.h> #include <atlcomcli.h> #pragma comment(lib, "Oleacc.lib") BOOL Init(HWND hWnd, CComQIPtr<IAccessible, &IID_IAccessible>& ppAcc) { HRESULT hr = AccessibleObjectFromWindow(hWnd, OBJID_WINDOW, IID_IAccessible, (void**)&ppAcc); if (hr != S_OK) return FALSE; return TRUE; } 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) { // 根据返回的状态值生成以逗号连接的字符串。 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(strlen(lpszState)); } 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; //wchar_t* tmp = str; wchar_t* tmp = strTmp; WideCharToMultiByte(CP_ACP, 0, tmp, -1, objName, len, NULL, NULL); } 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); } wchar_t* tmp = lpszRoleString; WideCharToMultiByte(CP_ACP, 0, tmp, -1, objRole, len, NULL, NULL); free(lpszRoleString); 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; } wchar_t* tmp = strClass; WideCharToMultiByte(CP_ACP, 0, tmp, -1, objClass, len, NULL, NULL); free(strClass); } 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 { //如果一个父亲不支持IEnumVARIANT接口,子ID就是它的序号 varChild.vt = VT_I4; varChild.lVal = index; } // 找到此子ID对应的 IDispatch 接口 if (varChild.vt == VT_I4) { //通过子ID序号得到对应的 IDispatch 接口 pDisp = NULL; hr = paccParent -> get_accChild(varChild, &pDisp); } else //如果父支持IEnumVARIANT接口可以直接得到子IDispatch 接口 pDisp = varChild.pdispVal; // 通过 IDispatch 接口得到子的 IAccessible 接口 pCAcc if (pDisp) { hr = pDisp->QueryInterface(IID_IAccessible, (void**)&pCAcc); hr = pDisp->Release(); } // Get information about the child if(pCAcc) { //如果子支持IAccessible 接口,那么子ID就是CHILDID_SELF VariantInit(&varChild); varChild.vt = VT_I4; varChild.lVal = CHILDID_SELF; *paccChild = pCAcc; } else //如果子不支持IAccessible 接口 *paccChild = paccParent; //跳过了有不可访问状态的元素 GetObjectState(*paccChild, &varChild, szObjState, sizeof(szObjState)); if(NULL != strstr(szObjState, "unavailable")) { if(pCAcc) pCAcc->Release(); continue; } //通过get_accName得到Name GetObjectName(*paccChild, &varChild, szObjName, sizeof(szObjName)); //通过get_accRole得到Role GetObjectRole(*paccChild, &varChild, szObjRole, sizeof(szObjRole)); //通过WindowFromAccessibleObject和GetClassName得到Class GetObjectClass(*paccChild, szObjClass, sizeof(szObjClass)); //以上实现代码比较简单,大家自己看代码吧。 //如果这些参数与输入相符或输入为NULL if ((!szName || !strcmp(szName, szObjName)) && (!szRole || !strcmp(szRole, szObjRole)) && (!szClass || !strcmp(szClass, szObjClass))) { found = true; *pvarChild = varChild; break; } if(!found && pCAcc) { // 以这次得到的子接口为父递归调用 found = FindChild(pCAcc, szName, szRole, szClass, paccChild, pvarChild); if(*paccChild != pCAcc) pCAcc->Release(); } }//End for // Clean up if(pEnum) pEnum -> Release(); return found; } void EnumWechat() { // 获取微信窗口 HWND hWnd = FindWindow(TEXT("WeChatMainWndForPC"), TEXT("微信")); // 转成ACC接口 CComQIPtr<IAccessible,&IID_IAccessible> m_pAcc; if( !Init(hWnd, m_pAcc) ) { printf("打开失败!\n"); return ; } // 获取控件 VARIANT varControl; IAccessible* paccControl = NULL; if( FindChild(m_pAcc, "聊天", "按下按钮", NULL, &paccControl, &varControl) ) { printf("找到控件!\n"); // 操作控件 HRESULT hr = paccControl->accDoDefaultAction(varControl); // 发送事件 long pxLeft = 0; long pyTop = 0; long pcxWidth = 0; long pcyHeight = 0; if (S_OK == paccControl->accLocation(&pxLeft, &pyTop, &pcxWidth, &pcyHeight, varControl)) // 获取到坐标 是全局坐标 { printf("%u\n", pxLeft); HDC hdc = GetDC(GetDesktopWindow()); // 在控件上画个矩形 HPEN hPen = CreatePen(PS_SOLID,0,RGB(255,0,0)); HBRUSH hBrush = CreateSolidBrush(RGB(255,0,0)); SelectObject(hdc, hPen); SelectObject(hdc, hBrush); Ellipse(hdc, pxLeft, pyTop, pxLeft pcxWidth, pyTop pcyHeight); ReleaseDC(GetDesktopWindow(), hdc); // 点击聊天 RECT rect = {0}; GetWindowRect(hWnd, &rect); int xpoint, ypoint; xpoint = pxLeft-rect.left pcxWidth/2; ypoint = pyTop-rect.top pcyHeight/2; printf("坐标(%u, %u)\n", xpoint, ypoint); SendMessage(hWnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(xpoint, ypoint)); SendMessage(hWnd, WM_LBUTTONUP, 0, MAKELONG(xpoint, ypoint)); Sleep(800); // 切换到联系人 ypoint = pcyHeight; SendMessage(hWnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(xpoint, ypoint)); SendMessage(hWnd, WM_LBUTTONUP, 0, MAKELONG(xpoint, ypoint)); } paccControl->Release(); VariantClear(&varControl); } } INT _tmain(INT argc, TCHAR **argv) { CoInitializeEx(NULL, COINIT_MULTITHREADED); EnumWechat(); CoUninitialize(); return 0; }
标签: 测试
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论