CE软键盘的问题

kerode   2009-8-27 14:38 楼主
我用evc4.0写了一个软键盘程序,是基于对话框的,单击按钮模拟按键消息keybd_event,在模拟器上调试一切正常,可拿到2440板子上一试问题就出现了,我的程序A需要输入,可点击软键盘,模拟字符输出a-z,正常应该是两个keydown和keyup,可程序A只接收到一个消息,所以编辑框里没有接收到字符。还有一个问题,模拟数字键,对应的键值是VK_NUMPAD0- VK_NUMPAD9,可在程序A里收到的键值是97-107。但其他的功能键是正常的,比如退格键,回车键,CapsLK等的,真是很奇怪,左思右想就是不知道问题在哪里,下面我把关键代码贴出来,大家帮我看看问题在哪里,多谢了。
BOOL CNumKeyboardDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
HWND wnd = ::GetForegroundWindow();
if(IsWindow(wnd))
{
//如果当前激活窗口不是本程序的窗口
if(wnd != this->m_hWnd)
{
//激活窗口发生了改变
if(m_hFocus != wnd)
{
if(IsWindow(m_hFocus))
{
//释放本进程和gFocus线程的联系
// AttachThreadInput(
// GetWindowThreadProcessId(m_hWnd,NULL),
// GetWindowThreadProcessId(m_hFocus,NULL),
// FALSE);
m_hFocus = ::GetFocus();
}

m_hFocus = wnd;
//使本进程和激活窗口的进程联系起来,接收本进程的按键消息
// AttachThreadInput(
// GetWindowThreadProcessId(m_hWnd,NULL),
// GetWindowThreadProcessId(m_hFocus,NULL),
// TRUE);
}
}
}

return CDialog::PreTranslateMessage(pMsg);
}

void CNumKeyboardDlg::ReleaseFocus()
{
//释放焦点
if(IsWindow(m_hFocus))
{
HWND wnd = ::GetForegroundWindow();
if(IsWindow(wnd))
{
if(wnd == m_hFocus)
{
return;
}
}
//设置保存的焦点窗口处于激活状态
::SetForegroundWindow(m_hFocus);
::SetFocus(m_hFocus);
}

}

void CKeyboardDlg::SendKeyMessage(int vk_code)
{
ReleaseFocus();
if(vk_code >= 'A' && vk_code <= 'Z')
{
/* SHORT nTmp = GetAsyncKeyState(VK_CAPITAL);
if(!(GetKeyState(VK_CAPITAL) && 0xFF))
if(nTmp < 0)
{
keybd_event(VK_CAPITAL,0,0,0);
keybd_event(VK_CAPITAL,0,KEYEVENTF_KEYUP,0);
}
*/
if(m_bPressKeyShift)
keybd_event(VK_SHIFT, 0, 0, 0);

if(!m_bCapsLK)
vk_code += 32;//lowercase
keybd_event(vk_code, 0, KEYEVENTF_SILENT, 0);
keybd_event(vk_code, 0, KEYEVENTF_KEYUP | KEYEVENTF_SILENT, 0);

if(m_bPressKeyShift)
{
keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
m_bPressKeyShift = FALSE;
m_KeyShift.ChangeColor(WHITE_COLOR);
GetDlgItem(IDC_KEY_SHIFT)->SetWindowText(_T("SHIFT"));
}

}
else if(vk_code == VK_LPARENTHESIS || vk_code == VK_RPARENTHESIS)
{
keybd_event(VK_SHIFT , 0, 0, 0);
keybd_event(vk_code, 0, 0, 0);
keybd_event(vk_code, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_SHIFT , 0, KEYEVENTF_KEYUP, 0);
}
else if(vk_code == VK_SHIFT)
{
keybd_event(VK_SHIFT, 0, 0, 0);
keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);

m_KeyShift.ChangeColor(PALEGREEN_COLOR);
m_bPressKeyShift = TRUE;
//m_KeyShift.
}
else if(vk_code == VK_CAPITAL)
{
keybd_event(vk_code, 0, 0, 0);
SHORT ntmp = GetKeyState(VK_CAPITAL); //只能得到VK_CAPITAL 的触发状态,0为大写状态,1为小写状态
keybd_event(vk_code, 0, KEYEVENTF_KEYUP, 0);
char text;
CString strText;
if(ntmp == 0)
{
m_bCapsLK = TRUE;
for(int id = IDC_KEY_A; id <= IDC_KEY_Z; id++)
{
text = 'A' + (id - IDC_KEY_A);
strText = text;
GetDlgItem(id)->SetWindowText(strText);
}
}
else if(ntmp == 1)
{
m_bCapsLK = FALSE;
for(int id = IDC_KEY_A; id <= IDC_KEY_Z; id++)
{
text = 'A' + (id - IDC_KEY_A) + 32;
strText = text;
GetDlgItem(id)->SetWindowText(strText);
}
}

}
else//VK_BACK,,VK_COMMA,VK_PERIOD,VK_ESCAPE,VK_SEMICOLON,VK_SLASH,VK_SPACE,VK_RETURN
{
keybd_event(vk_code, 0, 0, 0);
keybd_event(vk_code, 0, KEYEVENTF_KEYUP, 0);
}
ReleaseFocus();
}

回复评论 (4)

我移植过vc代码,你参照一下
void CDlgKeyBoard::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 CAPSLOCK:    // 0x03
                                vk = VK_CAPITAL;
                                break;
                        case SHIFT:    // 0x04
                                vk = VK_SHIFT;
                                if(GetKeyState(vk) & 0xF000) //shift 已经按下
                                {
                                        vk = VK_CONTROL;
                                        if(GetKeyState(vk) & 0xF000) //ctrl 也按下
                                        {
                                                vk = VK_SHIFT;
                                                keybd_event(vk,0,0,0);
                                        }
                                        vk = VK_SHIFT;
                                        keybd_event(vk,0,KEYEVENTF_KEYUP,0);
                                        return;
                                }
                                uptoo = FALSE;   //保存shift状态
                                break;
                        case CTRL:    // 0x05
                                vk = VK_CONTROL;
                                if(GetKeyState(vk) & 0xF000)   //ctrl已经按下
                                {
                                        vk = VK_SHIFT;
                                        if(GetKeyState(vk) & 0xF000) //shift 也按下
                                        {
                                                vk = VK_CONTROL;
                                                keybd_event(vk,0,0,0);
                                        }
                                        vk = VK_CONTROL;
                                        keybd_event(vk,0,KEYEVENTF_KEYUP,0);
                                        return;
                                }
                                uptoo = FALSE;   //保存ctrl状态
                                break;
                        case BSPACE:    // 0x06
                                vk = VK_BACK;
                                break;
                        case ENTER:    // 0x07
                                vk = VK_RETURN & 0xFF;
                                break;
                        case DEL: //0x14
                                vk = VK_DELETE;
                                break;
                        case SPACE: //0x15
                                vk = VK_SPACE;
                                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 = VKeyScan(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-8-27 15:09
零分你好,零分88
点赞  2009-8-27 15:09
二楼的,你的是vc下面的,没什么问题。可在ce下就不行了,真奇怪
点赞  2009-9-2 16:03
楼主问题似乎是这样解决的:
1.同时输出两个字符,可能在输出两字符间没有时间间隔,系统自动做了屏蔽;
2.不能输出数字键,CE下面,如果我没记错的话,数字键你要直接写键值,VK_NUMPAD0并不是真正的数字键键值。
点赞  2009-9-9 13:30
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复