【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 5360|回复: 4

一个VC++屏幕软键盘程序代码

[复制链接]
发表于 2009-3-1 02:01:47 | 显示全部楼层 |阅读模式

在网络游戏中,或银行密码输入时,为确保密码安全,很多时候采用屏幕软键盘。

一个VC++屏幕软键盘程序代码

一个VC++屏幕软键盘程序代码


首先定义链表保存按键值:
    CTypedPtrList<CPtrList, KEYDEF*> cKeys
这里是采用MFC的PtrList实现的,当然如果用stl的list就更好了。

分别添加键盘中的按键如下:
    //control row
    AddKey(0x00,0x00,0); //signal row change
    AddKey(0x00,ESC,10);
    for(int fnkey = 0x70; fnkey < 0x7C; fnkey++)
    {
        AddKey(0x00,fnkey & 0xFF,10);
    }
    AddKey(0x00,INS,14);
    AddKey(0x00,DEL,-10);

    //first row
    AddKey(0x00,0x00,1); //signal row change
    AddKey('`','~',10);
    AddKey('1','!',10);
    AddKey('2','@',10);
    AddKey('3','#',10);
    AddKey('4','$',10);
    AddKey('5','%',10);
    AddKey('6','^',10);
    AddKey('7','&',10);
    AddKey('8','*',10);
    AddKey('9','(',10);
    AddKey('0',')',10);
    AddKey('-','_',10);
    AddKey('=','+',10);
    AddKey(0x00,BSPACE,14); //backspace
    AddKey(0x00,PUP,-12);

    //second row
    AddKey(0x00,0x00,2); //signal row change
    AddKey(0x00,TAB,14); //tab
    AddKey('q','Q',10);
    AddKey('w','W',10);
    AddKey('e','E',10);
    AddKey('r','R',10);
    AddKey('t','T',10);
    AddKey('y','Y',10);
    AddKey('u','U',10);
    AddKey('i','I',10);
    AddKey('o','O',10);
    AddKey('p','P',10);
    AddKey('[','{',10);
    AddKey(']','}',10);
    AddKey('\\','|',10);
    AddKey(0x00,PDN,-12);

    //third row
    AddKey(0x00,0x00,3); //signal row change
    AddKey(0x00,CAPSLOCK,18); //caps lock
    AddKey('a','A',10);
    AddKey('s','S',10);
    AddKey('d','D',10);
    AddKey('f','F',10);
    AddKey('g','G',10);
    AddKey('h','H',10);
    AddKey('j','J',10);
    AddKey('k','K',10);
    AddKey('l','L',10);
    AddKey(';',':',10);
    AddKey('\'','\"',10);
    AddKey(0x00,ENTER,16); //enter
    AddKey(0x00,HOME,-10);

    //fourth row
    AddKey(0x00,0x00,4); //signal row change
    AddKey(0x00,SHIFT,22); //shift
    AddKey('z','Z',10);
    AddKey('x','X',10);
    AddKey('c','C',10);
    AddKey('v','V',10);
    AddKey('b','B',10);
    AddKey('n','N',10);
    AddKey('m','M',10);
    AddKey(',','<',10);
    AddKey('.','>',10);
    AddKey('/','?',10);
    AddKey(0x00,SHIFT,22); //shift
    AddKey(0x00,END,-10);

    //fifth row
    AddKey(0x00,0x00,5); //signal row change
    AddKey(0x00,CTRL,12); //ctrl
    AddKey(0x00,WINDOW,12); //window
    AddKey(0x00,ALT,12); //alt
    AddKey(' ',' ',60);
    AddKey(0x00,LEFT,12); //left
    AddKey(0x00,UP,12); //up
    AddKey(0x00,DOWN,12); //down
    AddKey(0x00,RIGHT,12); //right
    AddKey(0x00,WWW,-10); //http://WWW

    CalcWidthHeight();

画键盘函数如下:
void COnscreenKeyboardDlg:rawKeyboard()
{
    CClientDC dc(this);
    CRect client;
    GetClientRect(client);
    CRgn clipRgn;
    clipRgn.CreateRectRgnIndirect(&client);
    dc.SelectClipRgn(&clipRgn);
    dc.SelectObject(GetStockObject(DEFAULT_GUI_FONT));
    dc.SetBkMode(TRANSPARENT);
    int x = 0;
    int y = -pKeyHeight;
    KEYDEF * key;
    OSITION pos = cKeys.GetHeadPosition();
    cCurrentKeyState = DescribeKeyState();
    int state = cCurrentKeyState;
    while(pos)
    {
        key = cKeys.GetNext(pos);
        if((key->cNormal == 0x00) && (key->cShifted == 0x00))
        {
            x = 0;
            y += pKeyHeight;
        }
        else
        {
            int width = ((abs(key->cWidth) * pKeyWidth) / 10);
            CRect rc(x,y,x + width, y + pKeyHeight);
            x += width;
            if(key->cWidth < 0)
            {
                rc.right = client.right;
            }
            BOOL hilight = FALSE;
            if(key->cNormal == 0x00)
            {
                switch(key->cShifted)
                {
                case CAPSLOCK:
                    if(state & 0x01)
                    {
                        hilight = TRUE;
                    }
                    break;
                case SHIFT:
                    if(state & 0x02)
                    {
                        hilight = TRUE;
                    }
                    break;
                case CTRL:
                    if(state & 0x04)
                    {
                        hilight = TRUE;
                    }
                    break;
                default:
                    break;
                }
            }
            DrawKey(&dc, rc, key, hilight);
        }
    }
}
一张帖子贴不完,楼下继续贴...

 楼主| 发表于 2009-3-1 02:02:59 | 显示全部楼层

当鼠标在按键所在区域点击,即模拟按键:
void COnscreenKeyboardDlg::SendKey(KEYDEF * keydef)
{
    if(keydef->cNormal == 0x00)
    {
        int vk;
        BOOL uptoo = TRUE;
        if(keydef->cShifted > 0x6F) //is a function key
        {
            vk = keydef->cShifted;
        }
        else
        {
            switch(keydef->cShifted)
            {
            case TAB:    // 0x02
                vk = VkKeyScan(0x09) & 0xFF;
                break;
            case CAPSLOCK:    // 0x03
                vk = VK_CAPITAL;
                break;
            case SHIFT:    // 0x04
                vk = VK_SHIFT;
                if(GetKeyState(vk) & 0xF000) return;
                uptoo = FALSE;
                break;
            case CTRL:    // 0x05
                vk = VK_CONTROL;
                if(GetKeyState(vk) & 0xF000) return;
                uptoo = FALSE;
                break;
            case BSPACE:    // 0x06
                vk = VK_BACK;
                break;
            case ENTER:    // 0x07
                vk = VkKeyScan(0x0D) & 0xFF;
                break;
            case ALT:    // 0x08
                vk = VK_MENU;
                break;
            case WINDOW:    // 0x9
                vk = VK_LWIN;
                break;
            case LEFT:    // 0x0A
                vk = VK_LEFT;
                break;
            case RIGHT:    // 0x0B
                vk = VK_RIGHT;
                break;
            case UP:    // 0x0C
                vk = VK_UP;
                break;
            case DOWN:    // 0x0D
                vk = VK_DOWN;
                break;
            case PUP: //0x0F
                vk = VK_PRIOR;
                break;
            case PDN: //0x10
                vk = VK_NEXT;
                break;
            case HOME: //0x11
                vk = VK_HOME;
                break;
            case END: //0x12
                vk = VK_END;
                break;
            case INS: //0x13
                vk = VK_Insert;
                break;
            case DEL: //0x14
                vk = VK_Delete;
                break;
            case WWW:
                KEYDEF key;
                key.cNormal = key.cShifted = 'H';
                SendKey(&key);
                key.cNormal = key.cShifted = 'T';
                SendKey(&key);
                SendKey(&key);
                key.cNormal = key.cShifted = 'P';
                SendKey(&key);
                key.cNormal = key.cShifted = ':';
                SendKey(&key);
                key.cNormal = key.cShifted = '/';
                SendKey(&key);
                SendKey(&key);
                key.cNormal = key.cShifted = 'W';
                SendKey(&key);
                SendKey(&key);
                SendKey(&key);
                vk = VkKeyScan('.') & 0xFF;
                break;
            default:
                ASSERT(FALSE);
                break;
            }
        }
        keybd_event(vk,0,0,0);
        if(uptoo)
        {
            keybd_event(vk,0,KEYEVENTF_KEYUP,0);
        }
    }
    else
    {
        char pChar = keydef->cNormal;
        SHORT ks = VkKeyScan(pChar);
        BYTE key = ks & 0xFF;

        keybd_event(key,0,0,0);
        keybd_event(key,0,KEYEVENTF_KEYUP,0);

        //turn off the control and shift if they were down
        unsigned char vk = VK_SHIFT;
        if(GetKeyState(vk) & 0xF000)
        {
            keybd_event(vk,0,KEYEVENTF_KEYUP,0);
        }
        vk = VK_CONTROL;
        if(GetKeyState(vk) & 0xF000) //allow toggle
        {
            keybd_event(vk,0,KEYEVENTF_KEYUP,0);
        }
    }
}

具体细节请参见相关代码。
点击下载此文件
发表于 2009-3-10 12:56:55 | 显示全部楼层
鼠标位置的获取
发表于 2009-11-26 14:34:22 | 显示全部楼层
[BR]好人啊!收了先
发表于 2009-11-26 14:34:22 | 显示全部楼层
[BR]好人啊!收了先
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2025-6-25 10:59

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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