Home > Net >  This piece of code always does something unexpected
This piece of code always does something unexpected

Time:01-07

I wanted to use a marksman Rifle as a rifle when I was playing PUBG, so I wrote a mouse clicker, which works very well in most cases, but in some cases, when I let go of the mouse, he still keeps shooting continuously. I suspect that it is because I release the left mouse button after the code judges that the mouse is pressed, but the code has not yet executed the simulated click, which will cause the operating system to receive a hardware mouse release message, but the software sends another mouse left button The message that the button is pressed causes the left mouse button to still be pressed.

I tried to use threads or mutexes to make sure that the next event will be executed after the execution is completed, but it has no effect.So I suspect that it is caused by the delay of cpu execution.How to solve this problem

The following is the part of the timer loop judgment in the code.

static void click() {

        if (KEY_DOWN(VK_LBUTTON)) {
            POINT point;
            GetCursorPos(&point);
            if (KEY_DOWN(VK_LBUTTON)) {
                mouse_event(MOUSEEVENTF_LEFTDOWN, point.x, point.y, 0, 0);
            }
        };
    }

All the codes are below.


#include <windows.h>
#include<vector>
#include<string>
#include<uxtheme.h>
#pragma comment(lib,"UxTheme.lib")
using namespace std;
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#pragma region Help
#define WM_MONITOR 0x8075u
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0) 
INT toint(std::wstring  str) {
    INT nRet = 0;
    if (!str.empty())
    {
        nRet = _wtoi(str.c_str());
    }
    else
        nRet = 0;
    return nRet;
}
std::wstring GetText(HWND m_hWnd)
{
    if (!m_hWnd)
    {
        return std::wstring();
    }
    int length = GetWindowTextLengthW(m_hWnd);
    std::vector<wchar_t> buffer(length   1);
    GetWindowTextW(m_hWnd, buffer.data(), buffer.size());
    return std::wstring(buffer.data());
}

#pragma endregion

#pragma region Helpclass
class Clock
{
public:
    //-回调函数 返回值:无 (整数型 hWnd,整数型 msg,整数型 时钟ID,整数型 系统启动时间)
    //-void (HWND hWnd,UINT msg,UINT_PTR 时钟ID,UINT_PTR 系统启动时间)
    bool Create(HWND hWnd, UINT time, void* callback)
    {
        m_hWnd = hWnd;
        m_hClock = (UINT_PTR)this;
        m_Callback = callback;
        m_Time = time;
        if (time == 0)
        {
            return true;
        }
        m_hClock = SetTimer(hWnd, m_hClock, time, (TIMERPROC)m_Callback);;

        return m_hClock == 0;
    };
    bool Time(UINT time) {

        if (time != m_Time)
        {
            if (m_Time == 0) {
                m_hClock = SetTimer(m_hWnd, m_hClock, time, (TIMERPROC)m_Callback);
                if (m_hClock) {

                    m_Time = time;
                    return true;
                };
            }
            if (time == 0)
            {
                m_Time = time;
                return KillTimer(m_hWnd, m_hClock);
            }
            if (KillTimer(m_hWnd, m_hClock)) {
                m_hClock = SetTimer(m_hWnd, m_hClock, time, (TIMERPROC)m_Callback);
                if (m_hClock) {

                    m_Time = time;
                    return true;
                };
            };
        }
        return false;
    };
    UINT Time() {
        return m_Time;
    };
    bool Destory() {
        return KillTimer(m_hWnd, m_hClock);
    };
    Clock() {
        m_hWnd = 0;
        m_hClock = (UINT_PTR)this;
        m_Callback = 0;
        m_Time = 0;
    };
    ~Clock() {
        if (m_hClock)
        {
            KillTimer(m_hWnd, m_hClock);
            m_Callback = nullptr;
            m_hClock = 0;
            m_hWnd = 0;
            m_Time = 0;
        }

    };
private:
    UINT_PTR m_hClock;
    HWND m_hWnd;
    void* m_Callback;
    UINT m_Time;
};

class MyRegisterHotKey
{
public:
    int  Register(HWND hWnd, HWND labelhwnd, UINT fsModifiers, UINT vk)
    {
        // 将 fsModifiers 转换为 RegisterHotKey 函数所需的值
        label_hwnd = labelhwnd;
        switch (fsModifiers)
        {
        case 1: // Alt
            fsModifiers = MOD_ALT;
            break;
        case 2: // Ctrl
            fsModifiers = MOD_CONTROL;
            break;
        case 4: // Shift
            fsModifiers = MOD_SHIFT;
            break;
        case 3: // Alt   Ctrl
            fsModifiers = MOD_ALT | MOD_CONTROL;
            break;
        case 5: // Alt   Shift
            fsModifiers = MOD_ALT | MOD_SHIFT;
            break;
        case 6: // Ctrl   Shift
            fsModifiers = MOD_CONTROL | MOD_SHIFT;
            break;
        }

        // 如果窗口还没有设置窗口过程,就将窗口过程设置为 shellEx__RegWindowProc
        if (!old_proc)
            old_proc = (WNDPROC)SetWindowLongPtrA(hWnd, GWLP_WNDPROC, (LONG_PTR)RegWindowProc);//获取缺省回调,不太安全是否有方法修改

        SetWindowLongPtrA(hWnd, GWLP_USERDATA, (LONG_PTR)this);
        IDarry =   regcount   33000;//本次标识
        if (RegisterHotKey(hWnd, regcount   33000, fsModifiers, vk))
            return IDarry;
        else
            return 0;
    }

private:
    static LRESULT WINAPI RegWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        MyRegisterHotKey* r = (MyRegisterHotKey*)GetWindowLongPtrA(hWnd, GWLP_USERDATA);
        // 当接收到消息类型为 WM_HOTKEY 时,执行循环遍历
        if (uMsg == WM_HOTKEY)
        {

            for (int i = 33000; i <= r->IDarry; i  )//易里标识里从33000开始,不知道为什么怕冲突??
            {
                // 检查 传入参数 是否与 值 相等
                if (i == wParam)//ID值
                {
                    // 如果相等,则发送消息类型为 WM_COMMAND 的消息给 label_hwnd
                    SendMessageA(r->label_hwnd, WM_MONITOR, wParam, 0);
                }
            }
        }
        // 调用原来的窗口过程函数
        return CallWindowProcA(r->old_proc, hWnd, uMsg, wParam, lParam);
    }
    int regcount = 0;
    int IDarry = 0;
    HWND label_hwnd = 0;
    WNDPROC old_proc = 0;

};


#pragma endregion

static int F11 = 0;
static int F10 = 0;
static bool IsF10 = false;
static Clock Click;
static HWND hStatic;
static HWND hEditBox;
static WNDPROC StaticOldProc = NULL;












class ClickWindow
{
    static void StarContinuousClick() {
        if (!IsF10)
        {
            IsF10 = true;
            ::MessageBeep(MB_OK);
            int t = 0;
            if (!GetText(hEditBox).empty())
            {
                t = toint(GetText(hEditBox));
            }
            //开始连点就不允许编辑
            EnableWindow(hEditBox, FALSE);
            Click.Time(t);
        }
    };
    static void EndContinuousClick() {

        if (IsF10)
        {
            IsF10 = false;
            ::MessageBeep(0xFFFFFFFF);
            EnableWindow(hEditBox, TRUE);
            Click.Time(0);
        }

    };

    static LRESULT CALLBACK StaticWNDPROC(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
        if (StaticOldProc == NULL)
        {
            StaticOldProc = DefWindowProc;
        }
        PAINTSTRUCT ps;
        HDC hdcWnd;
        HDC hdcStatic;
        static HBRUSH hBrush; //画刷
        hBrush = CreateSolidBrush(RGB(0x41, 0x96, 0x4F));
        switch (Message) {
        case  WM_MONITOR:
            if (wParam == F10)
            {
                StarContinuousClick();
            }
            else if (wParam == F11)
            {
                EndContinuousClick();
            }
            break;
        default:
            break;
        }

        return StaticOldProc(hwnd, Message, wParam, lParam);
    }

    static void click() {

        if (KEY_DOWN(VK_LBUTTON)) {
            POINT point;
            GetCursorPos(&point);
            if (KEY_DOWN(VK_LBUTTON)) {
                mouse_event(MOUSEEVENTF_LEFTDOWN, point.x, point.y, 0, 0);
            }
        };
    }
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
        static HBRUSH hBrush; //画刷

        switch (Message)
        {
        case WM_CREATE: {

            //创建画刷
            hBrush = CreateSolidBrush(RGB(255, 255, 255)); //白色
            //创建控件
            hEditBox = CreateWindow(L"Edit",
                L"80",
                WS_CHILD | WS_VISIBLE | ES_LEFT | WS_BORDER | ES_LEFT | ES_MULTILINE | ES_AUTOHSCROLL,
                125,
                11,
                96,
                24,
                hwnd,
                0,
                GetModuleHandleW(0),
                NULL);
            LONG_PTR exStyle = GetWindowLongPtr(hEditBox, GWL_EXSTYLE);
            HWND temp = CreateWindow(L"Static",
                L"请输入频率",
                WS_CHILD | WS_VISIBLE | ES_LEFT | BS_MULTILINE,
                40,
                13,
                72,
                24,
                hwnd,
                0,
                GetModuleHandleW(0),
                NULL);
            hStatic = CreateWindow(L"Static",
                L"F10:开启   F11:关闭",
                WS_CHILD | WS_VISIBLE | ES_LEFT | BS_MULTILINE,
                60,
                52,
                136,
                24,
                hwnd,
                0,
                GetModuleHandleW(0),
                NULL);
            SetBkMode(GetDC(hStatic), TRANSPARENT);
            LOGFONTW m_Font = { 0 };
            wchar_t FontName[LF_FACESIZE] = L"Times New Roman";
            wcscpy_s(m_Font.lfFaceName, FontName);
            m_Font.lfHeight = 16;
            SendMessageW(hStatic, WM_SETFONT, (WPARAM)CreateFontIndirectW(&m_Font), 1);
            SendMessageW(hEditBox, WM_SETFONT, (WPARAM)CreateFontIndirectW(&m_Font), 1);
            SendMessageW(temp, WM_SETFONT, (WPARAM)CreateFontIndirectW(&m_Font), 1);
            StaticOldProc = (WNDPROC)SetWindowLongPtrW(hStatic, GWLP_WNDPROC, (LONG_PTR)StaticWNDPROC);
            Click.Create(hwnd, 0, click);
            //win98风格
            SetWindowTheme(hwnd, L"", L"");
            break;
        }
        case WM_CTLCOLORSTATIC:
        {
            //可以通过子类化窗口回调加上获取HDC需要绘制的rect,来改变指定控件
            HDC hdc = (HDC)wParam;
            SetTextColor(hdc, 255);
            SetBkColor(hdc, RGB(255, 255, 255));
            return (LRESULT)hBrush;
        }
        case WM_DESTROY:
        {
            PostQuitMessage(0);
            break;
        }
        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);
        }
        return 0;
    }
public:
    ClickWindow(HMODULE hInstance) :hwnd(NULL), msg{ 0 }{

        WNDCLASSEX wc = { 0 };
        wc.cbSize = sizeof(WNDCLASSEX);
        wc.lpfnWndProc = WndProc;
        wc.hInstance = hInstance;
        wc.lpszClassName = L"ALWindowClass";
        if (!RegisterClassEx(&wc)) {
            exit(0);
            return;
        }
        hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
            L"ALWindowClass",
            L"阿龙吃鸡连点器:",
            WS_VISIBLE | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT,
            280,
            119,
            NULL,
            NULL,
            hInstance,
            NULL);
        //置WIN98风格


        F11 = r.Register(hwnd, hStatic, 0, 122);
        F10 = r.Register(hwnd, hStatic, 0, 121);

    };
    WPARAM ShowAndLoop() {
        while (GetMessage(&msg, NULL, 0, 0) > 0) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return msg.wParam;

    }
    ~ClickWindow() {
        DestroyWindow(hwnd);
        exit(0);
    };

private:
    HWND hwnd;
    MSG msg;
    MyRegisterHotKey r;
};

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR    lpCmdLine,
    _In_ int       nCmdShow)

{
    ClickWindow MainWindow(hInstance);

    MainWindow.ShowAndLoop();
}

CodePudding user response:

Set a WH_MOUSE_LL hook. When the mouse button is released, send a message to your window telling it to stop or set a global variable.

As noted in the comments, the function signature of click is incorrect for a timer callback. Remove the cast and fix click() and your class.

void CALLBACK click(HWND, UINT, UINT_PTR, DWORD) { ... }
  • Related