国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

用VC實現特定編輯框上對回車鍵響應

2019-11-17 05:06:28
字體:
來源:轉載
供稿:網友
摘要:本文講述了在指定的編輯框上能響應從鍵盤輸入回車鍵的一種方法,對進程內消息的解析、動態獲取指定資源ID等技術也作了簡要描述。
要害字:Microsoft Visual C++ 6.0、編輯框、回車鍵、消息、資源 一、引言在通常的以CEditView為基類的單文檔/多文檔視圖程序中,可以很好的響應鍵盤輸入的回車鍵,只需比較最近兩次的輸入的字符,看看最新輸入的字符是否內碼是13(0x0d,回車鍵的內碼)即可識別出來,而要單獨把一個編輯框放入對話框中卻根本不響應,這個看似簡單的問題在實際應用中還是解決起來比較困難的。尤其是當一個充當表單錄入的對話框上有若干個編輯框,這就要求在一個編輯框添完一項表單后用習慣的回車鍵將該編輯框上的數據讀取到內存中去,并自動將光標移動到下一個編輯框中預備填寫下一欄表單。無疑這種界面是十分人機友好的,使錄入人員不必去執行每填一下表單就去按一下執行讀入到緩存功能的按鈕的煩瑣操作。但上述功能的實現卻并不象其演示的功能那樣簡單,下面本文就對這項技術的實現及附帶的其他技術作簡要的介紹。二、不能響應回車鍵的原因分析之所以在以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);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作下比較即可區分出是需要哪個編輯框對回車鍵作出響應。小結:本文通過對消息的解析實現了對特定編輯框的回車鍵的響應,在對消息機制有了基本的了解之后,可以用與本文類似的方法,對代碼稍作改動,就可以使其他一些不能響應非凡消息的控件能接收、處理特定的消息。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 铜梁县| 两当县| 湖北省| 巴中市| 翼城县| 金溪县| 本溪| 亳州市| 沙田区| 景东| 三河市| 胶州市| 龙游县| 翁源县| 鹿邑县| 漳浦县| 图片| 无棣县| 黄骅市| 神农架林区| 错那县| 兰州市| 潼南县| 武宣县| 兴隆县| 黄浦区| 德安县| 从化市| 漳州市| 昔阳县| 南和县| 关岭| 普兰县| 漯河市| 武安市| 镇平县| 南雄市| 江陵县| 桂阳县| 昭觉县| 兴文县|