鱼C论坛

 找回密码
 立即注册
查看: 1501|回复: 6

c语言怎样实现当窗口失去焦点时按键检测

[复制链接]
发表于 2023-10-11 07:33:22 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
这是我用getch函数写的,但是不能失去焦点。
#include <stdio.h>
#include <conio.h>

void main()
{
        int anjian_d = 0;
        int anjian_f = 0;
        int anjian_j = 0;
        int anjian_k = 0;
        int anjian_sum = 0;
        while(1)
        {
                if (_kbhit())
                {
                        
                        switch (_getch())
                        {
                        case 'd':
                        case 'D':
                                anjian_d++;
                                break;
                        case 'f':
                        case 'F':
                                anjian_f++;
                                break;
                        case 'j':
                        case 'J':
                                anjian_j++;
                                break;
                        case 'k':
                        case 'K':
                                anjian_k++;
                                break;
                        }
                        system("cls");
                        anjian_sum = anjian_d + anjian_f + anjian_j + anjian_k;
                        printf("d:%d\nf:%d\nj:%d\nk:%d\nsum:%d\n", anjian_d, anjian_f, anjian_j, anjian_k,anjian_sum);
                }
        }
}

这是我用getkeystate写的,但是如果持续按键他会一直检测到,然后变量会一直在增加。
#include <stdio.h>
#include <conio.h>
#include <Windows.h>

void main()
{
        int ajd,ajD, ajf, ajj, ajk,ajF,ajJ,ajK;
        int anjian_d = 0;
        int anjian_f = 0;
        int anjian_j = 0;
        int anjian_k = 0;
        int anjian_sum = 0;
        while (1)
        {
                if (_kbhit())
                {
                        ajd = GetKeyState(100);
                        ajf = GetKeyState(102);
                        ajj = GetKeyState(106);
                        ajk = GetKeyState(107);
                        ajD = GetKeyState(68);
                        ajF = GetKeyState(70);
                        ajJ = GetKeyState(74);
                        ajK = GetKeyState(75);
                        if (ajd < 0 || ajD < 0)
                        {
                                anjian_d++;
                                goto end;
                        }
                        if (ajf < 0 || ajF < 0)
                        {
                                anjian_f++;
                                goto end;
                        }
                        if (ajJ < 0 || ajj < 0)
                        {
                                anjian_j++;
                                goto end;
                        }
                        if (ajK < 0 || ajk < 0)
                        {
                                anjian_k++;
                        }
                end:
                        system("cls");
                        anjian_sum = anjian_d + anjian_f + anjian_j + anjian_k;
                        printf("d:%d\nf:%d\nj:%d\nk:%d\nsum:%d\n", anjian_d, anjian_f, anjian_j, anjian_k, anjian_sum);
                }
        }
}

想问问怎么用getkeystate实现和getch一样的效果。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-10-11 07:33:57 | 显示全部楼层
可以使用GetForegroundWindow和GetFocus函数来获取当前窗口是否失去焦点,如果失去焦点就不再检测按键。同时,可以使用GetAsyncKeyState函数来检测按键是否按下,如果按下就执行相应的操作。

以下是代码示例:
#include <stdio.h>
#include <Windows.h>

void main() {
    int anjian_d = 0;
    int anjian_f = 0;
    int anjian_j = 0;
    int anjian_k = 0;
    int anjian_sum = 0;
    HWND hwnd = GetForegroundWindow();
    while (1) {
        if (hwnd != GetForegroundWindow() || GetFocus() != hwnd) {
            Sleep(100); // 等待100毫秒
            continue; // 如果窗口失去焦点,就不再检测按键
        }
        if (GetAsyncKeyState('D') & 0x8000) {
            anjian_d++;
        }
        if (GetAsyncKeyState('F') & 0x8000) {
            anjian_f++;
        }
        if (GetAsyncKeyState('J') & 0x8000) {
            anjian_j++;
        }
        if (GetAsyncKeyState('K') & 0x8000) {
            anjian_k++;
        }
        system("cls");
        anjian_sum = anjian_d + anjian_f + anjian_j + anjian_k;
        printf("d:%d\nf:%d\nj:%d\nk:%d\nsum:%d\n", anjian_d, anjian_f, anjian_j, anjian_k, anjian_sum);
        Sleep(100); // 等待100毫秒
    }
}

在代码中,使用GetForegroundWindow函数获取当前窗口句柄,然后在循环中判断窗口是否失去焦点。如果窗口失去焦点,就使用Sleep函数等待100毫秒,然后重新开始循环。如果窗口没有失去焦点,就使用GetAsyncKeyState函数检测按键是否按下,并执行相应的操作。最后使用Sleep函数等待100毫秒,然后重新开始循环。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-11 07:34:10 | 显示全部楼层
在Windows环境下,GetKeyState函数可以用来检测键盘的按键状态,包括当窗口失去焦点时的按键状态。但是,GetKeyState函数会持续检测按键状态,即使按键已经被按下并释放,只要没有其他键被按下,它仍然会返回按键被按下的状态。这就是你在使用GetKeyState函数时,如果持续按键,变量会一直增加的原因。

要实现和getch一样的效果,即只在按键被按下的那一刻检测到按键,可以使用Windows的消息队列。当一个按键被按下时,Windows会将一个消息放入消息队列,你可以使用GetMessagePeekMessage函数来获取这个消息。然后,你可以使用TranslateMessageDispatchMessage函数来处理这个消息。

以下是一个使用消息队列来检测按键的示例代码:
#include <stdio.h>
#include <windows.h>

void main() {
    MSG msg;
    int anjian_d = 0;
    int anjian_f = 0;
    int anjian_j = 0;
    int anjian_k = 0;
    int anjian_sum = 0;

    while (1) {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
            if (msg.message == WM_KEYDOWN) {
                switch (msg.wParam) {
                case 'd':
                case 'D':
                    anjian_d++;
                    break;
                case 'f':
                case 'F':
                    anjian_f++;
                    break;
                case 'j':
                case 'J':
                    anjian_j++;
                    break;
                case 'k':
                case 'K':
                    anjian_k++;
                    break;
                }
                system("cls");
                anjian_sum = anjian_d + anjian_f + anjian_j + anjian_k;
                printf("d:%d\
f:%d\
j:%d\
k:%d\
sum:%d\
", anjian_d, anjian_f, anjian_j, anjian_k, anjian_sum);
            }
        }
    }
}

这段代码会创建一个消息循环,不断地从消息队列中取出消息并处理。当检测到一个按键被按下的消息时,它会增加相应的计数器,并更新显示的按键计数。

请注意,这段代码只能在Windows环境下运行,因为它使用了Windows的消息队列。在其他操作系统下,你可能需要使用不同的方法来检测按键。
请注意,本回答来自GPT-4
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-11 07:35:14 | 显示全部楼层
对于需要在窗口失去焦点时检测按键的需求,可以使用Windows API函数来实现。你可以使用GetAsyncKeyState函数来获取按键状态。以下是修改后的代码示例:
#include <stdio.h>#include <Windows.h>int main() {    int anjian_d = 0;    int anjian_f = 0;    int anjian_j = 0;    int anjian_k = 0;    int anjian_sum = 0;    while (1) {        if (GetAsyncKeyState('D') & 0x8000) {            anjian_d++;            system("cls");            anjian_sum = anjian_d + anjian_f + anjian_j + anjian_k;            printf("d:%d\nf:%d\nj:%d\nk:%d\nsum:%d\n", anjian_d, anjian_f, anjian_j, anjian_k, anjian_sum);        }        if (GetAsyncKeyState('F') & 0x8000) {            anjian_f++;            system("cls");            anjian_sum = anjian_d + anjian_f + anjian_j + anjian_k;            printf("d:%d\nf:%d\nj:%d\nk:%d\nsum:%d\n", anjian_d, anjian_f, anjian_j, anjian_k, anjian_sum);        }        if (GetAsyncKeyState('J') & 0x8000) {            anjian_j++;            system("cls");            anjian_sum = anjian_d + anjian_f + anjian_j + anjian_k;            printf("d:%d\nf:%d\nj:%d\nk:%d\nsum:%d\n", anjian_d, anjian_f, anjian_j, anjian_k, anjian_sum);        }        if (GetAsyncKeyState('K') & 0x8000) {            anjian_k++;            system("cls");            anjian_sum = anjian_d + anjian_f + anjian_j + anjian_k;            printf("d:%d\nf:%d\nj:%d\nk:%d\nsum:%d\n", anjian_d, anjian_f, anjian_j, anjian_k, anjian_sum);        }    }    return 0;}
这样修改后的代码使用GetAsyncKeyState函数来检测按键状态,当某个按键被按下时,对应的计数器增加,并打印输出结果。请注意,GetAsyncKeyState函数在窗口失去焦点时也能正常工作。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-10-11 07:35:16 | 显示全部楼层
isdkz 发表于 2023-10-11 07:33
可以使用GetForegroundWindow和GetFocus函数来获取当前窗口是否失去焦点,如果失去焦点就不再检测按键。同 ...

我的意思是失去焦点的时候也能获取
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-10-11 07:38:47 | 显示全部楼层
Mike_python小 发表于 2023-10-11 07:35
对于需要在窗口失去焦点时检测按键的需求,可以使用Windows API函数来实现。你可以使用GetAsyncKeyState函 ...

这样如果持续按键变量会一直增加
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-10-11 07:41:04 | 显示全部楼层
陶远航 发表于 2023-10-11 07:34
在Windows环境下,GetKeyState函数可以用来检测键盘的按键状态,包括当窗口失去焦点时的按键状态。但是,Ge ...

按下按键之后没反应
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-7 07:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表