【问题标题】:Arrow Keys as Wide Chars箭头键作为宽字符
【发布时间】:2013-11-01 02:42:53
【问题描述】:

我正在尝试确定是否可以使用箭头键并将它们转换为宽字符。我将 conio.h 用于它的 getch() 函数,我只是喜欢它与类似函数相比的工作方式,并且必须调用它两次才能检索箭头键。

按下箭头键时返回 0xE0 (-32) 作为第一个字符,然后 {Left = 'K', Up = 'H', Right = 'M', Down = 'P'}

所以我一直在尝试找到一种方法将这两个字符合并为一个。这是我想出的最接近的东西。但是,功能键不能与它一起使用,无论按下功能键,它总是返回相同的值。 {F1-12 = 0, Arrows = 224} 我拿出了可信赖的 windows 计算器,能够确定 224 相当于二进制的 -32。我只是把它归结为一个字节并使用十进制系统,然后是 100+124,它是 = -32。

所以也许有人可以帮我弄清楚为什么转换只考虑数组中的第一个字符。我肯定做错了什么。废话不多说,如果是这样的话,抱歉拖了太久,现在这里是代码。

#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <wincon.h>
#include <conio.h>
#include <cwchar>

/**int main()
{
    int N;
    char C;
    wchar_t R;

    while(true)
    {
        while(!kbhit()){}
        //C = getch();

        //if((R == 0) || (R == 224))

        std::cout << R << std::endl;
        N = R;
        std::cout << R << " = " << N << std::endl;
    }
}*/



int main()
{
    int N = 0;
    char C[2];
    wchar_t R;
    mbstate_t mbst;

    while(true)
    {
        mbrlen(NULL,0,&mbst);
        memset(&mbst,0,sizeof(mbst));

        for(int i = 0; i < 2; ++i)
        {
            while(!kbhit()){}
            C[i] = getch();
            N = C[i];
            switch(N)
            {
                case 0:
                    break;
                case -32:
                    break;
                default:
                    //input needs to be converted
                    mbrtowc(&R,C,2,&mbst);
                    N = R;
                    std::cout << R << " = " << N << std::endl;
                    i = 3;
                    break;
            }
        }
    }
}

编辑:

我找到了一种使用联合来组合 2 个字节的方法。我发这个的时候还不知道工会是什么。联合允许我为两种不同的数据类型使用相同的内存空间。它的工作原理在这里 - http://www.cplusplus.com/doc/tutorial/other_data_types/

【问题讨论】:

  • mbrlen(NULL,0,&mbst); - 我认为你根本不需要这个,或者在 memset 之后使用它

标签: c++ visual-c++ arrow-keys widechar


【解决方案1】:

我能够解决我自己的问题,但不是以我一直尝试的方式。如果有人想帮助找出我做错了什么,那就太好了。

然而,就将每个键读取为唯一的 2 字节变量而言,我能够解决问题。我发现了一个关于移位的问题,并用它来组合我的两个字符。然后我发现数字没有正确组合,我发现这是因为我使用的是有符号字符而不是无符号字符。我不想使用无符号字符,所以我找到了一个使用联合的新解决方案。

这是我的联合解决方案。很简单。

#include <iostream>
#include <conio.h> //getch() & kbhit()
#include "rndgen.h"
#define FN_ESCAPE 27
#define FN_UP_ARROW 18656
#define FN_DOWN_ARROW 20704
#define FN_LEFT_ARROW 19424
#define FN_RIGHT_ARROW 19936
                                                                    //This union allows for two 8-bit values to be read as one 16-bit value 
union wide_char
{
    short wide_C;
    char C[2];
};
                                                                    //Function waits for a key to be pressed
inline short key_wait()
{
    wchar_t R;
    wide_char user_input;
    user_input.wide_C = 0;
                                                    //Loop twice, or until code causes the loop to exit
                                                        //Two times are neccessary for function keys unfortunately
    for(int i = 0; i < 2; ++i)
    {
                                                //While there isn't a key pressed, loop doing nothing
        while(!kbhit()){}
                                                //Grab the next key from the buffer
                                                    //Since the loop is done, there must be at least one
        user_input.C[i] = getch();
        switch(user_input.C[i])
        {
            case 0:
            case -32:
                                                //The key pressed is a Function key because it matches one of these two cases
                                                    //This means getch() must be called twice
                                                    //Break switch, run the for loop again ++i
                break;
            default:
                R = user_input.wide_C;
                return R;
                break;
        }
    }
    return -1;
}

wide_C 以 {C[1],C[0]} 的顺序返回 C[2] 的位,这很好,因为这意味着 F1-12 可以唯一读取(F1 的第一个字符返回为 0 -12)它可能会用 wchar_t 替换short,但我想为什么要修复一些没有损坏的东西。当/如果我决定在不同程序的新解决方案中重新实现代码时,我可能会这样做。

这也意味着 a-Z & 0-9 都可以被读取为它们的常规字符值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-19
    • 2011-11-07
    • 2015-11-11
    • 2015-03-15
    • 2022-12-24
    • 1970-01-01
    • 1970-01-01
    • 2010-09-24
    相关资源
    最近更新 更多