• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

              C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              117 Posts :: 2 Stories :: 61 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(8)

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

             

            1、 問題闡述

                  在很多情況下,程序員迫切需要取得一個(gè)按鍵的ASCII碼值,一些常用的字符的ASCII可以去記住它,比如‘A’,‘1’等,但是一些生僻的字符的ASCII,比如‘:’、‘+’等,就要去查ASCII碼表,擴(kuò)展ASCII碼共有256個(gè)字符,查詢時(shí)浪費(fèi)時(shí)間并且有時(shí)還會(huì)查詢錯(cuò)誤。下面寫一個(gè)程序,程序在接受到某個(gè)按鍵消息時(shí),將接受到按鍵的轉(zhuǎn)換為ASCII碼。

            2、 實(shí)現(xiàn)技巧

                  Windows程序是消息機(jī)制的,鍵盤在按某個(gè)鍵時(shí),會(huì)產(chǎn)生一個(gè)按鍵消息,這個(gè)消息被操作系統(tǒng)獲得。程序的處理重點(diǎn)就是如何從操作系統(tǒng)捕獲這個(gè)消息,從這個(gè)消息的參數(shù)中解析出所需要的值。應(yīng)用程序從Windows接收的關(guān)于鍵盤事件的消息稱為按鍵消息。

                  按鍵消息,當(dāng)按下一個(gè)鍵時(shí),操作系統(tǒng)把WM_KEYDOWN或者WM_SYSDOWN消息放入消息隊(duì)列中,當(dāng)釋放一個(gè)按鍵時(shí),操作系統(tǒng)把WM_KEYUP或者WM_SYSDOWN消息放入消息隊(duì)列中。
                  DOWN和UP這一組消息通常成對(duì)出現(xiàn)。如果按住某個(gè)鍵長(zhǎng)時(shí)間不動(dòng),讓它重復(fù)產(chǎn)生相同的功能,操作系統(tǒng)將連續(xù)的WM_KEYDOWN或者WM_SYSDOWN送入應(yīng)用程序的消息處理窗口。釋放該鍵的時(shí)候,操作系統(tǒng)將連續(xù)的WM_KEYUP或者WM_SYSDOWN送入應(yīng)用程序的消息處理窗口。
                  按鍵之間也是有時(shí)間間隔,通過調(diào)用GetMessageTime()獲取按鍵和釋放按鍵的時(shí)間間隔,WM_SYSKEYDOWNWM_SYSKEYUP是一對(duì)系統(tǒng)鍵消息,類似地消息由系統(tǒng)自動(dòng)處理,用戶無需去截獲。產(chǎn)生這種消息的按鍵多為組合鍵,比如Alt+F,Ctrl+S等。
                  
                  消息原型消息名:WM_KEYDOWN,參數(shù)nVirtKey=(int)wParam;  IKeyData=IParam;,
                  消息名:WM_KEYUP,參數(shù)nVirtKey=(int)wParam;  IKeyData=IParam;,
                  其中,參數(shù)wParam是虛擬鍵碼。這個(gè)值是由鍵盤驅(qū)動(dòng)程序轉(zhuǎn)換掃描碼獲得的,它是與設(shè)備無關(guān)的,所以稱為虛擬鍵碼,大多數(shù)虛擬鍵碼的名稱在WINUSER.H表頭文件中都定義為VK_開頭的。
                  注意,數(shù)字和字母的虛擬鍵碼是ASCII碼。
                  
                  Windows程序幾乎從不使用這些虛擬鍵碼,實(shí)際上,程序使用的是ASCII碼字符的字符消息。參數(shù)IParam參數(shù)則含有對(duì)了解按鍵非常有用的其他信息。
                  IParam的32位分為6個(gè)字段,其中0~15表示重復(fù)計(jì)數(shù),重復(fù)計(jì)數(shù)是該消息所表示的按鍵次數(shù);16~23表示OEM掃描碼,它是由硬件產(chǎn)生的值;24表示擴(kuò)充鍵標(biāo)識(shí)25~28表示保留位;29表示內(nèi)容代碼。
                  按右鍵時(shí),假如同時(shí)按下【Alt】鍵,那么內(nèi)容代碼為1,對(duì)WM_SYSKEYUPWM_SYSKEYDOWN而言,此位總視為1,而對(duì)WM_SYSKEYUPWM_KEYDOWN消息而言,此位為0;
                  30表示先前狀態(tài),如果在此之前鍵是釋放的,則鍵的先前狀態(tài)為0,否則為1,
                  對(duì)WM_KEYUP或者WM_SYSKEYUP消息,它總是設(shè)定為1,但是對(duì)WM_KEYDOWN或者WM_SYSKEYDOWN消息,此位可以為0,也可以為1,如果為1,則表示該鍵是自動(dòng)重復(fù)功能所產(chǎn)生的第二個(gè)或者后續(xù)消息;31為表示轉(zhuǎn)換狀態(tài),如果鍵正被按下,則轉(zhuǎn)換狀態(tài)為0,如果鍵正被釋放,則轉(zhuǎn)換狀態(tài)為1,對(duì)WM_KEYDOWN或者WM_SYSKEYDOWN消息,此字段為0,對(duì)WM_KEYUP或者WM_SYSKEYUP消息,此字段為1。

            3、 實(shí)例代碼

                  接下來將開始制作一個(gè)ASCII碼查詢器。首先利用VC++6.0向?qū)Ы⒁粋€(gè)基于MFC的對(duì)話框工程QueryASCII,在界面上放置兩個(gè)只讀的EDIT,其中一個(gè)用于接收字符的值,另外一個(gè)顯示相應(yīng)的ASCII碼值,界面布局如下圖所示(關(guān)于如何建立MFC工程,可參考隨筆——在VC6下建立MFC工程圖解


            ①通過
            class winzard(View菜單下)添加對(duì)話框的WM_KEYDOWN消息響應(yīng)函數(shù)OnKeyDown,如下圖所示:


            ②通過
            class winzard(View菜單下)添加對(duì)話框QueryASCII的虛繼承函數(shù)PreTranslateMessage,如下圖所示:


            添加好后,分別在相應(yīng)的函數(shù)里面添加相應(yīng)的代碼,因?yàn)槲乙膊皇呛芏?,就寫了很多注釋,代碼如下:
            /* 接受KEYDOWN消息 */
            // 關(guān)于OnKeyDown函數(shù)請(qǐng)看注釋一
            void CQueryASCIIDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
            {
                
            // TODO: Add your message handler code here and/or call default
                CString strTemp;
                
            char ch=nChar;
                strTemp.Format(
            "%c",ch);    //關(guān)于Format的說明請(qǐng)看注釋二
                SetDlgItemText(IDC_CHAR_ED,strTemp);    //當(dāng)程序運(yùn)行時(shí)出現(xiàn),IDC_CHAR_ED未定義的說明時(shí),請(qǐng)看注釋三
                strTemp.Format("%0x",nChar);
                SetDlgItemText(IDC_ASCII_ED,strTemp);
                
            // then do not forget to call baseclass, 下面的是回調(diào)函數(shù)
                CDialog::OnKeyDown(nChar, nRepCnt, nFlags);    //想獲得更多知識(shí)可看注釋四
            }

            /* 翻譯信息 */
            // 關(guān)于PreTranslateMessage函數(shù)的解釋可看注釋五
            BOOL CQueryASCIIDlg::PreTranslateMessage(MSG* pMsg) 
            {
                
            // TODO: Add your specialized code here and/or call the base class
                if(pMsg->message == WM_KEYDOWN)
                
            //    pMsg->hwnd = m_hWnd;
                return CDialog::PreTranslateMessage(pMsg);
            }

            /* 注釋一 */
            /*******************************************************************/
            /* typedef UINT unsign int,占4個(gè)字節(jié),即為無符號(hào)整型
            /* nChar: Specifies the virtual key code of the given key. For a list
            /* of of standard virtual key codes, see Winuser.h
            /* 指定給定鍵的虛擬鍵碼。有關(guān)標(biāo)準(zhǔn)的虛擬鍵碼清單,可查看Winuser.h中
            /* nRepCnt: Repeat count(the number of times the keystroke is repeated
            /* as a result of the user holding down the key).     
            /* 重復(fù)計(jì)數(shù)(當(dāng)用戶按住了鍵,才會(huì)造成按鍵的數(shù)目重復(fù))。
            /* nFlags: Specifies the scan code, key-transition code, previous key
            /* state, and context code
            /* 指定掃描碼,關(guān)鍵過渡代碼,上一個(gè)鍵的狀態(tài)以及代碼的上下文
            /******************************************************************
            */

            /* 注釋二 */
            /********************************************************************************/
            /* Format(String, Object) 
            /* 將指定的 String 中的格式項(xiàng)替換為指定的 Object 實(shí)例的值的文本等效項(xiàng)。
            /*
            /* Format(String, array<Object>[]()[]) 
            /* 將指定 String 中的格式項(xiàng)替換為指定數(shù)組中相應(yīng) Object 實(shí)例的值的文本等效項(xiàng)。
            /* 
            /* Format(IFormatProvider, String, array<Object>[]()[]) 
            /* 將指定 String 中的格式項(xiàng)替換為指定數(shù)組中相應(yīng) Object 實(shí)例的值的文本等效項(xiàng)。指定
            /* 的參數(shù)提供區(qū)域性特定的格式設(shè)置信息。
            /*
            /* Format(String, Object, Object) 
            /* 將指定的 String 中的格式項(xiàng)替換為兩個(gè)指定的 Object 實(shí)例的值的文本等效項(xiàng)。
            /*
            /* Format(String, Object, Object, Object) 
            /* 將指定的 String 中的格式項(xiàng)替換為三個(gè)指定的 Object 實(shí)例的值的文本等效項(xiàng) 
            /*******************************************************************************
            */

            /* 注釋三 */
            /********************************************************************************/
            /* IDC_CHAR_ED和IDC_ASCII_ED指的是Edit Box的ID,只要右鍵單擊字符對(duì)應(yīng)的Edit Box選中
            /* Properties(屬性),General里的ID選項(xiàng)改為IDC_CHAR_ED即可。ASCII對(duì)應(yīng)的Edit Box的
            /* ID改為IDC_ASCII_ED即可。
            /* SetDlgItemText是一個(gè)函數(shù),設(shè)置對(duì)話框中控件的文本和標(biāo)題。
            /* 函數(shù)原型:
            /* BOOL SetDlgltemText(HWND hDlg,int nlDDlgltem,LPCTSTR IpString);
            /* 參數(shù):
            /* hDlg:指定含有控件的對(duì)話框。
            /* nlDDlgltem:標(biāo)識(shí)帶有將被設(shè)置的標(biāo)題和文本的控制。
            /* IpString:指向一個(gè)以NULL結(jié)尾的字符串指針,該字符串指針包含了將被復(fù)制到控制的文本。
            /* 返回值:如果函數(shù)調(diào)用成功,則返回值為非零值。如果函數(shù)調(diào)用失敗,則返回值為零。
            /* 若想獲得更多的錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。
            /******************************************************************************
            */

            /* 注釋四 */
            /*******************************************************************************/
            /* 要用“回車鍵”,“左移光標(biāo)健”,“右移光標(biāo)健”,“上移光標(biāo)健”,“下移光標(biāo)健”
            /* 這幾個(gè)鍵,你可以在這樣:   
            /* switch(nChar)   
            /* {   
            /*   case vk_return:   
            /*       //your   code   
            /*   case   vk_right:   
            /*       //your   code   
            /*   case   vk_left:  
            /*   case   vk_up:   
            /*   case   vk_down:  
            /* }   
            /******************************************************************************
            */

            /* 注釋五 */
            /****************************************************************/
            /* 函數(shù)原型:virtual BOOL PreTranslateMessage(MSG* pMsg);      
            /* 功能:重載該函數(shù)可以實(shí)現(xiàn)窗口消息派發(fā)給窗口函數(shù)TranslateMessage()
            /* 和DispatchMessage()之前的過濾。默認(rèn)的實(shí)現(xiàn)是完成加速鍵的翻譯。
            /* 因?yàn)槟仨氃谀愕闹剌d版本中調(diào)用CWinApp:PreTranslateMessage()函數(shù).
            /* 在MFC中,PreTranslateMessage()是虛函數(shù),我們可以重載它來處理鍵盤和鼠標(biāo)消息。
            /* 在SDK中,這又有所不同,我們必須在回調(diào)函數(shù)中
            /* LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
            /* 處理消息,它和PreTranslateMessage起的作用是類似的。只是MFC封裝的更好而已
            /* 更多相關(guān)信息可查看隨筆:
            http://www.shnenglu.com/kangnixi/archive/2010/02/17/107989.html
            /***************************************************************
            */


            我對(duì)代碼進(jìn)行了修改和優(yōu)化,如下所示
            (未完,稍等)

            想要獲得更多內(nèi)容,可點(diǎn)擊:《Visual C++代碼參考與技巧大全》學(xué)習(xí)筆記——索引隨筆

            Feedback

            # re: ASCII碼查詢器 2010-04-04 01:36 huangzongwu@hotmail.com
            BOOL CQueryASCIIDlg::PreTranslateMessage(MSG* pMsg)
            {
            // TODO: Add your specialized code here and/or call the base class
            if(pMsg->message == WM_KEYDOWN)
            // pMsg->hwnd = m_hWnd;
            return CDialog::PreTranslateMessage(pMsg);
            }

            這個(gè)函數(shù)很明顯陷入死循環(huán)了,好好想想吧

              回復(fù)  更多評(píng)論
              

            # re: ASCII碼查詢器 2012-09-12 10:16 侯云猛
            ??
              回復(fù)  更多評(píng)論
              

            久久精品国产亚洲网站| 久久无码av三级| 久久天天躁狠狠躁夜夜2020老熟妇| 欧美久久亚洲精品| 亚洲国产成人久久综合野外| 久久久久99精品成人片| 久久久噜噜噜久久| 一本久道久久综合狠狠躁AV| 亚洲国产小视频精品久久久三级 | 亚洲国产精品久久久天堂| 久久久久无码中| 久久久国产视频| 久久久久久曰本AV免费免费| 久久婷婷午色综合夜啪| 99久久夜色精品国产网站| 18禁黄久久久AAA片| 亚洲AV乱码久久精品蜜桃| 久久99精品国产99久久| 久久www免费人成精品香蕉| 区亚洲欧美一级久久精品亚洲精品成人网久久久久| 久久久久国色AV免费观看| 亚洲欧美一区二区三区久久| 99精品国产99久久久久久97| 99精品久久精品| 久久免费观看视频| 无码日韩人妻精品久久蜜桃| 精品久久久久久| 精品国产日韩久久亚洲| 国产精品久久久久无码av| 久久久久亚洲AV无码专区网站| 久久精品国产亚洲AV不卡| www.久久99| 综合网日日天干夜夜久久| 国产成人久久久精品二区三区| 97精品伊人久久大香线蕉| 久久精品国产精品国产精品污| 伊人色综合九久久天天蜜桃| 国产精品久久久久天天影视| 日韩久久久久中文字幕人妻| 97超级碰碰碰久久久久| 久久婷婷午色综合夜啪|