使用就是打开就行,设好参数点击开始,其中设置CTRL+V会导致原本粘贴无效
[C++] 纯文本查看 复制代码
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <string.h>
// 确保虚拟键码定义
#define VK_E 0x45
#define VK_Q 0x51
#define VK_V 0x56
// 定义资源标识符
#define IDC_BUTTON_START 101
#define IDC_BUTTON_STOP 102
#define IDC_EDIT_INTERVAL 103
#define IDC_COMBO_HOTKEY 104
// 定义定时器ID
#define TIMER_ID_RESET_INTERVAL 1
// 全局变量
HINSTANCE g_hInst = NULL;
HHOOK g_hHook = NULL;
BOOL g_bHookInstalled = FALSE;
HWND g_hMainWnd = NULL;
int g_nInputInterval = 20; // 默认输入间隔(毫秒)
BOOL g_bTerminateInput = FALSE; // 是否终止输入标志
int g_nSelectedHotkey = 0; // 0: Ctrl+E, 1: Ctrl+Q, 2: Ctrl+V, 3: Alt+V
HANDLE g_hInputThread = NULL; // 输入线程句柄
WCHAR* g_pszClipboardText = NULL; // 剪贴板文本
// 函数声明
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void SetClipboardHook();
void RemoveClipboardHook();
void SimulateTextInput(const WCHAR* text);
void SimulateCharInput(WCHAR ch);
void CreateMainWindow();
void UpdateUIState();
DWORD WINAPI SimulateTextInputThread(LPVOID lpParam);
// DLL 入口点
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
g_hInst = (HINSTANCE)hModule;
return TRUE;
}
// 键盘钩子回调函数
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode >= 0) {
KBDLLHOOKSTRUCT* pkbllhs = (KBDLLHOOKSTRUCT*)lParam;
// 检测快捷键
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
BOOL bBlock = FALSE;
BOOL bAltPressed = (GetAsyncKeyState(VK_MENU) & 0x8000) != 0;
BOOL bCtrlPressed = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0;
switch (g_nSelectedHotkey) {
case 0: // Ctrl+E
if (pkbllhs->vkCode == VK_E && bCtrlPressed && !bAltPressed) {
bBlock = TRUE;
}
break;
case 1: // Ctrl+Q
if (pkbllhs->vkCode == VK_Q && bCtrlPressed && !bAltPressed) {
bBlock = TRUE;
}
break;
case 2: // Ctrl+V
if (pkbllhs->vkCode == VK_V && bCtrlPressed && !bAltPressed) {
bBlock = TRUE;
}
break;
case 3: // Alt+V
if (pkbllhs->vkCode == VK_V && bAltPressed && !bCtrlPressed) {
bBlock = TRUE;
}
break;
}
if (bBlock) {
if (g_hInputThread != NULL) {
g_bTerminateInput = TRUE; // 设置终止输入标志
} else {
if (OpenClipboard(NULL)) {
HANDLE hData = GetClipboardData(CF_UNICODETEXT);
if (hData != NULL) {
g_pszClipboardText = (WCHAR*)GlobalLock(hData);
if (g_pszClipboardText != NULL) {
g_hInputThread = CreateThread(NULL, 0, SimulateTextInputThread, (LPVOID)g_pszClipboardText, 0, NULL);
}
GlobalUnlock(hData);
}
CloseClipboard();
}
}
return 1; // 阻止默认操作
}
}
}
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
// 设置钩子
void SetClipboardHook() {
if (!g_bHookInstalled) {
g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, g_hInst, 0);
if (g_hHook != NULL) {
g_bHookInstalled = TRUE;
UpdateUIState();
}
}
}
// 移除钩子
void RemoveClipboardHook() {
if (g_bHookInstalled) {
UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
g_bHookInstalled = FALSE;
UpdateUIState();
}
}
// 模拟输入宽字符文本
void SimulateTextInput(const WCHAR* text) {
g_bTerminateInput = FALSE; // 重置终止标志
for (const WCHAR* p = text; *p != L'\0' && !g_bTerminateInput; ++p) {
SimulateCharInput(*p);
Sleep(g_nInputInterval); // 使用自定义间隔
}
if (g_bTerminateInput) {
g_bTerminateInput = FALSE; // 重置标志
}
}
// 模拟宽字符输入
void SimulateCharInput(WCHAR ch) {
INPUT input[2] = {0};
input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = 0;
input[0].ki.wScan = ch;
input[0].ki.dwFlags = KEYEVENTF_UNICODE;
input[1].type = INPUT_KEYBOARD;
input[1].ki.wVk = 0;
input[1].ki.wScan = ch;
input[1].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
SendInput(2, input, sizeof(INPUT));
}
// 创建主窗口
void CreateMainWindow() {
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = g_hInst;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = "ClipboardHookWndClass";
if (RegisterClassEx(&wc)) {
g_hMainWnd = CreateWindowEx(
0,
"ClipboardHookWndClass",
"剪贴板文本输入器1.0",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 350, 250,
NULL,
NULL,
g_hInst,
NULL
);
if (g_hMainWnd) {
ShowWindow(g_hMainWnd, SW_SHOW);
UpdateUIState();
}
}
}
// 更新UI状态
void UpdateUIState() {
if (g_hMainWnd) {
EnableWindow(GetDlgItem(g_hMainWnd, IDC_BUTTON_START), !g_bHookInstalled);
EnableWindow(GetDlgItem(g_hMainWnd, IDC_BUTTON_STOP), g_bHookInstalled);
}
}
// 窗口过程函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
static HWND hEditInterval = NULL;
static HWND hComboHotkey = NULL;
switch (message) {
case WM_CREATE:
{
// 创建控件
CreateWindow("BUTTON", "开启",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
20, 30, 80, 30, hWnd, (HMENU)IDC_BUTTON_START, g_hInst, NULL);
CreateWindow("BUTTON", "关闭",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
120, 30, 80, 30, hWnd, (HMENU)IDC_BUTTON_STOP, g_hInst, NULL);
hEditInterval = CreateWindow("EDIT", "50",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | ES_NUMBER,
170, 80, 140, 30, hWnd, (HMENU)IDC_EDIT_INTERVAL, g_hInst, NULL);
CreateWindow("STATIC", "输入间隔(毫秒):",
WS_VISIBLE | WS_CHILD | SS_LEFT,
20, 80, 130, 30, hWnd, NULL, g_hInst, NULL);
CreateWindow("STATIC", "快捷键(再按终止)):",
WS_VISIBLE | WS_CHILD | SS_LEFT,
20, 120, 150, 100, hWnd, NULL, g_hInst, NULL);
// 创建组合框
hComboHotkey = CreateWindowW(L"COMBOBOX", NULL,
WS_TABSTOP | WS_VISIBLE | WS_CHILD | CBS_DROPDOWNLIST,
160, 120, 165, 100, hWnd, (HMENU)IDC_COMBO_HOTKEY, g_hInst, NULL);
// 添加组合框项
SendMessageW(hComboHotkey, CB_ADDSTRING, 0, (LPARAM)L"Ctrl+E");
SendMessageW(hComboHotkey, CB_ADDSTRING, 0, (LPARAM)L"Ctrl+Q");
SendMessageW(hComboHotkey, CB_ADDSTRING, 0, (LPARAM)L"Ctrl+V");
SendMessageW(hComboHotkey, CB_ADDSTRING, 0, (LPARAM)L"Alt+V");
SendMessageW(hComboHotkey, CB_SETCURSEL, 0, 0); // 默认选择第一个
// 设置定时器,在100毫秒后触发
SetTimer(hWnd, TIMER_ID_RESET_INTERVAL, 100, NULL);
UpdateUIState();
break;
}
case WM_CTLCOLORSTATIC:
{
HDC hdc = (HDC)wParam;
HWND hwndStatic = (HWND)lParam;
// 设置背景颜色为白色
SetBkColor(hdc, RGB(255, 255, 255));
// 返回白色画刷作为背景
return (LRESULT)GetStockObject(WHITE_BRUSH);
}
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
if (wmId == IDC_BUTTON_START) {
SetClipboardHook();
} else if (wmId == IDC_BUTTON_STOP) {
RemoveClipboardHook();
} else if (wmId == IDC_EDIT_INTERVAL) {
if (HIWORD(wParam) == EN_CHANGE) {
TCHAR buffer[32];
GetWindowText(hEditInterval, buffer, 32);
g_nInputInterval = _ttoi(buffer);
}
} else if (wmId == IDC_COMBO_HOTKEY) {
if (HIWORD(wParam) == CBN_SELCHANGE) {
int index = SendMessage(hComboHotkey, CB_GETCURSEL, 2, 0);
g_nSelectedHotkey = index;
}
}
break;
}
case WM_TIMER:
{
if (wParam == TIMER_ID_RESET_INTERVAL) {
// 停止定时器
KillTimer(hWnd, TIMER_ID_RESET_INTERVAL);
// 将输入间隔改回20
g_nInputInterval = 20;
// 更新编辑框的显示
TCHAR buffer[32];
_itot(g_nInputInterval, buffer, 10);
SetWindowText(hEditInterval, buffer);
}
break;
}
case WM_CLOSE:
RemoveClipboardHook();
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// 主函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
CreateMainWindow();
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
// 模拟输入线程函数
DWORD WINAPI SimulateTextInputThread(LPVOID lpParam) {
SimulateTextInput((WCHAR*)lpParam);
g_hInputThread = NULL;
return 0;
}