| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6050 人关注过本帖
标题:Edit框响应回车键的问题
只看楼主 加入收藏
daisyzhou45
Rank: 1
等 级:新手上路
帖 子:75
专家分:0
注 册:2006-2-10
收藏
 问题点数:0 回复次数:7 
Edit框响应回车键的问题

如题:我在单文档FormView模式的主窗口里设置了一些Edit框,如果要在按回车键时跳到下一个控件,比如说下一个Edit框,也就时说要响应回车键,在响应函数里设置SetFocus去下一个控件,如何弄?
还有一个问题:怎样获得指向一个窗口的指针,比如说主窗口。它是一个类,我要其它的类里访问里面的一些成员是不是必须得获得指向这个类的指针?

搜索更多相关主题的帖子: 回车键 Edit 
2006-04-15 22:31
myajax95
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:30
帖 子:2978
专家分:0
注 册:2006-3-5
收藏
得分:0 
好像edit box没什么好的message handler能管回车, 用EN_CHANGE可以但是写出来的逻辑太难看了。
不如给你的FormView class 加个WM_KEYDOWN的message handler。
C....View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (现在的focus 在edit box 上而且nChar 是回车)
setfocus (...)
}

窗口的指针获得的方法一般是在窗口初始化是当参数传进去的,例如定义一个CDialog class
C..Dialog(CWnd* pParent), 这个pParent就可以在Dialog生成的时候传进去,一般是生成这个窗口的父窗口。

但你用的单文档还有一套更加系统的管理,叫document/view architeure(不知怎么翻译),document class, view class, frame class,和app class都有定义好的互相访问的方法。比用指针指来指去的要方面得多。

http://myajax95./
2006-04-16 02:45
daisyzhou45
Rank: 1
等 级:新手上路
帖 子:75
专家分:0
注 册:2006-2-10
收藏
得分:0 
主窗口上有很多Edit控件,通过OnKeyDown这个函数我是不是可以根据Table键的先后顺序来设置下一个Focus的控件?
在其它的按钮上,回车键相当于鼠标按下按钮,我试了一个,在onKeyDown这个程序里加了个MessageBox,可是没有反应,不知道是为什么?

2006-04-16 16:38
daisyzhou45
Rank: 1
等 级:新手上路
帖 子:75
专家分:0
注 册:2006-2-10
收藏
得分:0 
void CTV_WALLView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// if(nChar =='\r')
MessageBox("Hello");



CFormView::OnKeyDown(nChar, nRepCnt, nFlags);
}


2006-04-16 16:45
maoguoqing
Rank: 6Rank: 6
来 自:重庆
等 级:贵宾
威 望:28
帖 子:2980
专家分:19
注 册:2005-12-5
收藏
得分:0 

对于回车,可以用缺省按扭的响应函数来处理,可以在其响应函数中用GetNextDlgTabItem(GetFocus())->
SetFocus()来实现,具体意思看MSDN.如果程序中还没有缺省按扭的响应函数,可以先添加一个OK按扭,将
它的ID号设为IDOK,然后增加它的处理函数,再把这个OK按扭删掉。函数的具体意思看MSDN.

怎样获得指向一个窗口的指针,比如说主窗口。它是一个类,我要其它的类里访问里面的一些成员是不是必须得获得指向这个类的指针?
AfxGetApp()获得指向应用程序对象的指针;
AfxGetMainWnd()获得指向主框架窗口的指针;这两个是全局的,在任何地方都可以用。
CFrameWnd::GetActiveView();获得指向视图类对象的指针;
Cview::GetDocument();获得指向文档类对象的指针;
..........
CWnd::GetParent();获得指向父窗口的指针;

CWnd::GetWindow();
CWnd::GetNextWindow();
CWnd::GetNextDlgTabItem();均是获取窗口指针,具体用法自己看MSDN吧。


天行健,君子以自强不息!!QQ:68660681
2006-04-16 21:18
myajax95
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:30
帖 子:2978
专家分:0
注 册:2006-3-5
收藏
得分:0 
十分抱歉,二楼的方法错误,FormView 或者 CDialog 不会把OnKeyDown信息传给edit box。
楼上的方法是对CDialog的正解,不过在FormView上试了一下,好像不行,可能是因为FormView本身的style就是child的原因。
楼主最好在请教高人寻找正解,如果找到,麻烦告诉我。目前只能想出个土办法:
假设你的edit box 叫 IDC_EDIT1,对应的变量叫m_strAll。把edit box的属性里选multi-line和want return。给你的edit box 加ON_EN_UPDATE的信息:
void CForm1View::OnUpdateEdit1()
{
int intPos;
UpdateData();
while ((intPos = m_strAll.Find("\r\n")) >= 0)
{
m_strAll = m_strAll.Left(intPos) + m_strAll.Right(m_strAll.GetLength() - intPos - 2);
UpdateData(FALSE);
GetNextDlgTabItem(GetFocus())->SetFocus();
}
}

http://myajax95./
2006-04-17 02:52
浪漫冰块
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2006-4-21
收藏
得分:0 

  二、不能响应回车键的原因分析

  之所以在以CEditView作为基类的程序中可以响应回车键,是由于该程序的视类本身就是一个Edit控件,这就是问题的关键所在。CEditView作为CView的派生类能响应从键盘输入的各种消息,其中有和键盘输入相关的WM_CHAR、WM_KEYDOWN、WM_KEYUP等消息。我们就可以在这些消息的响应函数中灵活地设计程序去捕捉到回车键的输入,并执行响应的操作。

  当我们将编辑框作为一个普通的控件放到对话框上时情况就发生了变化。在此我们以CFormView为例,它也是CView的一个派生类,视是一个Form窗体(即对话框),当放有编辑框的窗体有回车键输入时,由于只有编辑框可以接受从键盘输入的字符,所以当键盘按下时统统把消息都发给了编辑框(在Windows下每个窗口、按钮、编辑框都看作一个窗口,都可以接受消息),可以通过ClassWizard在"Object IDs"选中编辑框所对应的ID号,在右边的消息框中可以看出该编辑框并不能响应WM_CHAR等消息,只能用EN_CHANGE事件来做类似的响应。可当我们加入了对该事件的处理函数时,却又将回车键当作控制字符,当输入回车键并不会激发EN_CHANGE事件,也就是说用这种方法仍旧无法捕获回车键的输入。

  三、拦截回车键的思路与方法

  Windows操作系统下各个窗口、控件归根结底都是通过系统的各种各样的消息来相互协调、相互联系的,而我们所遇到的这个问题换到消息的角度说就是"如何使程序能响应在编辑框上输入的回车键所发出的消息",只要能响应到这个消息,剩下的工作都可以在消息处理函数中完成。所以有必要对Windows系统的消息机制做些了解。

  每个Windows应用程序开始执行后,Windows都为该程序创建一个"消息队列(message queue)",用来存放邮寄给该程序可能创建的各种不同窗口的消息。消息队列中消息的结构(MSG)为:

typedef struct tagMSG{
 /*msg*/
 HWND hwnd;//窗口句柄,标识接收消息的窗口。
 UINT message;//消息标识号,如WM_TIMER等。
 WPARAM wParam;//消息参数,当为键盘消息时,表示虚拟键码如VK_RETURN等。
 LPARAM lParam;//消息参数。
 DWORD time;//邮寄消息的时间。
 POINT pt;//邮寄消息时的光标位置,用屏幕坐标表示。
}MSG;

  在系统下最常用的消息循环是调用GetMessage()函数从消息队列中取出消息,然后调用DespatchMessage() 函数让系统把消息发送给窗口函数,一般情况下其结果是把窗口的所有消息都传送给窗口函数。但特殊情况下可以在GetMessage()函数获得消息而又没发送出去之前,通过TranslateMessage()函数可以中途对消息进行解析,可以对指定的消息进行拦截,拦截后即可以照样发送出去,也可以不继续发送,完成对该消息的拦截,下面代码是该过程的示例:

MSG msg;
while(GetMessage(&msg,NULL,NULL,NULL,NULL){
 TranslateMessage(&msg);
 …… //对拦截的消息进行处理
 DispathchMessage(&msg);
}

  由于按下回车键时把产生的消息加入到消息队列中了,也传给了编辑框,但仅仅是由于编辑框没有能力处理该消息而造成了无法对回车键的响应,所以可以在消息循环里在把消息发送到编辑框之前就对消息进行拦截,并对其进行处理。其效果同编辑框响应回车键是一样的,仅在时序上有所提前而已。上述代码是在SDK(Software Develope Kits)下使用的,在MFC(Microsoft Foundation Class)下早已对其进行了封装,可以通过重载虚函数PreTranslateMessage()对所关心的消息进行解析:

BOOL CTestView::PreTranslateMessage(MSG* pMsg)
{
 if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST)
 {
  if(pMsg->wParam==VK_RETURN )
  {
   UpdateData(TRUE);

2006-04-21 18:17
myajax95
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:30
帖 子:2978
专家分:0
注 册:2006-3-5
收藏
得分:0 
1。楼主问的不是Editvew是Formview。
2。不该用EN_CHANGE,而该用EN_UPDATE,试一下就知道其区别。
3。让PreTranslateMessage来管这事不是不可以,不过这种在这么通用的函数里hard code一个对只管回车键回车的if,个人觉得这个程序风格实在不值得推荐。几乎可以预见这么写下去如果软件越写越大,这个PreTranslateMessage不知要加多少的if else。

http://myajax95./
2006-04-22 13:28
快速回复:Edit框响应回车键的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020606 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved