U
U
username2352013-12-06 14:02:16
C++ / C#
username235, 2013-12-06 14:02:16

How to find the required window using the EnumWindows function, then press the OK button in this window?

Microsoft Visual C++ application. How to use the EnumWindows function to find the required window, then click the "Yes" button in this window? A dialog box with the prompt "This computer is being used by other users. Shutting down Windows can result in data loss. Do you want to continue shutting down?" And yes and no buttons. Can you provide an example to explain the code. or a manual for the function in Russian, understandable to the noob.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
SHVV, 2013-12-09
@username235

If the window always appears in the same position, then you can simply poke the mouse in the desired coordinates. Something like this:

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

This option works for me.
If you need a more stable approach, then you can use EnumWindows, since FindWindow does not seem to work with windows from another process. It is used simply:
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 <-- это дочернее окно
}

What can be checked?
For a top-level window, the name of the process (GetWindowThreadProcessId, OpenProcess, EnumProcessModules, GetModuleBaseName).
For all windows - title (GetWindowText), class (GetClassName), specific values ​​can be found in Spy++. It should be enough for your task.
You can already press the button either as I wrote above, or:
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);

A
AlexP11223, 2013-12-06
@AlexP11223

And FindWindow (+ apparently FindWindowEx to search for buttons in the window) is not enough? By window title.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question