看板 EE_DSnP 關於我們 聯絡資訊
開始玩testAsc了 一開始就發現我的程式編譯不過 上版一查 FLAG的問題 comment掉就沒事了 (#1GR_Es0d (EE_DSnP)) 正常編譯後開始測按鍵 結果所有非字元鍵全死... 原來是因為cmdCharDef.cpp裡面的處理函數只處理了單碼按鍵 雙碼以上都是空的 於是先把下面助教會用的那段code毫不猶豫的抄過來 重新編譯後 開始讀的到特殊碼了 但是!! Backspace, Home, End這三個按鍵沒有正常顯示 不幸啊... ====以下正文==== 真的像我這麼不幸(好吧只有三個鍵已經很幸福了)的話要怎麼辦 基本上就是"讓程式看懂這串輸入是啥鬼" 所以第一件事就是紀錄自己的按鍵傳出怎樣的碼 以我的例子 Home傳出來的是27->79->72 End傳出來的是27->79->70 什麼? 你問我怎麼知道的? 就算認不得你的按鍵 testAsc還是會老實的印出來啊(笑) 接下來是分析 首先我們觀察助教的鍵盤 cmdCharDef.h Line:54開始是enum ParseChar的定義 這裡面包含了所有按鍵會傳出來的碼 大致上分為 1) 所有系統都一樣的單碼字元(Line 56:63) Tab啦Enter啦Esc啦大概都在這裡 2) 跟系統有關的單碼字元(Line 65:78) 只有一個Backspace 3) 跟系統有關的多碼字元(Line 80:105) Arrow keys & Mod keys 4) 未定義字元, 嗶一聲等等根本跟鍵盤無關的常數 我們可能需要改動的地方是2和3 我很幸運的 Backspace跟助教一樣是127 所以把助教的抄過來就好了 為了讓我們能適當的定義對應到自己按鍵的常數 我們要先了解編碼規則 第三區的按鍵編碼規則 以助教的鍵盤為例 Ex: ARROW_UP = 27 -> 91 -> 65 第一碼是特殊按鍵識別 一定是Esc 第二碼是特殊按鍵種類識別 助教的鍵盤在這裡沒有分別 Arrow和Mod都是91 像我的鍵盤就有分91和79的 第三碼是區分特殊按鍵 像UP是65 DOWN是66 諸如此類 Ex: PG_UP = 27 -> 91 -> 53 -> 126 前三碼的意義同上 第四碼是後綴修飾 助教的Mod鍵全都有這個後綴 接著來分析自己的按鍵的編碼規則 以我的為例 就是Esc -> [種類識別碼79] -> [識別碼] 所以就這樣定義常數: // // --HOME_END keys: 27 -> 79 -> {72,70} // MY_KEY_FLAG = 1 << 10, MY_KEY_INT = 79, MY_HOME_KEY = 72 + MY_KEY_FLAG, MY_END_KEY = 70 + MY_KEY_FLAG, 注意到因為我的按鍵是不連續的(天知道為什麼) 所以我定義_BEGIN和_END毫無用處 然後因為ARROW用掉了1<<8 MOD用掉了1<<9 所以我的_FLAG是1<<10 這裡說明一下_BEGIN, _END & _FLAG 這些其實是設計者的巧思: i) 因為這些特殊碼的第三碼是連續的 所以如果把頭尾記錄下來 到時候想要判斷這些碼的時候就只要看範圍就好 這是_BEGIN和_END ii) 如果我們今天拿到一個代表某按鍵的常數 我們想知道它是哪種按鍵 我們自然也可以去看範圍 但是有_FLAG就會更方便 例如我們可以寫這樣: bool isArrowKey(ParseChar ch){ return ch & ARROW_KEY_FLAG; } 這樣就可以把兩個邏輯運算變成一個位元運算了 注意到當成FLAG的bit在char的範圍外 所以可以用char(ARROW_UP_KEY)這種方式把FLAG遮起來 這就是為什麼會有 PG_UP_KEY = 53 + MOD_KEY_FLAG 這種寫法 常數定義完之後就要處理 處理的函數是ParseChar checkChar(char,istream&) @ cmdCharDef.cpp, Line 73:109 基本上當然是在那個switch裡作文章 處理的邏輯是如果讀到ESC就去抓下一個碼 根據這碼所代表的特殊鍵種類進行不同的處理 只要記得回傳的時候 是傳原本定義好的常數而不是自己定義的那個 (因為我們只動這兩個地方 其他部份的程式都不知道我們有偷改這裡 所以他們根本不認得我們定義的常數) (不過如果是原本沒定義過的常數 也是可以硬傳回去 只是接收端的處理可能要改寫) -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.248.9.32
jackervator:推一下 10/07 02:49
OckhamsRazor:推原PO 我也是這三個鍵不一樣XD 10/07 11:36
vegired:推一下,我這三個鍵也是另外改的XD 10/07 22:35
ric2k1:很實用的心得分享,先置底一下到 HW#2 due!! 10/07 23:30
XDucka:如果is Arrowkey那樣寫 不是要先確定 home 跟 uparrow雖然 10/09 21:49
XDucka:flag不一樣 但是也要確定key值不一樣 要是 pageup也是53 10/09 21:49
XDucka:leftarrow也是53不就G了@@ 既然這個不會重複 那當初幹嘛 10/09 21:50
XDucka:要多設定這種27 -> 91 -> xx 的方法阿.. 10/09 21:50
taldehyde:可以問一下1<<10的意思嗎? 10/12 20:47
OckhamsRazor:樓上裝弱... 10/12 21:04
taldehyde:樓上別這樣...後來查到是bitwise-shifting 10/12 21:17
andy13579372:感謝樓上 剛自D了一篇同樣的問題文 10/13 22:48
abc346289:所以意思是說我的home是27->79->72改完之後執行testAsc 10/14 00:19
abc346289:按home顯示"27 79 72 Home key"這樣就是完成了嗎? 10/14 00:20
ric2k1:會顯示 Home Key 而且再按下一個 key 也是正常的話,應該 10/14 13:44
ric2k1:就是 OK 囉! 10/14 13:44
ss355227:自己改完的經驗,如果定義成MY_HOME_KEY,testAsc好像會 10/18 03:49
ss355227:看不懂,應該只要HOME_KEY就好了 好像是原本就定好了 10/18 03:49
Phantasnix:參看這篇心得指點了自己的迷惑,感謝這麼用心又條理明 10/18 20:36
Phantasnix:晰的心得 <(_ _)> 10/18 20:36
ypf791:姆...其實我的意思是checkChar裡面 判斷用MY_KEY_INT和 10/19 00:55
ypf791:MY_KEY_FLAG之類的 但是return的時候用已經定義過的 10/19 00:55
ypf791:直接回傳MY_HOME_KEY的話的確會看不懂 10/19 00:56