Другое С/С++ Вопрос - Ответ

Digger Man52

52NGG
Проверенный
1,122
987
можно просто в центр кликать, если окно не известно
C++:
HWND hwnd = GetForegroundWindow(); // дескриптор окна
// далее получаем размеры окна
RECT rect;
GetClientRect(hwnd, &rect);
int centerX = (rect.right - rect.left) / 2; // Х центра
int centerY = (rect.bottom - rect.top) / 2; // Y центра
// нажимаем
SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(centerX, centerY));
SendMessage(hwnd, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(centerX, centerY));
 
  • Нравится
Реакции: Z3roKwq и Sadow

x0r1x

Потрачен
112
97
Как можно такое реализовать в Rage MP? Я пишу вместо gta sa GTAV (название основного приложения с гташкой) и не работает
ну в общем написал вот такой код:
C++:
#include "mHook.hpp"

LRESULT CALLBACK HookMouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (wParam == WM_LBUTTONUP) {
        std::cout << "click" << std::endl;
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

DWORD GetProcessIdByName(const char* process_name) {
    PROCESSENTRY32 processEntry;
    processEntry.dwSize = sizeof(PROCESSENTRY32);
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snapshot == INVALID_HANDLE_VALUE) {
        std::cerr << "failed to create process snapshot" << std::endl;
        return 0;
    }
    if (!Process32First(snapshot, &processEntry)) {
        std::cerr << "failed to get the first process" << std::endl;
        CloseHandle(snapshot);
        return 0;
    }
    DWORD processId = 0;
    while (Process32Next(snapshot, &processEntry)) {
        if (strcmp(processEntry.szExeFile, process_name) == 0) {
            processId = processEntry.th32ProcessID;
            break;
        }
    }
    CloseHandle(snapshot);
    return processId;
}
C++:
#pragma once

#include "main.hpp"

LRESULT CALLBACK HookMouseProc(int nCode, WPARAM wParam, LPARAM lParam);
DWORD GetProcessIdByName(const char* process_name);
C++:
#include "main.hpp"

int main() {
    HHOOK hook_mouse = SetWindowsHookExA(WH_MOUSE_LL, HookMouseProc, NULL, NULL);
    if (hook_mouse == NULL) {
        return 1;
    }
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    UnhookWindowsHookEx(hook_mouse);
    return 0;
}
C++:
#pragma once

#include <iostream>
#include <windows.h>
#include <tlhelp32.h>

#include "mHook.hpp"
данный код устанавливает хук функции hookmouseproc, которая обрабатывает нажатие левой кнопки мыши. но одна проблема, @kin4stat написал что rage mp создаёт окно с разными названиями, то есть hwnd уже и не получишь, но в моём способе он и не нужен, нужен process id, который я получаю с помощью функции getprocessidbyname, то есть мне в эту функцию нужно передать параметр с именем процесса, и на возврате он выдаст мне его pid. pid я должен указать в функцию установки хука, в качестве последнего параметра, то есть:
C++:
SetWindowsHookExA(WH_MOUSE_LL, HookMouseProc, NULL, 0);
там где стоит 0 в конце, нужно указать dwThreadId в качестве параметра, но проблема в том, что когда я указываю pid процесса, у меня срабатывает вот это условие:
C++:
if (hook_mouse == NULL) {
    return 1;
}
и в итоге всё идёт по пизде, короче я не знаю как это исправить, поэтому пока что могу предложить просто юзать в качестве последнего параметра функции setwindowshookexa - 0, то есть хук будет работать сразу для всех приложений, а не определённо для твоего процесса, это конечно плохо, но это намного лучше твоих бесконечных циклов.

p.s. при запуске этого исходника, будет обрабатываться левая кнопка мыши, и выводится в консоль сообщение "click", чтобы эмулировать нажатие клавиши, тебе нужно вместо этого:
C++:
std::cout << "click" << std::endl;
написать код который будет эмулировать нажатие левой клавиши мыши, с помощью функции sendmessagea, но тут проблемка, нужен всё равно hwnd, чтобы тебе его получить, тебе надо в твоём случае, с помощью process id получать заголовок окна по его pid'у, и только потом создавать переменную hwnd, где будет лежать этот заголовок.

ну в общем разбирайся, я тебе начальный код написал, тебе осталось написать функцию по определению заголовка окна по его pid'у. и да, функцию которую придётся тебе использовать в получении pid'а, я уже тебе написал:
C++:
DWORD GetProcessIdByName(const char* process_name);

p.s. забыл упомянуть что если ты собираешься использовать этот код, у тебя должны быть вот такие настройки проекта:
1684267330095.png

1684267349255.png

1684267371090.png
 
Последнее редактирование:
  • Нравится
Реакции: Sadow

writeline

Новичок
21
8
Возникла необходимость смены Window Text после инициализации.
Сделал вот так, не работает, кто подскажет в чём может быть проблема? И где моя ошибка

с++:
#include "pch.h"
#include <windows.h>
#include <stdio.h>

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        HWND hwnd = FindWindow(NULL, L"GTA:SA:MP");
        if (hwnd == NULL)
            return FALSE;
        SetWindowText(hwnd, L"GTA:NewText");

        //debug
        MessageBox(NULL, L"ASI initialization successful!", L"Success", MB_OK);
        FILE* f;
        fopen_s(&f, "SetWindowText.log", "a");
        fprintf(f, "Success\n");
        fclose(f);
    }
    return TRUE;
}
 
Последнее редактирование:

x0r1x

Потрачен
112
97
Возникла необходимость смены Window Text после инициализации.
Сделал вот так, не работает, кто подскажет в чём может быть проблема? И где моя ошибка

с++:
#include "pch.h"
#include <windows.h>
#include <stdio.h>

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        HWND hwnd = FindWindow(NULL, L"GTA:SA:MP");
        if (hwnd == NULL)
            return FALSE;
        SetWindowText(hwnd, L"GTA:NewText");

        //debug
        MessageBox(NULL, L"ASI initialization successful!", L"Success", MB_OK);
        FILE* f;
        fopen_s(&f, "SetWindowText.log", "a");
        fprintf(f, "Success\n");
        fclose(f);
    }
    return TRUE;
}
в dll_process_attach в твоём случае чтобы исполнить код который ты хочешь нужно ставить инициализацию функции где будет лежать код который тебе надо, и инициализироваться он должен обязательно через:
C++:
std::thread(name_func).detach();
вот тебе пример:
C++:
#include <windows.h>
#include <stdio.h>
#include <thread>
#include <iostream>

bool func() {
    HWND hwnd = FindWindowA(nullptr, "GTA:SA:MP");
    if (hwnd == NULL) {
        MessageBoxA(nullptr, "ПИЗДЕЦ НАХУЙ", "ПИЗДЕЦ", MB_OK);
        return true;
    }
    SetWindowTextA(hwnd, "GTA:NewText");
    MessageBoxA(nullptr, "ASI initialization successful!", "Success", MB_OK);
    FILE* f;
    fopen_s(&f, "SetWindowText.log", "a");
    fprintf(f, "Success\n");
    fclose(f);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        std::thread(func).detach();
    }
    return TRUE;
}
 
Последнее редактирование:
  • Нравится
Реакции: writeline

ARMOR

Модератор по раксампу
Модератор
4,936
6,732
Возникла необходимость смены Window Text после инициализации.
Сделал вот так, не работает, кто подскажет в чём может быть проблема? И где моя ошибка

с++:
#include "pch.h"
#include <windows.h>
#include <stdio.h>

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        HWND hwnd = FindWindow(NULL, L"GTA:SA:MP");
        if (hwnd == NULL)
            return FALSE;
        SetWindowText(hwnd, L"GTA:NewText");

        //debug
        MessageBox(NULL, L"ASI initialization successful!", L"Success", MB_OK);
        FILE* f;
        fopen_s(&f, "SetWindowText.log", "a");
        fprintf(f, "Success\n");
        fclose(f);
    }
    return TRUE;
}
До инициализации игры у окна другое название, поэтому плагин и не может найти GTA:SA:MP. Дожидайся загрузки игры например хуком CTimer::Update и уже тогда делай поиск по названию окна.
 

kin4stat

mq-team · kin4@naebalovo.team
Всефорумный модератор
2,744
4,806
в dll_process_attach в твоём случае чтобы исполнить код который ты хочешь нужно ставить инициализацию функции где будет лежать код который тебе надо, и инициализироваться он должен обязательно через:
C++:
std::thread(name_func).detach();
вот тебе пример:
C++:
#include <windows.h>
#include <stdio.h>
#include <thread>
#include <iostream>

bool func() {
    HWND hwnd = FindWindowA(nullptr, "GTA:SA:MP");
    if (hwnd == NULL) {
        MessageBoxA(nullptr, "ПИЗДЕЦ НАХУЙ", "ПИЗДЕЦ", MB_OK);
        return true;
    }
    SetWindowTextA(hwnd, "GTA:NewText");
    MessageBoxA(nullptr, "ASI initialization successful!", "Success", MB_OK);
    FILE* f;
    fopen_s(&f, "SetWindowText.log", "a");
    fprintf(f, "Success\n");
    fclose(f);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    if (fdwReason == DLL_PROCESS_ATTACH)
    {
        std::thread(func).detach();
    }
    return TRUE;
}
и получить гонку потоков, не найденное окно, потому что там будет Grand Theft Auto: San Andreas, а не GTA:SAMP
 
  • Нравится
Реакции: ARMOR и Savok

kin4stat

mq-team · kin4@naebalovo.team
Всефорумный модератор
2,744
4,806
До инициализации игры у окна другое название, поэтому плагин и не может найти GTA:SA:MP. Дожидайся загрузки игры например хуком CTimer::Update и уже тогда делай поиск по названию окна.
А можно просто HWND окна из памяти игры дернуть...
 
  • Нравится
Реакции: ARMOR

Sadow

Известный
1,428
592
Как прямо в таблице изменить местоположение какому-то элементу? Тоесть. К примеру есть массив:
C++:
const char table[] = {'n', 'e', 'g', 'r'}
И внутри массива мне надо присвоить первому элементу местоположение 5.
 

ARMOR

Модератор по раксампу
Модератор
4,936
6,732
Как прямо в таблице изменить местоположение какому-то элементу? Тоесть. К примеру есть массив:
C++:
const char table[] = {'n', 'e', 'g', 'r'}
И внутри массива мне надо присвоить первому элементу местоположение 5.
Ты не установишь его на 5ку потому что у тебя будет всего 0, 1, 2, 3. Нужно будет как минимум пересоздавать массив.