• 千万注意!使用GetAsyncKeyState检测窗口按键时要检查是否为前端窗口!


    我先放一些图:
    1
    2
    3
    4
    记住,这些同志都是没有注意到这个问题的


    有时候比如说写游戏的时候都要检测玩家的按键,我们经常要么用getch(),要么就用GetAsyncKeyState(),我这里要强调一下后者的一个问题。
    这个函数很常见,比如可以写成宏:

    #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) 
    #define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
    
    • 1
    • 2

    (那个& 0x8000还是要写的,低位忽略可是微软官网上说的)
    很多人实际会这么写,上面也已经有很多例子了:

    if( GetAsyncKeyState('A') & 0x8000 )
    {
        p.x --;
        //还有一些坐标判断以及限制省略
    }
    else if( GetAsyncKeyState('D') & 0x8000 )
    {
        p.x ++;
    }
    if( GetAsyncKeyState('W') & 0x8000 )
    {
        p.y --;
    }
    else if( GetAsyncKeyState('S') & 0x8000 )
    {
        p.y ++; 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    (或者是检测VK_上下左右)

    这样就出现了这个问题了,那就是
    GetAsyncKeyState()是一个Windows全局用的函数,没有针对窗口。
    不判断的后果
    你在别的地方输入一行文字,其中包括a,w,s,d,(中文也行)你发现你的游戏人物竟然动起来了!!!
    万一你在哪里输个密码,岂不是字母都可以通过玩家的位移来推断了??!
    所以如果你不进行窗口前端的判断就会造成 用 户 隐 私 泄 露 。
    是不是很可怕?(别想着用这个函数窃听键盘,因为时间的问题是检测不出来的)

    正确的解决方式见下,抓紧时间记住!

    #define KEY_DOWN(VK) ((GetAsyncKeyState(VK)& 0x8000 ? 1:0))
    #define KEY_DOWN_FOREGROUND(hWnd,vk) (KEY_DOWN(vk) && GetForegroundWindow() == hWnd) //前景窗口判断
    
    • 1
    • 2

    其中hWnd为你的游戏或者什么程序的窗口句柄。
    如果嫌麻烦:

    #define K(sk) KEY_DOWN_FOREGROUND(hWnd,sk)
    
    • 1

    然后再去写实际的代码。这样才安全好吧。

    另外,如果使用getch()或_getch(),是不会有任何泄露隐私的问题的,因为它们是针对程序窗口按键缓冲区的,和别的窗口没关系。

    * 动动手指转发出去,以拯救更多的人!!!

  • 相关阅读:
    Java题目详解——LeetCode203. 移除链表元素
    Spring整合RabbitMQ-注解方式
    车联网之电子围栏模型使用翻滚窗口【二十一】
    2022年全球市场混合固态激光雷达总体规模、主要生产商、主要地区、产品和应用细分研究报告
    PostgreSQL LISTEN 与NOTIFY命令
    SpringBoot+Vue实现前后端分离的学生选课系统
    基于C#+MySQL的“零售店”商品销售与管理系统
    第2章 Linux多进程开发 2.18 内存映射
    C语言百日千题系列之《忘情水题》第一日
    单片机之硬件记录
  • 原文地址:https://blog.csdn.net/cjz2005/article/details/126034772