天天看點

Visual C C++ studio2019 自制滑鼠點選器,視窗版和指令行版 210325一 視窗版二 指令行版

一 視窗版

1.h和cpp

h: DesktopMouseClick1.h

#pragma once

#include "resource.h"
#include <thread>
#include <process.h>
#include <string>



#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0) // 對比判斷是不是哪個鍵按下

using namespace std;




static int interval = 3001;  // ClickPress間隔時間 ms毫秒
static wchar_t intervalStr [10];  // 用于從間隔時間編輯框擷取值得緩存
HWND intervalEdit;    // 間隔時間輸入框
HWND intervalEditCommitButton;    // 間隔時間輸入框送出按鈕
wchar_t interval_dec_itow_buffer[_MAX_ITOSTR_BASE10_COUNT];  //定義一個 _itow()  十進制用的緩沖 
const int KeyUpDownInterval = 1;
static int choose = 0;

const char MouseLeftClickStartKey = 'L';
const char MouseRightClickStartKey = 'R';
const char EnterpressStartKey = 'E';
const char SetIntervalMillisecondKey = 'T';

void keypress(int vk) {
	keybd_event(vk, 0, 0, 0); // keydown 按下
	Sleep(KeyUpDownInterval);
	keybd_event(vk, 0, KEYEVENTF_KEYUP, 0);  // keyup 起來
}
void enterpress() { keypress(VK_RETURN); }  // 模拟Enter鍵


void hotkeyListen() {
	while (1) {
		if (KEY_DOWN(VK_SPACE)) {//VK_SPACE 是空格的虛拟鍵值     停止
			choose = 0;			Sleep(KeyUpDownInterval);//你的手不會再一瞬間送開,是以要處理一下 
		}
		if (KEY_DOWN(MouseLeftClickStartKey)) { choose = MouseLeftClickStartKey;			Sleep(KeyUpDownInterval); }   // 左鍵連擊
		if (KEY_DOWN(MouseRightClickStartKey)) { choose = MouseRightClickStartKey;			Sleep(KeyUpDownInterval); }  // 右鍵連擊
		if (KEY_DOWN(EnterpressStartKey)) { choose = EnterpressStartKey;			Sleep(KeyUpDownInterval); }  //enter連擊

		
		Sleep(KeyUpDownInterval);
	}
}
void intervalFromEditCommit() {
	GetWindowText(intervalEdit, intervalStr, (int)GetWindowTextLength(intervalEdit) + 1);
	interval = _wtoi(intervalStr);
}

void ClickPressWork(void* ignored) {
	thread thread010(hotkeyListen);
	while (1) {

		if (choose == MouseLeftClickStartKey) {//模拟點選左鍵 
			mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
			Sleep(KeyUpDownInterval);//要留給某些應用的反應時間 
			mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
		}
		if (choose == MouseRightClickStartKey) {//模拟點選右鍵 
			mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
			Sleep(KeyUpDownInterval);
			mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
		}
		if (choose == EnterpressStartKey) {  //Enter
			enterpress();
		}
		if (interval < KeyUpDownInterval || interval >99999)interval = KeyUpDownInterval + 1;
		Sleep(interval - KeyUpDownInterval);//點選間隔 機關是毫秒 
	}
}
           

cpp : DesktopMouseClick1.cpp

// DesktopMouseClick1.cpp : 定義應用程式的入口點。
//
//#include<iostream>
#define _CRT_SECURE_NO_WARNINGS 1   //壓制編譯警告, 要放最上面  壓制 _itow()  (int轉wchar_t *) 的C4996警告
#include "framework.h"
#include "DesktopMouseClick1.h"

using namespace std;


#define _CRT_SECURE_NO_WARNINGS 1
#include <stdlib.h>

#define MAX_LOADSTRING 100

// 全局變量:
HINSTANCE hInst;                                // 目前執行個體
WCHAR szTitle[MAX_LOADSTRING] ;                  // 标題欄文本
WCHAR szWindowClass[MAX_LOADSTRING] ;            // 主視窗類名

// 此代碼子產品中包含的函數的前向聲明:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

// 我聲明的變量  ↓ ↓ ↓
RECT  rect;   //用于繪制


// 我聲明的變量  ↑ ↑ ↑

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

    // TODO: 在此處放置代碼。

    // 初始化全局字元串
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_DESKTOPMOUSECLICK1, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // 執行應用程式初始化:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DESKTOPMOUSECLICK1));

    MSG msg;

    // 主消息循環:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

//
//  函數: MyRegisterClass()
//
//  目标: 注冊視窗類。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DESKTOPMOUSECLICK1));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_DESKTOPMOUSECLICK1);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

//
//   函數: InitInstance(HINSTANCE, int)
//
//   目标: 儲存執行個體句柄并建立主視窗
//
//   注釋:
//
//        在此函數中,我們在全局變量中儲存執行個體句柄并
//        建立和顯示主程式視窗。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // 将執行個體句柄存儲在全局變量中
   
   HWND hWnd = CreateWindowW(
       //第 1 個參數
       szWindowClass    // window class name   用法:   TEXT("EDIT")則可編輯  | 
       //TEXT("EDIT")

       //第 2 個參數
       , szTitle      // window title caption  用法:  TEXT ("你好世界")
       //, TEXT("3000")

       // 第3個參數  dwStyle
       , WS_OVERLAPPEDWINDOW  //預設  WS_OVERLAPPEDWINDOW可以建立一個擁有各種視窗風格的窗體,包括标題,系統菜單,邊框,最小化和最大化按鈕等。
       //, WS_VISIBLE |  WS_BORDER | ES_AUTOHSCROLL  | WS_OVERLAPPEDWINDOW


       //第4,5,6,7個參數
       , CW_USEDEFAULT  // left      如果這個參數設定CW_USEDEFAULT,系統選擇的預設位置視窗的左上角,而忽略了y參數。CW_USEDEFAULT隻有對重疊視窗是有效的;如果指定一個彈出子視窗,x和y 參數設定為零。        也就是說一般用它來建立你的程式的父視窗用的。
       , 0     
       , 333  //width
       , 120   //height

       //第8,9,10.11個參數          nullptr 為 c11 的指針專用NULL
       , nullptr     // parent window handle  為“父視窗句柄”,一般為NULL,如果有視窗之間存在父子關系,則子視窗總是出現在父視窗的上面。但應用程式視窗出現在桌面視窗的上面時,不必為調用CreateWindow而找出桌面視窗的句柄。
       , nullptr     // window menu handle   為“視窗菜單句柄”,如沒有菜單則為NULL
       , hInstance   // program instance handle   為“程式執行個體句柄”,設定為執行個體句柄,它是作為WinMain的參數傳遞給這個程式的。
       , nullptr    //  // creation parameters  “建立參數”指針,設定為NULL,可以用這個指針通路以後想要引用的程式中的資料
   );
   if (!hWnd)   {      return FALSE;   }

   

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);
   return TRUE;
}

//
//  函數: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目标: 處理主視窗的消息。
//
//  WM_COMMAND  - 處理應用程式菜單
//  WM_PAINT    - 繪制主視窗
//  WM_DESTROY  - 發送退出消息并傳回
//
//

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE: {   //建立視窗時調用
        intervalEdit = CreateWindow(TEXT("EDIT"),  _itow(interval, interval_dec_itow_buffer, 10) ,  WS_VISIBLE | WS_CHILD, 150, 0, 100, 20, hWnd, nullptr, hInst, nullptr);
        intervalEditCommitButton = CreateWindow(L"Button", L"送出", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
            258, 0, 60, 20, hWnd, (HMENU)333, hInst, nullptr);


        //thread thread030(ClickPressWork);  // 開線程方式1;
        _beginthread(ClickPressWork, 0, 0);   //開線程方式2;
       
       
        break;
    }
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 分析菜單選擇:
            switch (wmId)
            {
            case ID_ClickPressStop :                choose = 0;                 break;
            case ID_StopClickPress001:                choose = 0;                 break;
            case ID_MouseLeftClickStart001:                 choose = MouseLeftClickStartKey;		                break;
            case ID_MouseLeftClickStart002:                 choose = MouseLeftClickStartKey;		                break;
            case ID_MouseLeftClickStart003:                 choose = MouseLeftClickStartKey;		                break;
            case ID_MouseRightClickStart002:                 choose = MouseRightClickStartKey;		                break;
            case ID_MouseRightClickStart003:                 choose = MouseRightClickStartKey;		                break;
            case ID_KeyboardEnterPressStart002:                 choose = MouseRightClickStartKey;		                break;
            case ID_KeyboardEnterPressStart003:                 choose = MouseRightClickStartKey;		                break;
            case 333:   intervalFromEditCommit();      MessageBox(hWnd, _itow(interval, interval_dec_itow_buffer, 10), L"間隔時間為(ms)", MB_OK);   break;  //間隔時間送出按鈕
           


            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT: 
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 在此處添加使用 hdc 的任何繪圖代碼...
            //我添加的代碼  ↓↓↓↓↓↓↓↓↓↓↓↓↓

            wchar_t str010[] = L"點選間隔時間(毫秒) : ";
            TextOut(hdc, 0, 0, str010, (int)wcslen(str010));   // 第 2 , 3 個參數可以指定 x , y
            
            
            wchar_t str020[] = L"空格停止, L左鍵, R右鍵, E回車連擊";
            //GetClientRect(hWnd, &rect);  /*傳入指定視窗的矩形區域*/    DrawText(hdc, str020, wcslen(str020), &rect, DT_CENTER | DT_VCENTER);
            TextOut(hdc, 0, 20, str020, (int)wcslen(str020));   // 第 2 , 3 個參數可以指定 x , y
           
            





            //我添加的代碼    ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY: 
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    
    return 0;
}

// “關于”框的消息處理程式。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}




           

2.根據所需功能建立菜單

Visual C C++ studio2019 自制滑鼠點選器,視窗版和指令行版 210325一 視窗版二 指令行版

3.根據菜單ID編寫功能

Visual C C++ studio2019 自制滑鼠點選器,視窗版和指令行版 210325一 視窗版二 指令行版

效果截圖

64位版大小109k 輕快小巧純綠色 win32原生api

Visual C C++ studio2019 自制滑鼠點選器,視窗版和指令行版 210325一 視窗版二 指令行版

二 指令行版

效果截圖

Visual C C++ studio2019 自制滑鼠點選器,視窗版和指令行版 210325一 視窗版二 指令行版

代碼

滑鼠連擊-指令行版.cpp

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

#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0) 

using namespace std;


static int interval = 3000;  // 連擊間隔時間 機關毫秒
const int KeyUpDownInterval = 1;  //按下與彈起的間隔 機關毫秒
static int choose = 0;

const char MouseLeftClickStartKey = 'L';
const char MouseRightClickStartKey = 'R';
const char EnterpressStartKey = 'E';
const char SetIntervalMillisecondKey = 'T';

void keypress(int vk) {
	keybd_event(vk, 0, 0, 0); // keydown 按下
	Sleep(KeyUpDownInterval);
	keybd_event(vk, 0, KEYEVENTF_KEYUP, 0);  // keyup 起來
}
void enterpress() { keypress(VK_RETURN); }  // 模拟Enter鍵
void configMethod() {


	string s = "3000";
	string* r = &s;
	while (1) {
		if (KEY_DOWN(VK_SPACE)) {//VK_SPACE 是空格的虛拟鍵值  
			choose = 0;
			Sleep(KeyUpDownInterval);//你的手不會再一瞬間送開,是以要處理一下 
		}
		if (KEY_DOWN(MouseLeftClickStartKey)) { choose = MouseLeftClickStartKey;			Sleep(KeyUpDownInterval); }
		if (KEY_DOWN(MouseRightClickStartKey)) { choose = MouseRightClickStartKey;			Sleep(KeyUpDownInterval); }
		if (KEY_DOWN(EnterpressStartKey)) { choose = EnterpressStartKey;			Sleep(KeyUpDownInterval); }

		if (KEY_DOWN(SetIntervalMillisecondKey)) {


			cout << "目前時間間隔" << interval - KeyUpDownInterval << "毫秒   " << endl;
			cout << "   請輸入時間: 機關毫秒" << endl;

			try { cin.end;   cin >> s; }
			catch (exception exception) { cout << exception.what(); }



			cout << "輸入的内容是 : " << s << endl;
			interval = atoi(s.c_str());
			if (interval < KeyUpDownInterval || interval >99999)interval = KeyUpDownInterval + 1;
			cout << "目前時間間隔" << interval- KeyUpDownInterval << "毫秒   " << endl;
			printf("按   空格   鍵停止\n");
			
			Sleep(KeyUpDownInterval);
		}
		Sleep(KeyUpDownInterval);
	}
}

int main() {


	::thread thread(configMethod);

	printf("按   空格   鍵停止\n");
	cout << "按   " << MouseLeftClickStartKey << "   開始滑鼠左鍵點選" << endl;
	cout << "按   " << MouseRightClickStartKey << "   開始滑鼠右鍵點選" << endl;
	cout << "按   " << EnterpressStartKey << "   開始Enter鍵點選" << endl;
	cout << "按   " << SetIntervalMillisecondKey << "    設定時間間隔 機關毫秒" << endl;



	while (1) {

		if (choose == MouseLeftClickStartKey) {//模拟點選左鍵 
			mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
			Sleep(KeyUpDownInterval);
			mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
		}
		if (choose == MouseRightClickStartKey) {//模拟點選右鍵 
			mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
			Sleep(KeyUpDownInterval);
			mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
		}
		if (choose == EnterpressStartKey) {  //Enter
			enterpress();
		}
		if (interval < KeyUpDownInterval || interval >99999)interval = KeyUpDownInterval + 1;
		Sleep(interval - KeyUpDownInterval);//點選間隔 機關是毫秒 
	}
}
           

帶正則驗證的指令行版

Visual C C++ studio2019 自制滑鼠點選器,視窗版和指令行版 210325一 視窗版二 指令行版
#include <iostream>
#include<regex>
#include<windows.h>
#include <thread>

#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0) 

using namespace std;


static int interval = 3000;  // 連擊間隔時間 機關毫秒
string s = "3000";
char charArray100[100];
const int KeyUpDownInterval = 1;  //按下與彈起的間隔 機關毫秒
static int choose = 0;
static regex regexNotDigit("\\D");

const char ExitKey = 'X';
const char MouseLeftClickStartKey = 'L';
const char MouseRightClickStartKey = 'R';
const char EnterpressStartKey = 'E';
const char SetIntervalMillisecondKey = 'T';

void keypress(int vk) {
	keybd_event(vk, 0, 0, 0); // keydown 按下
	Sleep(KeyUpDownInterval);
	keybd_event(vk, 0, KEYEVENTF_KEYUP, 0);  // keyup 起來
}

void enterpress() { keypress(VK_RETURN); }  // 模拟Enter鍵


void hint() {
	printf("按   空格   鍵停止\n");
	cout << "按   " << MouseLeftClickStartKey << "   開始滑鼠左鍵點選" << endl;
	cout << "按   " << MouseRightClickStartKey << "   開始滑鼠右鍵點選" << endl;
	cout << "按   " << EnterpressStartKey << "   開始Enter鍵點選" << endl;
	cout << "按   " << SetIntervalMillisecondKey << "   設定時間間隔 機關毫秒" << endl;
	cout << "按   " << ExitKey << "   退出" << endl;
}

void controlKeyListen() {

	while (1) {
		if (choose == ExitKey) { return; }
		if (KEY_DOWN(VK_SPACE)) { 	choose = 0;	Sleep(KeyUpDownInterval);		}  //VK_SPACE 是空格的虛拟鍵值    暫停點選
		if (KEY_DOWN(MouseLeftClickStartKey)) { choose = MouseLeftClickStartKey;			Sleep(KeyUpDownInterval); }
		if (KEY_DOWN(MouseRightClickStartKey)) { choose = MouseRightClickStartKey;			Sleep(KeyUpDownInterval); }
		if (KEY_DOWN(EnterpressStartKey)) { choose = EnterpressStartKey;			Sleep(KeyUpDownInterval); }

		if (KEY_DOWN(SetIntervalMillisecondKey)) {  //設定間隔時間
			cout << "目前時間間隔" << interval - KeyUpDownInterval << "毫秒   " << endl;
			cout << "   請移除非數字(如果有的話),并輸入時間: 機關毫秒" << endl;

			cin.getline(charArray100, 100);  s = charArray100;  cout << "輸入的内容是 : " << s << endl;
			// regex_replace(字元串, 正規表達式,替換後的字元串部分)函數,它傳回一個string字元串對象
			s = regex_replace(s, regexNotDigit, "");

			cout << "替換後的輸入的内容是 : " << s << endl;
			interval = atoi(s.c_str());
			if (interval < KeyUpDownInterval || interval >999999999)interval = KeyUpDownInterval + 1;
			cout << "目前時間間隔" << interval << "毫秒   " << endl;
			hint();
			
			Sleep(KeyUpDownInterval);
		}
		if (KEY_DOWN(ExitKey)) { choose = ExitKey;	 } 
		Sleep(KeyUpDownInterval);
	}
}

int main() {
	
	thread ControlKeyListenThread(controlKeyListen);  // 鍵盤監聽線程
	
	hint();

	while (1) {
		if (choose == ExitKey) { ControlKeyListenThread.join();  break; }  //退出程式
		if (choose == MouseLeftClickStartKey) {//模拟點選左鍵 
			mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
			Sleep(KeyUpDownInterval);
			mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
		}
		if (choose == MouseRightClickStartKey) {//模拟點選右鍵 
			mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
			Sleep(KeyUpDownInterval);
			mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
		}
		if (choose == EnterpressStartKey) {  //Enter
			enterpress();
		}
		if (interval < KeyUpDownInterval || interval >999999999)interval = KeyUpDownInterval + 1;
		Sleep(interval - KeyUpDownInterval);//點選間隔 機關是毫秒 
	}
	
}
           

初始參考

繼續閱讀