1. 程式人生 > >用VC實現特定編輯框上對回車鍵響應

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

摘要:本文講述了在指定的編輯框上能響應從鍵盤輸入回車鍵的一種方法,對程序內訊息的解析、動態獲取指定資源ID等技術也作了簡要描述。

  一、引言

  在通常的以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中,並將其顯示出來。
 

相關推薦

VC實現特定編輯回車鍵響應

摘要:本文講述了在指定的編輯框上能響應從鍵盤輸入回車鍵的一種方法,對程序內訊息的解析、動態獲取指定資源ID等技術也作了簡要描述。   一、引言   在通常的以CEditView為基類的單文件/多文件檢視程式中,可以很好的響應鍵盤輸入的回車鍵,只需比較最近兩次的輸入的字元,看看最新輸入的字元是否內碼是13(0x

vue實現模態組件

dispatch cast out cancel 升級 -m 接收 方法 eno 基本上每個項目都需要用到模態框組件,由於在最近的項目中,alert組件和confirm是兩套完全不一樣的設計,所以我將他們分成了兩個組件,本文主要討論的是confirm組件的實現。 組件結構

【JS】checked實現複選全選和全不選

<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf8"> <title>無標題文件</title>

https是如何加密的 (知道了原理之後,希望自己能程式碼實現一下,還有用於個人資訊和公鑰進行加密的雜湊演算法,有時間也去查一下)

由於http協議是明文傳輸資料,資料的安全性沒有保障。為了改進這種明文傳輸協議,https誕生了。   https是在應用層和傳輸層之間,增加了一層ssl加密。對於加密,請往下看:   1、對稱加密   每次在傳送資料之前,伺服器先生成一把金鑰,

基於jQuery的ajax系列之FormData實現頁面無重新整理

接著上一篇ajax系列之用jQuery的ajax方法向伺服器發出get和post請求寫,這篇主要寫如何利用ajax和FormData實現頁面無重新整理的檔案上傳效果,主要用到了jQuery的ajax()方法和XMLHttpRequest Level 2的FormData介面。

vc++實現IFS分形演算法畫一棵樹

void IFS() { double a[][8]={ 0,0.195,-0.488 ,0.344 ,0.433 ,0.4431 ,0.2452 ,0.25 ,\ 0,0.462 ,0.414 ,-0.252 ,0.361 ,0.2511 ,0.5692 ,0.

《資料結構》嚴蔚敏 實現編輯程式

參考文章:https://blog.csdn.net/Vit_rose/article/details/52781086 核心程式碼:void LineEdit(SqStack L) //order stack //接受使用者輸入在緩衝區中,使用者發現輸入錯誤的時候,可以補一個

jsp實現簡單的圖片傳功能

public voiddoGet(HttpServletRequest request, HttpServletResponse response)     throws ServletException, IOException {    String contentType=request.getCont

VC++實現Console程式顯示彩色文字

  用vc++寫console程式時,整天對著黑紙白字的螢幕,感覺很鬱悶吧?很多人想用CONIO.H/GRAPHICS.H中的一些函式來實現,卻發現VC++根本沒有這些標頭檔案。當然了CONIO.H/GRAPHICS.H是BORLAND TC/BC專有的標頭檔案,所以vc++

VC++實現應用程式視窗的任意分割(2)

一、關於CSplitterWnd類 我們在使用CuteFtp或者NetAnt等工具的時候,一般都會被其複雜的介面所吸引,在這些介面中視窗被分割為若干的區域,真正做到了視窗的任意分割。那麼我們自己如何建立類似的介面,也實現視窗的任意的分割呢?在VC6.0中這就需要使用到CSplitterWnd類。CSplitt

Java實現簡單的檔案傳伺服器和客戶端

/** * 使用TCP協議實現上傳功能的伺服器端 * 思路: * 新建ServerSocket * 等待客戶端連線 * 連線上後開啟子執行緒,把連接獲取的Socket傳給子執行緒 * 迴圈進行 * @author yajun * */ public class UploadServer {

Django & JavaScript Ajax實現JSON數據的請求和響應

UNC else admin ros cat nbsp ejs -c var 【描述】 1.Server端定義了兩個字段:Article.title 和 Article.content 2.客戶端用JavaScript Ajax異步加載請求服務器的JSON數據 效果是點擊按

控制元件子類化實現拖放顯示檔名編輯時遇到的問題【基於對話方塊】

控制元件子類化的步驟: 為控制元件派生一個新類,在其中加上需要響應的訊息函式。 為DLG類新增控制元件派生類的物件,並在OnInitDialog中呼叫XXX.SubClassDlgItem(IDC_XXX,this); 由於需要實現拖放檔案功能,所以在EDIT控制元件初始化時需

視訊傳:標籤編輯效果快速實現

本節我們來完成tag框,輸入關鍵字後回車即可出現標籤增加和刪除效果。 安裝: cd到我們的專案根目錄下執行 npm install vue-input-tag --save 安裝完成,我們的node_modules目錄中會多一個vue-in

KindEditor富文本編輯傳圖片功能實現,基於java項目

ger char 大小 append 參考 java ont area reat 1. HTML標簽與jquery代碼 <textarea id="editor_id" style="width: 200px; height: 200px;"></text

dedecms織夢列表頁調TAG標簽並帶鏈接的實現方法

調用 clas 添加 exp lob run 實現 lod tags 在需要調用的地方添加如下代碼: [field:id runphp=‘yes‘] global $cfg_cmspath; $tags = GetTags(@me);

ckeditor 加入象到編輯

class div col reat document cnblogs blog data itl elem=editor.document.createElement("img",{ attributes:{

一起寫框架-Ioc內核容器的實現-象的調-@Bean註解註入容器的象(十二)

擴展 lac iter component cts block 根據 spa urn 實現功能 現實需求中,有一些類似無法加入掃描組件註解的。如jdk裏面的類。 那麽框架必須要支持將沒有組件註解標識的類也可以有一個方式註入到容器裏面。 那麽,我們通過類似Spring的@

2.2、Hibernate註解方式實現一對多、多多關系

tab 技術部 employee join incr 無法運行 hset strategy urn 一、一對多關系   1、在上一篇日誌中用.xml配置文件項目基礎上,再往lib目錄先添加一個包-hibernate-jpa-2.0-api-1.0.0.Final.jar  

python實現一個命令行文本編輯

screen alt 保存 模型 既然 ffffff 圖片 單行 pda “這看起來相當愚蠢”——題記   不過我整個人都很荒誕,何妨呢?貼一張目前的效果圖   看起來很舒服,不是麽?即使一切都是個幌子:光標只能在最後,按一下上下左右就會退出,一行超出75個字符