Если окно появляется всегда в одном и том же положении, то можно просто тыкать мышкой в нужных координатах. Как-то так:
#include "windows.h"
void set_event(int a_x, int a_y, int a_btn)
{
// Перемещаем мышку в абсолютных координатах
DWORD flags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
// Устанавливаем флаги для нажатия/отпускания кнопки мыши
switch (a_btn) {
case 1: {
flags |= MOUSEEVENTF_LEFTDOWN;
break;
}
case 2: {
flags |= MOUSEEVENTF_LEFTUP;
break;
}
}
// Получаем размер рабочего стола, чтобы получить нормализованные координаты
RECT full_rect;
GetWindowRect(GetDesktopWindow(), &full_rect);
// Нормализуем координаты
LONG x = (LONG)(a_x*(65535.0f/(full_rect.right - full_rect.left - 1)));
LONG y = (LONG)(a_y*(65535.0f/(full_rect.bottom - full_rect.top - 1)));
INPUT input;
memset(&input, 0, sizeof(INPUT));
input.type = INPUT_MOUSE;
input.mi.dwFlags = flags;
input.mi.dx = x;
input.mi.dy = y;
// Посылаем событие мыши
SendInput(1, &input, sizeof(INPUT));
}
int _tmain(int argc, _TCHAR* argv[])
{
// Координаты, по которым тыкаем
int x = 1160;
int y = 640;
// Сначала перемещаем мышку
set_event(x, y, 0);
// Потом нажимаем левую кнопку
set_event(x, y, 1);
// И, наконец, отпускаем
set_event(x, y, 2);
return 0;
}
У меня этот вариант работает.
Если нужен более стабильный подход, то можно использовать EnumWindows, так как FindWindow вроде как не будет работать с окнами другого процесса. Используется он просто:
BOOL CALLBACK enum_wnd_proc(HWND hwnd, LPARAM lParam)
// hwnd - окно, которое надо проверить
// lParam пользовательский параметр, передаваемый в функцию. Я через него свойства искомого окна передаю
{
WindowInfo* window_info = (WindowInfo*)lParam;
// Тут идут проверки нужных свойств, если они не проходят, надо вернуть TRUE
// Если все проверки прошли, сохраняем текущий хэндл окна в передаваемой структуре и возвращаем FALSE
window_info->m_hwnd = hwnd;
return FALSE;
}
// Это для окон верхнего уровня
if (EnumWindows(enum_wnd_proc, (LPARAM)(&window_info)) == TRUE) {
// Окно найдено
// window_info->m_hwnd; <-- это родительское окно
// Дальше ищем дочернее окно аналогично, но с помощью
WindowInfo window_info_2;
EnumChildWindows(window_info->m_hwnd, enum_wnd_proc, (LPARAM)(&window_info_2));
// window_info_2.m_hwnd <-- это дочернее окно
}
Что можно проверять?
Для окна верхнего уровня - название процесса (GetWindowThreadProcessId, OpenProcess, EnumProcessModules, GetModuleBaseName).
Для всех окон - заголовок (GetWindowText), класс (GetClassName), конкретные значения можно найти в Spy++. Для вашей задачи должно быть достаточно.
Нажимать кнопку уже можно либо как выше написал, либо:
l_param = x | (y << 16);
::PostMessage(hwnd, WM_MOUSEMOVE, 0, l_param);
::PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, l_param);
::PostMessage(hwnd, WM_LBUTTONUP, 0, l_param);