在好例子网,分享、交流、成长!
您当前所在位置:首页C/C++ 开发实例Windows系统编程 → WinACC测试

WinACC测试

Windows系统编程

下载此实例
  • 开发语言:C/C++
  • 实例大小:5.13KB
  • 下载次数:6
  • 浏览次数:85
  • 发布时间:2021-04-16
  • 实例类别:Windows系统编程
  • 发 布 人:jha334201553@
  • 文件格式:.zip
  • 所需积分:2
 相关标签: 测试

实例介绍

【实例简介】

【实例截图】

from clipboard

【核心代码】

#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;
}

标签: 测试

实例下载地址

WinACC测试

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警