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);AfxMessageBox(m_Text);}}return CFormView::PreTranslateMessage(pMsg);}
在上面的代码中,首先将pMsg->message所表示的消息同WM_KEYFIRST 和WM_KEYLAST比较,确定是键盘消息,然后通过消息参数pMsg->wParam的值来判定是否是回车键(VK_RETURN,虚拟键码可以从SDK相关资料查到)。如是,则可以将已输入到编辑框中的字符读取到m_Text中,并将其显示出来四、对编辑框的识别前面已经可以对回车键响应了,可一个表单窗体有若干个编辑框,其各自的处理方式不尽相同,这就有必要对编辑框进行识别、对不同的编辑框做不同的处理。而且当按下回车键时必须保证只有当前有焦点的编辑框能完成对回车键的响应动作,否则也就失去了实际意义。在Windows下的程序中,所有的资源都是有唯一标号的,使每个资源对象能唯一的区别于其他资源,所以我们可以通过资源ID来对编辑框做出区别,使之完成各自的响应处理。在Microsoft Visual C++ 6.0下可以通过"View"菜单的"ID= Resource Symboles…"查到指定ID的资源标识号的实际数值,如在本例中的两个编辑框IDC_EDIT1和IDC_EDIT2所对应的数值分别为1000和1001,对前面的解析消息的代码做些改动,主要如下所示:……if(pMsg->wParam==VK_RETURN ){HWND hWnd=::GetFocus();int iID=::GetDlgCtrlID(hWnd);if(iID==1000)//第一个编辑框的标识为1000{UpdateData(TRUE);AfxMessageBox(m_Text1);//显示第一个编辑框的内容}if(iID==1001) //第二个编辑框的标识为1001{UpdateData(TRUE);AfxMessageBox(m_Text2);//显示第二个编辑框的内容}}……
在此通过API函数::GetFocus()(注重前面的"::",标识是全局API函数,而非某个类中的成员函数)取得当前光标所处的(即有焦点的)编辑框的句柄,然后通过API函数::GetDlgCtrlID()根据这个句柄返回此窗口资源的ID 号,该ID号是动态获取的,使之同预先查看好的编辑框的ID作下比较即可区分出是需要哪个编辑框对回车键作出响应。小结:本文通过对消息的解析实现了对特定编辑框的回车键的响应,在对消息机制有了基本的了解之后,可以用与本文类似的方法,对代码稍作改动,就可以使其他一些不能响应非凡消息的控件能接收、处理特定的消息。