我用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();
}
我移植过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);
}
}
}
二楼的,你的是vc下面的,没什么问题。可在ce下就不行了,真奇怪
楼主问题似乎是这样解决的:
1.同时输出两个字符,可能在输出两字符间没有时间间隔,系统自动做了屏蔽;
2.不能输出数字键,CE下面,如果我没记错的话,数字键你要直接写键值,VK_NUMPAD0并不是真正的数字键键值。