• 虚拟桌面模拟查找点击自绘控件


    // VDesktopClick.cpp : 定义控制台应用程序的入口点。

    //
    
    #include "stdafx.h"
    #include <string>
    #include <Oleacc.h>
    using namespace std;
    
    #define SET_LIST 1
    #define SET_BUT 2
    
    #pragma comment(lib,"Oleacc.lib")
    
    wstring wsTitle = L"title";
    wstring wsAppPath = L"adasdasdasdasdasdasd.exe";
    DWORD dwX = 60;
    DWORD dwY = 20;
    
    /*
    目的:模拟点击自绘控件,同时不干扰电脑正常工作,也可以理解成不让使用者察觉到。
    
    测试功能:找到title是wsTitle的窗体,将位置移动到用户看不到的区域,然后以这个窗体为树根,遍历窗体上的所有其他小窗体,目标是找到一个自绘的
    byutton,尺寸是dwX,dwY。的自绘控件,然后模拟一次点击。
    
    如果界面程序不存在的话就开启一个虚拟桌面,然后在虚拟桌面上去启动这个界面程序,然后模拟。假设界面程序的路径是wsAppPath。
    */
    
    
    void GetObjectName(IAccessible* child,VARIANT* varChild,wchar_t* 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;
    
    	wcscpy_s(objName,MAX_PATH,tmp);
    }
    void GetObjectRole(IAccessible* child,VARIANT* varChild,wchar_t* 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;
    	wcscpy_s(objRole,MAX_PATH,tmp);
    	free(lpszRoleString);
    	return /*S_OK*/;
    
    }
    
    void GetObjectClass(IAccessible* child,wchar_t* 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;
    	wcscpy_s(objClass,MAX_PATH,tmp);
    	free(strClass);
    }
    
    BOOL Find(IAccessible* paccParent,IAccessible** paccChild) {
    	HRESULT hr;
    	long numChildren;
    	unsigned long numFetched;
    	VARIANT varChild;
    	int indexCount;
    	IAccessible* pCAcc = NULL;
    	IEnumVARIANT* pEnum = NULL;
    	IDispatch* pDisp = NULL;
    	BOOL found = false;
    	wchar_t 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;
    		}
    
    		ZeroMemory(szObjName,(MAX_PATH<<1));
    		ZeroMemory(szObjRole,(MAX_PATH<<1));
    		ZeroMemory(szObjClass,(MAX_PATH<<1));
    		GetObjectName(*paccChild,&varChild,szObjName,sizeof(szObjName));
    		GetObjectRole(*paccChild,&varChild,szObjRole,sizeof(szObjRole));
    		GetObjectClass(*paccChild,szObjClass,sizeof(szObjClass));
    
    		LONG px = 0;
    		LONG py = 0;
    		LONG pcx = 0;
    		LONG pcy = 0;
    		(*paccChild)->accLocation(&px,&py,&pcx,&pcy,varChild);
    
    		if(_wcsicmp(L"Button",szObjClass) == 0){
    			if(pcx==dwX) {
    				if(pcy==dwY) {
    					//wchar_t ccl[1024] = {0};
    					//wsprintf(ccl,L"-----------%s %s %s   %d,%d,%d,%d",szObjName,szObjClass,szObjRole,px,py,pcx,pcy);
    					//OutputDebugStringW(ccl);
    					(*paccChild)->accDoDefaultAction(varChild); //模拟点击运行按钮
    					Sleep(1500);//模拟点击,等待按钮响应。
    				}
    			}
    		}
    
    		if(!found && pCAcc) {
    			// Go deeper
    			found = Find(pCAcc,paccChild);
    			if(*paccChild!=pCAcc){
    				pCAcc->Release();
    			}
    		}
    	}
    	// Clean up
    	if(pEnum){
    		pEnum->Release();
    	}
    	return found;
    }
    
    BOOL CALLBACK EnumWindowsProc(HWND hwnd,DWORD lParam){
    	wchar_t temp[200];
    	ZeroMemory(temp,400);
    	GetWindowTextW((HWND)hwnd,temp,200);
    	if(_wcsicmp(wsTitle.c_str(),temp) == 0){
    		OutputDebugStringW(temp);
    		if(lParam == SET_BUT){
    			HWND hwndOneClickBar = (HWND)hwnd;
    			IAccessible* accT = NULL;
    			IAccessible* aaaaaaccT = NULL;
    			HRESULT hr = AccessibleObjectFromWindow(hwndOneClickBar,OBJID_WINDOW,IID_IAccessible,(LPVOID*)&accT);
    			if(FAILED(hr)) {
    				return TRUE;
    			}
    			Find(accT,&aaaaaaccT);
    		}
    	}
    	return TRUE;
    }
    
    void GoClick() {
    //方案1:直接就能找到界面的情况,界面开着呢
    	HWND hw = ::FindWindow(NULL,wsTitle.c_str());
    	if(hw!=NULL) {
    		::SetWindowPos(hw,0,-100,-100,100,100,SWP_NOZORDER);
    		::SetWindowLong(hw,GWL_HWNDPARENT,WS_EX_TOOLWINDOW);
    
    		EnumDesktopWindows(0,(WNDENUMPROC)EnumWindowsProc,SET_BUT);
    		CloseHandle(hw);
    		return;
    	}
    
    //方案2:需要自己开启虚拟桌面,然后再启动界面程序,达到隐藏的目的
    #define MAX_B_SIZE 1024
    	wchar_t strS[MAX_B_SIZE] = {0};
    	ZeroMemory(strS,(MAX_B_SIZE<<1));
    	wcscpy_s(strS,MAX_B_SIZE,wsAppPath.c_str());
    	HDESK hDesk = CreateDesktop(L"desktop__vvvv",NULL,NULL,NULL,GENERIC_ALL,NULL);
    	HDESK hDst = GetThreadDesktop(GetCurrentThreadId());
    	SetThreadDesktop(hDesk);
    
    	STARTUPINFO si = {0};
    	si.cb = sizeof(si);
    	si.lpDesktop = L"desktop__vvvv";
    	si.dwFlags = STARTF_USESHOWWINDOW;
    	si.wShowWindow = SW_SHOW;
    	PROCESS_INFORMATION pi = {0};
    	if(CreateProcess(NULL,strS,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) {
    		Sleep(5000);
    		EnumDesktopWindows(hDesk,(WNDENUMPROC)EnumWindowsProc,SET_BUT);
    		Sleep(10000);
    	}
    	CloseDesktop(hDesk);
    	SetThreadDesktop(hDst);
    	return;
    }
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	GoClick();
    	return 0;
    }
    
    


  • 相关阅读:
    CF343D Water Tree
    CF340B Maximal Area Quadrilateral
    测试环境/生产环境,接口地址配置
    json-server MOCK方案
    vscode prettier保存代码时自动格式化
    蓝鲸6.0前置准备
    nginx日志提取案列
    蓝鲸模拟考试
    部署维护
    第一次模拟考
  • 原文地址:https://www.cnblogs.com/csnd/p/12062211.html
Copyright © 2020-2023  润新知