CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

关于dialog和控件回车键消息处理的小问题

楼主brows(眉头)2001-12-14 18:37:01 在 VC/MFC / 基础类 提问

我在一个dialog上放了一个CTreeCtrl(设置为可编辑),在一个tree   item上编辑后想回车确定,但是这个回车被dialog的OnOK()处理了,如果去掉这个OnOK(),dialog就直接退出了。现在我想做的是:按下回车键时,  
  1、如果当前正在编辑tree   item,能得到TVN_ENDLABELEDIT通知消息  
  2、否则才调用OnOK()。  
   
  另:如果从CTreeCtrl派生一个子类,怎样才能对话框资源编辑里画的那个CTreeCtrl直接联系起来? 问题点数:30、回复次数:11Top

1 楼ghz(冰河)回复于 2001-12-14 18:40:56 得分 6

1、重载OnOk,不要返回CDialog::的OnOK,向CTreeCtrl发ENDLABELEDIT的消息就行了  
   
  2、给那个控件加个Control型的变量,用你的新类Top

2 楼jiangsheng(蒋晟.Net[MVP])回复于 2001-12-14 18:41:16 得分 15

BUG:   ESC/ENTER   Keys   Do   Not   Work   When   Editing   CTreeCtrl   Labels    
  ID:   Q167960    
   
   
  --------------------------------------------------------------------------------  
  The   information   in   this   article   applies   to:  
   
  Microsoft   Visual   C++,   32-bit   Editions,   versions   2.0,   2.1,   2.2,   4.0,   4.0a,   4.1,   4.2,   4.2b,   5.0,   6.0  
   
  --------------------------------------------------------------------------------  
   
   
  SYMPTOMS  
  When   you   edit   labels   in   a   CTreeCtrl,   you   are   allowed   to   press   the   ESC   key   to   cancel   the   changes   or   press   the   ENTER   key   to   accept   the   changes.   However,   when   the   CTreeCtrl   is   a   child   window   of   a   dialog   box   (CDialog),   a   formview   window   (CFormView),   or   a   property   page   (CPropertyPage),   the   ESC   or   ENTER   keys   do   not   function   as   expected.    
   
   
   
  CAUSE  
  IsDialogMessage()   function   is   called   in   the   PreTranslateInput()   function   which   in   turn   is   called   in   the   PreTranslateMessage()   function   of   all   CFormView   or   CDialog   derived   classes   mentioned   above.   The   ESC   and   ENTER   keys   are   processed   in   IsDialogMessage()   but   are   not   passed   on   to   the   edit   control   created   by   the   tree-view   control.   Thus,   these   keystrokes   have   no   effect.    
   
   
   
  RESOLUTION  
  For   Visual   C++   4.xx   and   later,   we   can   trap   the   ESC   and   ENTER   keystroke   messages   in   the   PreTranslateMessage()   function   for   all   CFormView,   CDialog   (modal   or   modeless)   and   CPropertyPage   (either   in   modal   or   modeless   CPropertySheet)   derived   classes.    
   
  In   the   code   below,   m_TreeCtrl   is   a   member   variable   of   those   derived   classes   and   it   is   of   CTreeCtrl   data   type,   and   CMyXxx   can   be   any   CFormView,   CDialog,   or   CPropertyPage   derived   class.    
   
   
   
        BOOL   CMyXxx::PreTranslateMessage(MSG*   pMsg)  
        {  
              //   If   edit   control   is   visible   in   tree   view   control,   when   you   send   a  
              //   WM_KEYDOWN   message   to   the   edit   control   it   will   dismiss   the   edit  
              //   control.   When   the   ENTER   key   was   sent   to   the   edit   control,   the  
              //   parent   window   of   the   tree   view   control   is   responsible   for   updating  
              //   the   item's   label   in   TVN_ENDLABELEDIT   notification   code.  
              if   (pMsg->message   ==   WM_KEYDOWN   &&  
                    pMsg->wParam   ==   VK_RETURN   ||   pMsg->wParam   ==   VK_ESCAPE)  
              {  
                    CEdit*   edit   =   m_TreeCtrl.GetEditControl();  
                    if   (edit)  
                    {  
                          edit->SendMessage(WM_KEYDOWN,   pMsg->wParam,   pMsg->lParam);  
                          return   TRUE;  
                    }  
              }  
              //   CXxxx   can   be   a   CFormView,   Cdialog,   or   CPropertyPage   class.  
              return   CXxxx::PreTranslateMessage(pMsg);  
        }    
  For   Visual   C++   2.xx,   since   PreTranslateMessage()   is   not   called   for   modal   CDialog-derived   classes,   the   sample   code   above   does   not   apply   to   the   modal   dialog   and   property   page   in   a   modal   CPropertySheet   derived   class.   In   this   situation,   those   keystroke   messages   can   be   trapped   in   the   overridden   OnOK()   (for   Enter   key)   and   OnCancel()   (for   Esc   key)   functions   in   either   CDialog   or   CPropertySheet   derived-class.   The   sample   code   works   fine   even   in   the   absence   of   both   the   OK   and   Cancel   buttons   from   the   dialog   resource   template.    
   
  NOTE:   It   is   too   late   to   trap   those   keystroke   messages   in   CPropertyPage's   OnOK()   and   OnCancel()   functions.   Therefore,   we   have   to   do   it   in   CPropertySheet-derived   class.    
   
  A   new   member   function   called   IsTreeCtrlEditMessage()   is   added   to   the   CDialog   or   CPropertySheet   derived-class.   This   function   sends   a   WM_KEYDOWN   message   to   the   tree-view's   edit   control   when   it   is   the   window   with   focus.   And   it   is   being   called   in   both   overridden   OnOK()   and   OnCancel()   functions.   The   CMyDxxx   in   the   sample   code   below   can   either   be   a   CDialog   or   a   CPropertySheet   derived-class.   Note   that   the   MODAL_PROPERTYSHEET   constant   is   declared   and   used   in   IsTreeCtrlEditMessage()   so   the   same   code   can   be   applied   to   both   CDialog   and   CPropertySheet   derived-classes.    
   
        //   Set   MODAL_PROPERTYSHEET   to   1   for   modal   CPropertySheet-derived   class  
        //   and   0   for   CDialog-derived   class.  
        #define   MODAL_PROPERTYSHEET     1  
   
        BOOL   CMyDxxx::IsTreeCtrlEditMessage(WPARAM   KeyCode)  
        {  
              BOOL               rvalue   =   FALSE;  
   
              //   pWnd   is   a   pointer   to   either   an   active   CPropertyPage   of   the   modal  
              //   CPropertySheet   or   a   modal   CDialog   object.  
              CWnd*       pWnd   =   this;  
        #if   MODAL_PROPERTYSHEET  
              pWnd   =   GetActivePage();  
        #endif  
   
              //   IDC_TREECTRL   is   the   ID   of   the   tree   view   control.  
              CTreeCtrl   *treectrl   =   (CTreeCtrl   *)   pWnd->GetDlgItem(IDC_TREECTRL);  
              if   (!treectrl)  
                    return   rvalue;  
   
              //   If   the   edit   control   of   the   tree   view   control   has   the   input   focus,  
              //   sending   a   WM_KEYDOWN   message   to   the   edit   control   will   dismiss   the  
              //   edit   control.     When   ENTER   key   was   sent   to   the   edit   control,   the  
              //   parentwindow   of   the   tree   view   control   is   responsible   for   updating  
              //   the   item's   label   in   TVN_ENDLABELEDIT   notification   code.  
              CWnd*     focus   =   GetFocus();  
              CEdit*   edit     =   treectrl->GetEditControl();  
              if   ((CEdit   *)   focus   ==   edit)  
              {  
                    edit->SendMessage(WM_KEYDOWN,   KeyCode);  
                    rvalue   =   TRUE;  
              }  
              return   rvalue;  
        }  
   
        void   CMyDxxx::OnOK()  
        {  
              //   Do   not   dismiss   the   dialog   object   if   ENTER   key   was   sent   to   the   tree  
              //   view's   edit   control.     You   may   call   the   CDialog::OnOK()   function   if  
              //   this   is   for   CDialog.  
              if   (!IsTreeCtrlEditMessage(VK_RETURN))  
                    EndDialog(IDOK);  
        }  
   
        void   CMyDxxx::OnCancel()  
        {  
              //   Do   not   dismiss   the   dialog   object   if   ESC   key   was   sent   to   the   tree  
              //   view's   edit   control.     You   might   call   the   CDialog::Cancel()  
              //   function   if   this   is   for   CDialog.  
              if   (!IsTreeCtrlEditMessage(VK_ESCAPE))  
                    EndDialog(IDCANCEL);  
        }    
   
   
   
  STATUS  
  Microsoft   has   confirmed   this   to   be   a   bug   in   the   Microsoft   products   listed   at   the   beginning   of   this   article.    
   
   
   
  MORE   INFORMATION  
  For   more   information   about   CTreeCtrl,   please   refer   to   the   MFC   online   help   and   Win32   SDK   help   files.    
   
   
   
  REFERENCES  
  For   additional   information,   please   see   the   following   article   in   the   Microsoft   Knowledge   Base:    
   
  Q130691   BUG:   ESC/ENTER   Keys   Don't   Work   When   Editing   Labels   in   TreeView    
  (c)   Microsoft   Corporation   1997,   All   Rights   Reserved.   Contributions   by   Yeong-Kah   Tam,   Microsoft   Corporation    
  ©   Microsoft   Corporation   1997,   All   Rights   Reserved.  
  Contributions   by   Yeong-Kah   Tam,   Microsoft   Corporation  
   
   
  Additional   query   words:    
   
  Keywords   :   kbui   kbMFC   kbTreeView   KbUIDesign   kbVC   kbVC200bug   kbVC210bug   kbVC220bug   kbVC400bug   kbVC410bug   kbVC420bug   kbVC500bug   kbVC600bug   kbGrpMFCATL    
  Version   :   winnt:2.0,2.1,2.2,4.0,4.0a,4.1,4.2,4.2b,5.0,6.0    
  Platform   :   winnt    
  Issue   type   :   kbbug    
  Technology   :   kbvc    
   
   
  Last   Reviewed:   March   6,   2000  
  ©   2000   Microsoft   Corporation.   All   rights   reserved.   Terms   of   Use.  
     
   
   
   
  --------------------------------------------------------------------------------  
  Send   feedback   to   MSDN.Look   here   for   MSDN   Online   resources.   Top

3 楼wkgenius()回复于 2001-12-14 18:55:34 得分 3

重载PreTranslateMessage函数,将WM_RETURN消息截获,然后发给那个控件。  
  或者直接将它的属性设为Default也行。Top

4 楼sgr0426()回复于 2001-12-14 19:19:54 得分 3

用subclassdlg(),可以解决你的类与资源相连系的问题Top

5 楼brows(眉头)回复于 2001-12-14 19:37:34 得分 0

多谢。  
  to   ghz(浪子)/wkgenius:  
  在OnOK()或PreTranslateMessage(),里怎么知道当前是否在编辑treeitem?  
  怎么处理escape也是同样的问题。Top

6 楼wangao88(呆子)回复于 2001-12-14 19:39:14 得分 0

重载PreTranslateMessage函数,将WM_RETURN消息截获,然后发给那个控件。  
  或者直接将它的属性设为Default也行。   Top

7 楼bluecrest(高歌)回复于 2001-12-14 19:50:25 得分 3

在dialog相关的那个类中  
  把派生mytreectrl成员捆绑倒那个nid上  
  (在member   variable标签下add   variable)Top

8 楼brows(眉头)回复于 2001-12-14 20:13:48 得分 0

照jiangsheng(蒋晟)的例子解决了第一个问题。Top

9 楼woodswoods(woodswoods)回复于 2001-12-14 20:37:32 得分 0

1.去掉对话框中按钮的DEFAULT属性,敲回车就不会直接退出了.  
   
  2.先得到对话框的指针,然后得到树形控件的指针,不就可以了吗?  
  例如:  
        对话框为:CTestDlg;   树形控件为它的一个成员变量:CTreeCtrl   *m_pTree;  
        调用时:CTestDlg   dlg;  
                      dlg.m_pTree;  
           
  Top

10 楼xiaoxiaohan(萧晓寒)回复于 2001-12-14 22:07:32 得分 0

重载OnOk.Top

11 楼brows(眉头)回复于 2001-12-19 14:03:23 得分 0

问题解决了,怎么给分啊?Top

相关问题

  • 数据窗口控件中回车键的处理
  • 消息问题:我想根据回车键判断当前焦点在那个控件上该怎么处理?
  • 请问如何截获对话框中编辑控件的回车键,让它执行自己的处理函数,而不结束对话框
  • 如何能使回车键在EDT控件中产生作用?
  • 怎样才能让CEdit控件接受回车键?
  • ASP+SQL Server的BBS,如何正确处理回车键??
  • 如何使对话框里的EDIT控件响应键盘的回车键????????????????????????
  • TWebBrowser控件无法响应回车键怎么办啊!UP有分
  • 怎样使CEDIT控件接受回车键后换行,在线等待。
  • 怎么样消除在textbox控件中按下回车键的bb声?

关键词

  • visual c++
  • 控件
  • 消息
  • 属性
  • ctreectrl
  • onok
  • dialog
  • 对话框
  • 回车
  • 处理

得分解答快速导航

  • 帖主:brows
  • ghz
  • jiangsheng
  • wkgenius
  • sgr0426
  • bluecrest

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo