WinAPI Получить доступ к элементам управления другого приложения - PullRequest
2 голосов
/ 08 марта 2011

Мне нужно получить список всех элементов управления из win calculator (calc.exe) и нажать кнопки на calc из моего приложения. Я попробовал внедрение кода и теперь смог выполнить мой код из приложения calc. В примере он отправляет сообщение msg:

#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?

как я пытался перечислить дочерние окна:

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);

Ответы [ 2 ]

1 голос
/ 15 марта 2011

Ознакомьтесь с API-интерфейсами MSAA и UIAutomation в MSDN - они предназначены для того, чтобы одно приложение могло получать информацию об элементах управления в другом, и часто используются инструментами и приложениями для автоматического тестирования и специальных возможностей.

Inspect.exeинструмент, который является частью Windows SDK, использует их;и вы должны иметь возможность использовать его для изучения и взаимодействия с кнопками в calc или различных других приложениях.

Все системные элементы управления в Windows поддерживают эти API, как и многие другие приложения (например, IE, Firefox);но, вероятно, он не будет работать в некоторых сторонних приложениях, которые просто рисуют свой собственный пользовательский интерфейс.

1 голос
/ 08 марта 2011

Я полагаю, вы уже получили необходимые кнопки

Если это так, попробуйте это - SendMessage (hButton, BN_CLICKED, 0, 0) Я не помню константы, вам, вероятно, придется искать их.

Обновление для получения дескрипторов окна кнопки - 1. Перечислите дочерние окна калькулятора, используя EnumChildWindows () http://msdn.microsoft.com/en-us/library/ms633494(VS.85).aspx

  1. Для каждого такого окна найдите кнопку, проверив текст на нем с помощью GetWindowText http://msdn.microsoft.com/en-us/library/ms633520(VS.85).aspx

  2. Создайте массив из всех кнопок и нажмите на них, как вам нравится:)

...