当前位置:C++技术网 > 精选软件 > 键盘的扩展键有哪些,用程序检测提取扩展键

键盘的扩展键有哪些,用程序检测提取扩展键

更新时间:2016-01-06 20:31:42浏览次数:1+次

    我们先来看看国际标准键盘有哪些。国际标准键盘一般按照键盘的数量来分,有86键键盘、101键键盘、104键键盘、Win98键盘等四种键盘。
    86键键盘:很早以前的键盘,键盘上有86键;
    101键键盘:将几常用键及数字键分离出来组合成键盘第三区即数字小键盘,这样就有101个键了。
    104键键盘:在Win95推出后,增加三个功能键,它是目前最流行的一种键盘。
    Win98键盘(1096键键盘):这是在Win98操作系统推出后,某些厂家推出的一种新盘。比Win95键盘多5个键,即109键键盘。
    我们大多数用的就是104键键盘。我的键盘就是104个键的键盘,我是真正数了一遍的哦。我这个键盘也就是IBM增强键盘。增强键盘是就是相对于以前很早的键盘来说,增加了很多按键。而这些按键所代表的键码在原来比较少按键的键盘里,是和其他按键键码共享一个物理按键的。独立出来之后,也就更加方便了。这就是扩展键的意思。
    我们想要知道我们的键盘有哪些按键是扩展出来的,可以通过程序来检测,而不需要去记忆,也没有记忆的价值。然而我们了解这个知识也就更加了解键盘了,还是有点必要的。
    在WM_KEYDOWN或者WM_SYSKEYDOWN消息中的lParam参数中有一个位表示当前按键是否为扩展键。通过提取这个按键,如果这个位为1,即表示当前按键为扩展的键,如果为0则不是扩展键。
    那么你会问,检测扩展键有什么用呢?假如你想区别左右两边的Ctrl和Alt,来完成不同的功能,比如在游戏中有两个大炮,按左边的Ctrl控制左边的大炮攻击,而用右边的Ctrl控制右边的大炮。这样可以双手操作了。并且这两个按键是两边分开的,操作起来也很好,名字也一样。
    作用肯定是有的,这是基础知识,用的时候才会感觉需要,学的时候总是思维比较受限制,以为学了没有用。然而你学会了,也不会有坏处,况且我们这里说的明明白白,一看即懂的。你不学会岂不是太不划算了。
    提取扩展键标志的方法还是用宏来得到lParam的高字节部分,然后再用位与操作来提取扩展标志位即可,你可以参考《键盘OEM扫描码深入分析以及OEM扫描码与键盘虚拟键码的关系》。
    下面是提取的代码:
BYTE btHiByte = HIBYTE(HIWORD(lParam));
bool bIsExtendKey = btHiByte&0x01;

    我们用一个布尔值来存储这个位的状态,如果为true则表示是扩展键,否则为非扩展键。下面是程序的运行截图:

检测按键是否为扩展键的效果

检测按键是否为扩展键的效果
    需要注意的是,系统键的检测要在WM_SYSKEYDOWN中进行,一定不要忽略了。
    我检测了一遍,从我的104键键盘中得到了扩展键有下面这些:左右windows键、右面的Alt、右边的Ctrl、右边的菜单键、单独的四个光标键、PageUp、PageDown、Home、End、Insert、Delete、PrintScreen、NumLock数字键盘锁、数字键盘的/、数字键盘的Enter。如果你的键盘和我的不一样,可能得到的结果是不一样的。
    下面是完整的检测扩展键的代码:
#include "windows.h"
#include <tchar.h>
#define MAX 100
TCHAR tip[MAX]=_T("");

// - 项目是Unicode字符集
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    switch (message)
    {
        case WM_PAINT:
            hdc = BeginPaint(hwnd,&ps);
            TextOut(hdc,0,0,tip,lstrlen(tip));
            EndPaint(hwnd,&ps);
            return 0;
        case WM_SYSKEYDOWN:
            {
                BYTE btHiByte = HIBYTE(HIWORD(lParam));
                bool bIsExtendKey = btHiByte&0x01;
                if (bIsExtendKey)
                {
                    wsprintf(tip,_T("此键为扩展键"));
                }
                else
                {
                    wsprintf(tip,_T("此键不是扩展键"));
                }
                InvalidateRect(hwnd,NULL,TRUE);
                return 0;
            }
        case WM_KEYDOWN:
            {
                BYTE btHiByte = HIBYTE(HIWORD(lParam));
                bool bIsExtendKey = btHiByte&0x01;
                if (bIsExtendKey)
                {
                    wsprintf(tip,_T("此键为扩展键"));
                }
                else
                {
                    wsprintf(tip,_T("此键不是扩展键"));
                }
                
                InvalidateRect(hwnd,NULL,TRUE);
                return 0;
            }
        
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        default:
        break;//跳出到默认处理
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev,LPSTR lpCmd,int iShow)
{
    TCHAR ClassName[] = _T("MyClass");
    TCHAR title1[] = _T("C++技术网http://www.cjjjs.com");
    WNDCLASS wndClass;
    wndClass.cbClsExtra=0;
    wndClass.cbWndExtra=0;
    wndClass.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndClass.hCursor=LoadCursor(NULL,IDC_HAND);
    wndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    wndClass.hInstance = hInstance;
    wndClass.lpfnWndProc = WinProc;
    wndClass.lpszClassName = ClassName;
    wndClass.lpszMenuName=NULL;
    wndClass.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClass(&wndClass))return 0;
    HWND hwnd = CreateWindow(ClassName,title1,WS_OVERLAPPEDWINDOW,0,0,650,400,NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,SW_SHOWNORMAL);

    MSG msg;
    while (GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}