在函数中调用onkeydown?---急---

nostopping 2008-11-22 01:47:57
有两个消息处理函数:ontimer和onkeydown.如何让程序在响应ontimer时调用一下onkeydown查看当前有没有按键消息,即如何在ontimer中调用onkeydown消息处理函数?
...全文
857 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
nostopping 2008-11-25
  • 打赏
  • 举报
回复
好了,问题解决了.
我在ontimer里面用GetQueueStatus(QS_KEY)检查当前消息队列中的消息状况,然后再添加一个OnKeyDown(),用于处理在两个ontimer事件之间时的按键.以后如果只检查有没有按键而不对消息进行处理的话,最好用GetQueueStatus(QS_KEY).
谢谢上面的朋友!
yjgx007 2008-11-22
  • 打赏
  • 举报
回复
cnzdgs已经说的很清楚了,我再举个例子:
你按下A键 (key down),并马上弹回去(key up),很不凑巧,在Key down的时候,你的OnTimer函数没有被执行,因此,你无法得知key down,为什么没有被执行呢?
这是系统I/O中断所决定的,定时事件和键盘事件不可能同时并发作出响应处理,必须有一个中断优先级。如果你非要按这种思路去做,并且,系统可以并发处理OnTimer和key down,你就真的能保证OnTimer能在某一时刻及时捕捉到这个时刻的键盘动作吗?

如果你知道窗口消息的处理机制,每个窗口(对话框也是窗口)会有一个窗口过程函数WindowProc,里面处理相关的消息,当键盘消息key down到达窗口后,你处理这个消息即可,在CWnd中,封装了WindowProc的处理过程,并且会有一个PreProcessMessage的重载函数给你,你在里面处理WM_KEYDOWN即可。
cnzdgs 2008-11-22
  • 打赏
  • 举报
回复
如果要检查有没有键按下,可以用PeekMessage函数。但实际上是不需要检查的,键盘消息的优先级高于定时消息,就是说当程序从消息队列中取消息时,如果有键盘消息,是不会取出定时消息的。如果你的OnTimer函数需要执行很长时间,应该用一个单独的线程来处理。
study_live 2008-11-22
  • 打赏
  • 举报
回复
用keybd_event函数可模拟键盘输入, 可上MSDN上找下这个函数的用法
jinlingzwp 2008-11-22
  • 打赏
  • 举报
回复
在pretranslatemessage中响应
lwx300 2008-11-22
  • 打赏
  • 举报
回复
void CbutDlg::OnTimer(UINT_PTR nIDEvent)
{
MSG msg;
if (::PeekMessage(&msg, m_hWnd, WM_KEYDOWN, WM_KEYDOWN, PM_NOREMOVE))
{
Flag = true;
}

if (!Flag)
{
//do something
}

CDialog::OnTimer(nIDEvent);
}
wltg2001 2008-11-22
  • 打赏
  • 举报
回复
;然后在ontimer的处理函数中判断Flag的值,看看当前是否有键被按下过,我发现有时候系统onkeydown的响应比ontimer慢,
===============================
你弄错了一个问题,当OnTimer在执行时,就是你按了键,也不会马上触发OnKeyDown的,消息处理函数正在处理OnTimer时又怎么会同时处理按键呢?
至于上面所说的中OnTimer中调用OnKeyDown就更是胡说了,你的目的是检测键是否按下去了,不是对按下键之后进行处理,如果你真的在OnTimer中调用OnKeyDown,即使没有按键,也会当作你按了键一样.
nostopping 2008-11-22
  • 打赏
  • 举报
回复
void CInvokeOnKeyDownDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default

AfxMessageBox("key down");
CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CInvokeOnKeyDownDlg::OnBnClickedOk()
{
// TODO: Add your control notification handler code here

OnKeyDown();
}

提示: error C2660: 'CInvokeOnKeyDownDlg::OnKeyDown' : function does not take 0 arguments
nostopping 2008-11-22
  • 打赏
  • 举报
回复
直接调用onkeydown(),不用传参数吗?
etz2008 2008-11-22
  • 打赏
  • 举报
回复
bool Flag = false;
void CbutDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{

Flag = true;
CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CbutDlg::OnTimer(UINT_PTR nIDEvent)
{
//能不能在这儿先调用onkeydown,再执行下面的代码?
//要确保在有键被按下时首先被onkeydown处理,即把Flag设为true

if (!Flag)
{
//do something
}
CDialog::OnTimer(nIDEvent);
}

可以
一条晚起的虫 2008-11-22
  • 打赏
  • 举报
回复
OnTimer()
{
OnKeyDown(); //类成员函数,直接掉用。
}
nostopping 2008-11-22
  • 打赏
  • 举报
回复
先介绍下我的程序(基于对话框的单文档程序):
有一个全局变量比如Flag,当响应onkeydown的时候让Flag=true;然后在ontimer的处理函数中判断Flag的值,看看当前是否有键被按下过,我发现有时候系统onkeydown的响应比ontimer慢,ontimer是50毫秒响应一次,我把这个值改为500毫秒也会出现上面的问题(出于程序的效率考虑,不能比这个值再大了).
所以我想在触发ontimer的时候让系统查看一下有没有按键信息(Flag是不是为true),这样当按下按键时,就不会出现先判断Flag而后再响应onkeydown了,代码如下:

bool Flag = false;
void CbutDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{

Flag = true;
CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CbutDlg::OnTimer(UINT_PTR nIDEvent)
{
//能不能在这儿先调用onkeydown,再执行下面的代码?
//要确保在有键被按下时首先被onkeydown处理,即把Flag设为true

if (!Flag)
{
//do something
}
CDialog::OnTimer(nIDEvent);
}
liyinlei 2008-11-22
  • 打赏
  • 举报
回复
同1楼,只要在OnKeyDown里做相应处理就行了。
wltg2001 2008-11-22
  • 打赏
  • 举报
回复
同楼上,程序是由消息触发的/
xsc2001 2008-11-22
  • 打赏
  • 举报
回复
判断有没有按键消息不用在OnTimer里调用onkeydown,也用不着OnTimer呀,只要系统中的按键消息了onkeydown自然就响应了,也就能够即时知道。这样在onkeydown添加处理代码即可,一旦按键消息就通知你的系统即可。

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧