Ответы пользователя по тегу C++
  • Почему в char (C++) записывается лишняя информация?

    SHVV
    @SHVV
    В зыбыли место под терминальный ноль. Прибавьте по одному символу каждой строке.
    Ответ написан
    8 комментариев
  • WinApi как определить нужное окно для хука?

    SHVV
    @SHVV
    Если вы передаёте HWND окна, то процесс проверять нет смысла, так как идентификаторы окон уникальны для всей сессии.
    Ответ написан
    Комментировать
  • Как определить, принадлежит ли точка ромбу?

    SHVV
    @SHVV
    Собственно, если у вас дагонали dx, dy, и они параллельны осям, а центр - rx, ry, точка - x, y, то проверка сводится к следующей:
    |(x - rx) / dx| + |(y - ry) / dy| <= 2.
    Всё.
    Ответ написан
    Комментировать
  • Как справиться с неправильным нулем в C++?

    SHVV
    @SHVV
    Это нормально. Вы просто упёрлись в ограничение разрядной сетки чисел с плавающей запятой. В реальных приложениях нужно учится с этим жить.

    Например, для вывода пользователю, всегда округлять до некоторого знака в зависимости от величин, тогда числа, близкие к нулую, станут просто нулями.
    При сравнении чисел между собой необходимо задавать порог схожести опять же в зависимости от порядка чисел и их точности.
    Операции с матрицами, которые требуют соблюдения ортонормирования, дополнять принудительным ортонормированием.
    И т. д.
    Ответ написан
  • Разделение кода. Вынесение реализации методов шаблона класса из заголовочного файла ".h" в исходный файл ".cpp"?

    SHVV
    @SHVV
    У нас для реализации темплейтов введено специальное расшерение типа ".tpl", где и описывается реализация. Этот файл инклудится прямо в конце заголовочного файла, чтобы не делать двойных инклюдов в месте использования.
    Ответ написан
  • Как правильно наложить текстуру на каждую сторону модели?

    SHVV
    @SHVV
    Не работал с OSG, но судя по всему вы создаёте планарную проекцию текстуры на объект. Так что не удивительно, что они накладываются не очень хорошо.

    Не пробовали использовать текстурные координаты, загруженные из файла? Есть ли они там?
    Ответ написан
    Комментировать
  • Как сократить время выполнения программы [C++]?

    SHVV
    @SHVV
    Я бы сделал цикл не по i до n, а по c до с*с < n. Сам код будет сложнее, но, во-первых, цикл будет выполняться меньшее число раз, во-вторых, вы сэкономите медленную операцию возведения в произвольную степень.
    Ответ написан
  • Почему при динамическом копировании символов, остается лишняя память?

    SHVV
    @SHVV
    Жесть какая-то. Зачем вообще изобретать такой велосипед?
    - во-первых, первый result у вас не выделен на динамической памяти;
    - во-вторых, забываете выделить память под терминальный ноль;
    - в-третьих, память освобождаете только один раз, а выделяете на каждом символе;
    - в-четвёртых, операции выделения памяти желательно экономить (идеально - выделять только один раз), так как они медленные и ведут к фрагментации.
    - strlen(string) в цикле - плохо, лучше сохранить в отдельную переменную.

    Рекомендую удалить всё и переписать заново.
    Ответ написан
  • Как можно в изображении опредилить 2-3 самых используемых цвета?

    SHVV
    @SHVV
    Первое, что приходит в голову - алгоритм кластеризации K-means. На сколько я знаю, он часто используется для построения палитр при конвертации изображения в индексные цвета. То есть, даже если на изображении нет 2 чётких доминирующих цветов, но есть близкие оттенки (небольшие градиенты, затенения или осветления), то он найдёт их средние значения.
    Ответ написан
    Комментировать
  • Как быстро найти группу объектов в массиве, попадающих в выбранную зону по координатам Лево-Верх-Право-Низ?

    SHVV
    @SHVV
    Я для оптимизации поиска обычно сеточку использую. Просто и эффективно.

    То есть, строите двумерный массив, в каждом элементе которого список всех объектов, попавших в эту ячейку.
    При перемещении объекта необходимо обновлять и его положение в сетке.
    Соответственно, для поиска достаточно проверить все ячейки, в которые попадает объект, собрать список потенциальных кандидатов на пересечение и проверить каждого из них.

    Если пространство сильно не онородное (то есть есть много разбитых далеко кучек объектов), то регулярная сетка становится сильно не эффективной с точки зрения потребления памяти, тогда лучше строить дерево сортировки (k-d, Quad, Binary).
    Ответ написан
    1 комментарий
  • Как тестировать приватные методы у классов со сложным поведением?

    SHVV
    @SHVV
    Мы по этому поводу не паримся - тестовые классы у нас просто в друзьях у тестируемого. Так что для них все внутренности доступны.
    Ответ написан
    3 комментария
  • Как проверить скорость выполнения кода на C++?

    SHVV
    @SHVV
    В институте использовали ассемблерную команду "rdtsc", она возвращает количество тактов с момента включения комьютера. Под win достаточно использовать QueryPerformanceCounter, как уже посоветовали, она внутри тоже испульзует "rdtsc".
    Ответ написан
    Комментировать
  • Как эмулировать нажатие мышью по координатам?

    SHVV
    @SHVV
    Если пользоваться WinAPI, то для этого есть mouse_event, или более новая SendInput.
    Ответ написан
    2 комментария
  • Как используя функцию EnumWindows найти требуемое окно, после нажать в этом окне кнопку "ОК"?

    SHVV
    @SHVV
    Если окно появляется всегда в одном и том же положении, то можно просто тыкать мышкой в нужных координатах. Как-то так:
    #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);
    Ответ написан
    2 комментария