WinAPI 访问另一个应用程序的控件 [英] WinAPI Get access to another application's controls

查看:26
本文介绍了WinAPI 访问另一个应用程序的控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从 win 计算器 (calc.exe) 获取所有控件的列表,然后从我的应用程序中按下 calc 上的按钮.我尝试了代码注入,现在可以从 calc 应用程序执行我的代码.在示例中,它发送消息框:

I need to get list of all controls from win calculator (calc.exe) and press buttons on calc from my application. I tried code injection and now could execute my code from calc application. In the example it sends msg box:

#define PROC_NAME _T("calc.exe")
#define MAX_READ 128
#include <windows.h>
#include <tlhelp32.h>

#pragma comment(linker,"/BASE:0x13140000") 

//-------- My code, which will be executed  from the app-------

DWORD WINAPI func(LPVOID)
{
    LoadLibrary(_T("kernel32.dll")); 
    LoadLibrary(_T("user32.dll"));
    MessageBox(0,_T("Hello from addres area of calculator"),_T("title"),0);
    return true;
}

//-------- find process ---------

DWORD GetProcessID(LPCWSTR lpNameProcess) 
{
    HANDLE snap;
    PROCESSENTRY32 pentry32;
    snap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if(snap==INVALID_HANDLE_VALUE) return 0;
    pentry32.dwSize=sizeof(PROCESSENTRY32);
    if(!Process32First(snap,&pentry32)) {CloseHandle(snap);return 0;}
    do
    {
        if(!lstrcmpi(lpNameProcess,&pentry32.szExeFile[0]))
        {
            CloseHandle(snap);
            return pentry32.th32ProcessID;
        }
    }
    while(Process32Next(snap,&pentry32));
    CloseHandle(snap);
    return 0;
}

//-------- injection to another process -------------------

BOOL Inject(HANDLE hProc,DWORD(WINAPI* func)(LPVOID))
{
    DWORD id;
    DWORD ByteOfWriten;
    HMODULE hModule = GetModuleHandle(NULL);
    DWORD size=((PIMAGE_OPTIONAL_HEADER)((LPVOID)((BYTE*)(hModule)+((PIMAGE_DOS_HEADER)(hModule))->e_lfanew+sizeof(DWORD)+sizeof(IMAGE_FILE_HEADER))))->SizeOfImage;
    char* hNewModule = (char*)VirtualAllocEx(hProc,hModule,size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
    if(hNewModule==NULL) return false;
    WriteProcessMemory(hProc,hNewModule,hModule,size,&ByteOfWriten);
    if(ByteOfWriten!=size){return false;}
    HANDLE hThread=CreateRemoteThread(hProc,NULL,0,func,(LPVOID)hNewModule,0,&id);
    if(hThread==0) return false;
    return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
    if(!Inject(OpenProcess(PROCESS_ALL_ACCESS,false,GetProcessID(PROC_NAME)),&func)) return false;
}

但是如何让按钮点击并从 calc 上的某些控件中获取文本?

我如何尝试枚举子窗口:

But how can I make buttons clicks and get text from some controls on calc?

how i tried to enumerate child windows :

HWND hwnd, child;
    child = NULL;
    char buf[MAX_STR];          
    hwnd = getMyWnd();  // my own func, returns hwnd to main window 
    do 
    {
        //  here i tried to get child windows
        child = FindWindowExA(hwnd, child, NULL, NULL);
        GetWindowTextA( child, buf, MAX_STR - 1 );
        printf(buf); printf("\n");      
    } while (child != NULL);

推荐答案

查看 MSDN 上的 MSAA 和 UIAutomation API - 它们旨在让一个应用程序获取有关另一个应用程序中控件的信息,并且经常用于自动化测试和辅助功能工具和应用.

Check out MSAA and UIAutomation APIs on MSDN - they are designed to let one application get information about the controls in another, and are often used by automated testing and accessibility tools and apps.

作为 Windows SDK 一部分的 inspect.exe 工具使用这些;并且您应该能够使用它来检查 calc 或其他各种应用中的按钮并与之交互.

The inspect.exe tool that's part of the Windows SDK uses these; and you should be able to use it to examine and interact with the buttons in calc or various other apps.

Windows 中的所有系统控件都支持这些 API,许多其他应用程序(例如 IE、Firefox)也是如此;但它可能不适用于某些仅绘制自己的 UI 的 3rd 方应用.

All the system controls in Windows support these APIs, as do many other apps (eg. IE, Firefox); but it likely won't work in some 3rd party apps that are just drawing their own UI.

这篇关于WinAPI 访问另一个应用程序的控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆