请问有谁知道CDialog在什么地方截取了在对话框子控件上按下ESC和ENTER键的消息?本来当一个子控件具有键盘输入焦点时,按下ESC和ENTER键,消息应该是发往该子控件的,但显然CDialog截取了发往子控件的消息,或者说子控件通过什么途径把消息上溯到CDialog的?

解决方案 »

  1.   

    因为,ESC和ENTER默认就是调用对话框的OnCancel和OnOK,你需要重载这两个函数并去掉基类的调用
      

  2.   

    用CLASSWIZARD添加一个PreTranslateMessage(MSG* pMsg) 处理函数,它能截取所有了窗口的消息。
      

  3.   

    用CLASSWIZARD添加一个PreTranslateMessage(MSG* pMsg) 处理函数,它能截取所有子窗口的消息。
      

  4.   

    "本来当一个子控件具有键盘输入焦点时,按下ESC和ENTER键,消息应该是发往该子控件的,"有根据吗?还是想当然。我同意overwind_slash(残翅迎风)的观点。
      

  5.   

    按键消息应该总是窗口先得到,然后传给控件处理的,
    窗口拦截了enter,esc,控件就得不到消息。这个是拦截enter转换为tab的例子:
    BOOL CXxDialog::PreTranslateMessage(MSG* pMsg)
             if(pMsg->message == WM_KEYDOWN )
    {
    CWnd * pWnd = CWnd::GetFocus(); 
    int  nID = pWnd->GetDlgCtrlID();
    switch (pMsg->wParam)
    {  
    case VK_RETURN:
    if(!pWnd->IsKindOf(RUNTIME_CLASS(CButton)))
    pMsg->wParam = VK_TAB;
    else
    {
    pWnd->PostMessage(WM_LBUTTONDOWN,WM_COMMAND,0);
    pWnd->PostMessage(WM_LBUTTONUP,WM_COMMAND,0);
    return TRUE;
    }
    break; }
    }
    return CDialog::PreTranslateMessage(pMsg);
    }
      

  6.   

    TO: mtsh(清风华仔(*****)) 在MFC中,当然通过消息映射或类的继承,WM_KEYDOWN消息会送往其他地方,这正是MFC和Win SDK的差别,你可以在CDialog::PreTranslateMessage中看到CDialog截获CEdit的WM_KEYDOWN消息(当wParam为VK_ESCAPE时),转而发送IDCANCEL命令消息,引发OnCancel()。
    我现在想要得就是当在对话框的一个编辑控件中按下ESC和ENTER时,由编辑控件来处理,而不是直接关闭对话框。
      

  7.   

    我看实际在licyme(锥子)的例子中,先获得WM_KEYDOWN的是Button子控件,然后Button子控件再把它发送给父窗口,即CXxDialog。
      

  8.   

    To cygroup():原来这样,原来我疏忽了!不过既然这样,你可以重写CDialog类重载PreTranslateMessage函数,改变对ESC和ENTRY键的默认处理方式,并把对基类的调用注释掉,实现起来应该没问题。
      

  9.   

    To mtsh(清风华仔(*****)) 
    通过参考MFC源代码,初步知道了解决办法,你说对了一半,是要重载CDialog子类的PreTranslateMessage函数,但不能屏蔽基类CDialog的PreTranslateMessage函数调用,因为那样会屏蔽掉所有针对对话框的其他输入,对话框会毫无反应。应该在对基类PreTranslateMessage函数的调用前,将ESC和ENTER的消息筛选出来重发向当前具有焦点的窗口。至于CDialog在什么地方如何截取ENTER的,我实在没时间、精力查下去了,都是MFC,把事情搞得那么复杂,要是用SDK就简单多了,键盘消息都是直接发向当前唯一具有输入焦点的窗口的。
      

  10.   

    补充:屏蔽基类CDialog的PreTranslateMessage函数调用也行,但一定返回FALSE,按MSDN的说法:
    Nonzero if the message was translated and should not be dispatched; 0 if the message was not translated and should be dispatched.
    非零的返回值会导致消息不再分发。