C语言解决爱写作(Iwrite)粘贴问题(附直接运行软件)

本文对以下相似问题具有参考价值:爱写作不让复制粘贴怎么办?被设置不能复制粘贴怎么办?如何解决爱写作不让复制粘贴问题;“允许粘贴”关闭/被关闭怎么办?模拟键盘一个一个打字的C语言程序

正文:为了应对Iwrite作业禁止粘贴的问题,许多圈内人已提出解决方案。不过,作为计算机专业且热爱C语言编程的学生,我仍然尝试编写了一个C语言小程序,通过模拟键盘输入,逐字打字,以规避粘贴检测。也算是学以致用,把知识用到实践中去。(文章末尾我会放置点开即用的程序软件,不用编程直接使用)

不说废话了,直接源代码:

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#define MAX_STRING_LENGTH 1024
#define BUFFER_SIZE (MAX_STRING_LENGTH * 10)

// 保存原始控制台属性
WORD originalAttributes;

void SetColor(int ForgC) {
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO csbi;

    if (GetConsoleScreenBufferInfo(hStdOut, &csbi)) {
        wchar_t wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);
        SetConsoleTextAttribute(hStdOut, wColor);
    }
}

void TypeCharacter(char c) {
    SHORT vkCode = VkKeyScanA(c);
    if (vkCode == -1) {
        return; // 跳过无效字符
    }

    BYTE key = LOBYTE(vkCode);
    bool needShift = HIBYTE(vkCode) & 0x01;
    bool isCapsLock = (GetKeyState(VK_CAPITAL) & 0x0001);
    needShift ^= isCapsLock; // 考虑大写锁定状态

    INPUT inputs[4] = {0};
    int inputCount = 0;

    // Shift按下
    if (needShift) {
        inputs[inputCount].type = INPUT_KEYBOARD;
        inputs[inputCount].ki.wVk = VK_SHIFT;
        inputCount++;
    }

    // 字符键按下
    inputs[inputCount].type = INPUT_KEYBOARD;
    inputs[inputCount].ki.wVk = key;
    inputCount++;

    // 字符键释放
    inputs[inputCount].type = INPUT_KEYBOARD;
    inputs[inputCount].ki.wVk = key;
    inputs[inputCount].ki.dwFlags = KEYEVENTF_KEYUP;
    inputCount++;

    // Shift释放
    if (needShift) {
        inputs[inputCount].type = INPUT_KEYBOARD;
        inputs[inputCount].ki.wVk = VK_SHIFT;
        inputs[inputCount].ki.dwFlags = KEYEVENTF_KEYUP;
        inputCount++;
    }

    SendInput(inputCount, inputs, sizeof(INPUT));
}

void PressEnter() {
    INPUT inputs[2] = {0};
    
    // 按下Enter键
    inputs[0].type = INPUT_KEYBOARD;
    inputs[0].ki.wVk = VK_RETURN;
    
    // 释放Enter键
    inputs[1].type = INPUT_KEYBOARD;
    inputs[1].ki.wVk = VK_RETURN;
    inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;

    SendInput(2, inputs, sizeof(INPUT));
}

int main() {
    char str[MAX_STRING_LENGTH] = {0};
    char buffer[BUFFER_SIZE] = {0};
    size_t buffer_len = 0;
    
    // 保存原始控制台属性
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hStdOut, (PCONSOLE_SCREEN_BUFFER_INFO)&originalAttributes);

    SetColor(11);
    printf("欢迎使用模拟键盘打字(仅限英语版)    "); 
    
    SetColor(8);
    printf("作者:孤星寒月 2024年12月22日\n\n");
    
    SetColor(14);
    printf("使用说明(简洁):\n");
    printf("1. 输入文本(支持换行)\n");
    printf("2. 单独输入#结束输入\n");
    printf("3. 10秒后自动开始模拟输入\n\n");

    SetColor(15);
    printf("详细说明:\n");
    printf("- 用Enter换行,用#+Enter结束输入\n");
    printf("- 文本中的#会被转换为换行\n");
    printf("- 确保最后切换到英文输入法和目标窗口\n\n");
    
    SetColor(10);
    printf("请输入文本(以单独#结束):\n");
    SetColor(15);

    // 读取输入
    while (fgets(str, MAX_STRING_LENGTH, stdin)) {
        // 移除换行符
        size_t len = strcspn(str, "\n");
        str[len] = 0;

        // 检查结束标记
        if (strcmp(str, "#") == 0) {
            break;
        }

        // 处理#替换
        char processed[MAX_STRING_LENGTH] = {0};
        strncpy(processed, str, sizeof(processed)-1);
        
        char *p = processed;
        while ((p = strchr(p, '#')) != NULL) {
            *p++ = '\n';
        }

        // 计算剩余空间
        size_t remain = BUFFER_SIZE - buffer_len - 1;
        size_t add_len = strlen(processed);
        
        if (add_len >= remain) {
            SetColor(12);
            printf("\n错误:输入内容过长!\n");
            break;
        }

        // 追加内容(保留用户原始换行)
        strcat(buffer + buffer_len, processed);
        buffer_len += add_len;
        
        // 添加换行符
        if (buffer_len < BUFFER_SIZE-1) {
            buffer[buffer_len++] = '\n';
            buffer[buffer_len] = 0;
        }
    }

    SetColor(10);
    printf("\n10秒后开始打印,请准备...\n");
    Sleep(10000); 

    // 执行模拟输入
    const char *ptr = buffer;
    while (*ptr) {
        if (*ptr == '\n') {
            PressEnter();
        } else {
            TypeCharacter(*ptr);
        }
        ptr++;
        Sleep(50);
    }

    // 恢复原始控制台颜色
    SetColor(15);
    
    printf("\n打印完成,请检查结果。\n");
    printf("3秒后自动退出...\n");
    Sleep(3000);
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值