天天看点

回车键的使用

在VC中创建一基于对话框的工程,编译运行,成功。面对着刚刚创建的工程,心里那个高兴呀。突然一时心血来潮,按了个回车键,工程一闪而过没了。再编译运行,成功。按了个ESC键,工程一闪而过也没了。

为什么会这样,因为CDialog 中有默认对ENTER和ESC键的处理。

解决这种一按回车和ESC键就关闭工程的正确处理方法是:触发PreTranslateMessage消息,截获ENTER和ESC对对话框的消息。

代码如下:

BOOL CXXX::PreTranslateMessage(MSG* pMsg)

{

    if(pMsg->message == WM_KEYDOWN)

    {

        switch(pMsg->wParam)

        {

        case VK_RETURN://屏蔽回车键

            return TRUE;

        case VK_ESCAPE://屏蔽ESC键

            return TRUE;

        }

    }

    return CDialog::PreTranslateMessage(pMsg);

}

OK了,这下好了。突然我在对话框上加了一个编辑框和一个列表框,我想先在编辑框中输入内容,然后按一下回车键,就把编辑框的内容插入到列表框中。

突然一想还真无从下手,再一想还是在PreTranslateMessage里面做,上面的我是直接return TRUE;的。我在这个return TRUE;上面做就行了。

代码如下:

BOOL CXXX::PreTranslateMessage(MSG* pMsg)

    HWND h1 = ::GetDlgItem(m_hWnd,IDC_EDIT1);

    if(pMsg->message == WM_KEYDOWN)

    {        

        switch(pMsg->wParam)

        {

           case VK_RETURN:

               UpdateData();

               if (pMsg->hwnd == h1)

               {                                      

                     m_list.AddString(m_edit1);

               }    

                 return TRUE;

           case VK_ESCAPE:

                  return TRUE;

             break;

          }

    }  

    return CDialog::PreTranslateMessage(pMsg);

}

要是两个编辑框呢。在编辑框1中回车,把编辑框1的内容加到列表框,在编辑框2中回车,把编辑框2的内容加到列表框,于是这样。

代码如下:

BOOL CXXX::PreTranslateMessage(MSG* pMsg)

    HWND h1 = ::GetDlgItem(m_hWnd,IDC_EDIT1);

    HWND h2 = ::GetDlgItem(m_hWnd,IDC_EDIT2);

    if(pMsg->message == WM_KEYDOWN)

    {        

         switch(pMsg->wParam)

        {

                case VK_RETURN:

                      UpdateData();

                     if (pMsg->hwnd == h1)

                     {                                     

                          m_list.AddString(m_edit1);

                      } 

                    if (pMsg->hwnd == h2)

                    {                                        

                         m_list.AddString(m_edit2);

                     }    

                    return TRUE;

                case VK_ESCAPE:

                     return TRUE;

                 break;

           }

    }  

    return CDialog::PreTranslateMessage(pMsg);

}

为了下面的使用,先来讲讲VC的窗口类和窗口句柄的转换。

窗口类就是CWnd,窗口句柄就是HWND。CWnd和HWND之间互相转换代码如下:

    CWnd *pWnd;

    HWND  hWnd;

    hWnd = pWnd->GetSafeHwnd();        //CWnd->HWND

    pWnd = CWnd::FromHandle(hWnd); //HWND->CWnd

则这样上面的两个编辑框的代码,改一下第二个编辑框先得到CWnd,转一下然后和HWnd比较。

改了的代码如下:

BOOL CXXX::PreTranslateMessage(MSG* pMsg)

    HWND h1 = ::GetDlgItem(m_hWnd,IDC_EDIT1);

    CWnd *h2=GetDlgItem(IDC_EDIT2);

    if(pMsg->message == WM_KEYDOWN)

    {        

        switch(pMsg->wParam)

        {

        case VK_RETURN:

              UpdateData();

              if (pMsg->hwnd == h1)

              {                                         

                         m_list.AddString(m_edit1);

              } 

              if (pMsg->hwnd == h2->GetSafeHwnd())

              {                                     

                      m_list.AddString(m_edit2);

              }    

             return TRUE;

        case VK_ESCAPE:

              return TRUE;

          break;

        }

    }  

    return CDialog::PreTranslateMessage(pMsg);

}

完成了,功能一模一样。

好开心!

举一反三,下面别的控件你也可以这样做了。如:列表框

等等。

突然一天,我发现这种做法失效了。失效在组合框上了。

原本的希望却变成了失望。痛苦啊。

程序如下:

BOOL CXXX::PreTranslateMessage(MSG* pMsg)

    HWND h3 = ::GetDlgItem(m_hWnd,IDC_COMBO1);

    if(pMsg->message == WM_KEYDOWN)

    {        

           switch(pMsg->wParam)

          {

           case VK_RETURN:

                  UpdateData();

                   if (pMsg->hwnd == h3)

                  {                                                      

                             m_list.AddString(m_combo1);

                  }    

                 return TRUE;

           case VK_ESCAPE:

                 return TRUE;

           break;

         }

    }  

    return CDialog::PreTranslateMessage(pMsg);

}

于是用SPY++一看,组合框却有两个句柄,一个是ComboBox,还有一个是Edit的句柄。想想也是呀:组合框的可视部分就是由一个Edit组合成的,而pMsg->hwnd得到的句柄就是这个Edit所指的句柄(因为回车就是在这个Edit里面敲的),而HWND h3 =::GetDlgItem(m_hWnd,IDC_COMBO1);得到的这个句柄却是ComboBox的句柄,pMsg->hwnd 和 h3这两个当然不等了。

呵呵,找到了原因就好办了。

这下记起来有个这个函数了吧:CWnd* GetParent() const;

其实ComboBox就是Edit的父窗口(组合框和编辑框都可以看成是窗口)。

哦,既然pMsg->hwnd是Edit的句柄,ComboBox又是Edit的父窗口,那用个GetParent();就得到父窗口的句柄了,就可以和得到的句柄比较了。

大功告成,于是代码就出来了。

代码如下(举了两个组合框):

BOOL CEntercomboDlg::PreTranslateMessage(MSG* pMsg)

{

       CWnd *h1=GetDlgItem(IDC_COMBO1);

       CWnd *h2=GetDlgItem(IDC_COMBO2);

       CWnd* hh = CWnd::FromHandle(pMsg->hwnd);

       CWnd* hhp = NULL;

       if(pMsg->message == WM_KEYDOWN)

        {        

        switch(pMsg->wParam)

         {

        case VK_RETURN:

             UpdateData();

             hhp = hh->GetParent();  

             if (hhp == h1) {

                      m_list.AddString(m_combo1);

             }

             if (hhp == h2) {

                      m_list.AddString(m_combo2);

              }   

             return TRUE;

        case VK_ESCAPE:

             return TRUE;

         break;

         }

 }  

 return CDialog::PreTranslateMessage(pMsg);

}

哦,不错。

这只是回车键在VC的应用之一。

继续阅读