一個項目需要。需要在2天時間裏在振中掌機上添加一個軟鍵盤,用於輸入掌機本身不支持的字符。
接到這個任務後,便開始構思怎麼實現,畢竟軟鍵盤的顯示與切換沒有一個好的算法,用起來會有很多的問題。思來想去,最後確定了方案,開始着手實現。
關於代碼的實現思想
其實實現起來不是很難,字符的輸入與顯示便是ASCII碼,只要把ASCII碼按照自己想要排列的鍵盤樣式編好數組,然後通過上下左右鍵實現不同ASCII碼的選擇與切換即可。
關於數組實現
因爲我這次是基於振中掌機去做的軟鍵盤,所以選用了振中掌機的zzdBase語言進行編寫。
下面是構造了一個簡單的ASCII碼數組:
ASCData{1,1} = 126
ASCData{2,1} = 33
ASCData{3,1} = 64
ASCData{4,1} = 35
ASCData{5,1} = 36
ASCData{6,1} = 37
ASCData{7,1} = 94
ASCData{8,1} = 38
ASCData{9,1} = 44
ASCData{10,1} = 92
ASCData{11,1} = 61
ASCData{12,1} = 60
ASCData{13,1} = 62
ASCData{14,1} = 63
ASCData{15,1} = 91
ASCData{16,1} = 93
ASCData{17,1} = 123
ASCData{18,1} = 125
ASCData{19,1} = 95
ASCData{20,1} = 124
ASCData{21,1} = 96
ASCData{22,1} = 39
ASCData{23,1} = 32
ASCData{24,1} = 34
ASCData{25,1} = 59
ASCData{26,1} = 58
ASCData{27,1} = 0
這個碼錶顯示的是我挑選的需要用來輸入的字符,共27個字符,組成了3行 x 9列的鍵盤陣列。最後一個字符的ASCII碼爲0代表空字符。
下圖爲完成後的鍵盤陣列顯示。
有了數組編好了,那麼該如何顯示呢,這就需要考慮陣列的顯示算法了。
陣列顯示算法
陣列顯示主要思想便是在第一行顯示前9個字符,按順序顯示,第2行顯示第10~18個字符,最後一行顯示第19-27個字符。因爲我要把鍵盤顯示在屏幕的第7-第9行,所以我的首行設爲7。
下面是顯示碼錶源代碼。
Procedure 顯示ASCII碼錶
clear 7,3
SET INTENSITY ON
@7,0 say SPACE(20)
@8,0 say SPACE(20)
@9,0 say SPACE(20)
/* 繪製座標 */
LINE 0,111,159,111
LINE 0,110,159,110
LINE 0,109,159,109
LINE 0,108,159,108
LINE 0,107,159,107
LINE 0,106,159,106
i=1
Do While i <= 27
L1 = ASCData{i,1}
if i<=9 .AND. i>=1
L2 = i*2-1
IF i = INDEX
SET INTENSITY OFF // 設置屏幕反顯 白色高亮選中
@7,L2+1 say CHR(L1)
SET INTENSITY ON // 恢復屏幕常顯 黑色等待選中
@7,L2 say SPACE(1)
Else
SET INTENSITY ON
@7,L2+1 say CHR(L1)
@7,L2 say SPACE(1)
EndIf
EndIf
if i<=18 .AND. i>=10
L2 = (i-9)*2-1
IF i = INDEX
SET INTENSITY OFF
@8,L2+1 say CHR(L1)
SET INTENSITY ON
@8,L2 say SPACE(1)
Else
SET INTENSITY ON
@8,L2+1 say CHR(L1)
@8,L2 say SPACE(1)
EndIf
EndIf
if i<=27 .AND. i>=19
L2 = (i-18)*2-1
IF i = INDEX
SET INTENSITY OFF
@9,L2+1 say CHR(L1)
SET INTENSITY ON
@9,L2 say SPACE(1)
Else
SET INTENSITY ON
@9,L2+1 say CHR(L1)
@9,L2 say SPACE(1)
EndIf
EndIf
i=i+1
EndDo
SET INTENSITY OFF
return
Endpro
這個還是比較好實現的。
在完成顯示之後,下面要做的便是如何通過上下左右鍵改變選用的數組索引,並實時刷新鍵盤顯示。
鍵盤顯示刷新
因爲我排列好了鍵盤,因此只需要做到在鍵盤上按下“上”鍵時,索引-9,按下“左”鍵時,索引-1,同樣按下“右”鍵索引+1,按下“下”鍵索引+9,但是要考慮索引越界的情況,當按“上”鍵索引-9之後,如果索引小於零,此時應+27保證索引變爲最後一行的對應列。
下面是詳細代碼。
Procedure 軟鍵盤輸入
INDEX = 1 /* 數組索引,默認選擇第一個,即“~” */
Do 顯示ASCII碼錶
Do while .T.
Wait "" To HitKey
if Asc(HitKey) = 11 && 左移
INDEXTEM = INDEX // 索引暫存緩衝
INDEX = INDEX - 1
if INDEX < 1
INDEX = 27
EndIf
EndIf
if Asc(HitKey) = 12 && 右移
INDEXTEM = INDEX
INDEX = INDEX + 1
if INDEX > 27
INDEX = 1
EndIf
EndIf
if Asc(HitKey) = 14 && 下
INDEXTEM = INDEX
INDEX = INDEX + 9
if INDEX > 27
INDEX = INDEX - 27
EndIf
EndIf
if Asc(HitKey) = 17 && 上
INDEXTEM = INDEX
INDEX = INDEX - 9
if INDEX < 1
INDEX = INDEX + 27
EndIf
EndIf
if INDEX>=1 .AND. INDEX <=9 // 新的選中的鍵 座標索引
L3 = 7
L2 = INDEX*2
EndIf
if INDEX>=10 .AND. INDEX <=18
L3 = 8
L2 = (INDEX-9)*2
EndIf
if INDEX>=19 .AND. INDEX <=27
L3 = 9
L2 = (INDEX-18)*2
EndIf
if INDEXTEM>=1 .AND. INDEXTEM <=9 //上一個選中的鍵索引
L4 = 7
L5 = INDEXTEM*2
EndIf
if INDEXTEM>=10 .AND. INDEXTEM <=18
L4 = 8
L5 = (INDEXTEM-9)*2
EndIf
if INDEXTEM>=19 .AND. INDEXTEM <=27
L4 = 9
L5 = (INDEXTEM-18)*2
EndIf
L1 = ASCData{INDEXTEM,1}
L9 = ASCData{INDEX,1}
SET INTENSITY OFF // 刷新新鍵鍵盤顯示
@L3,L2 say CHR(L9)
SET INTENSITY ON
@L4,L5 say CHR(L1) // 刷新上一個鍵鍵盤顯示
SET INTENSITY OFF
//以上爲鍵盤刷新,以下爲應用層操作
if Asc(HitKey) = 13 && 確認
i=1
Do while i < 33
L3 = TempString32{i,1}
if L3 = 0
TempString32{i,1} = ASCData{INDEX,1}
Do 刷新APN
Exit
endif
i=i+1
Enddo
EndIf
if Asc(HitKey) = 92 .or. Asc(HitKey) = 24
clear 7,3
Exit
EndIf
if Asc(HitKey) = 8 && 刪除
i=1
Do while i < 33
L3 = TempString32{i,1}
if L3 = 0
TempString32{i-1,1} = 0
Do 刷新APN
Exit
endif
i=i+1
Enddo
EndIf
EndDo
return
Endpro
上面便是基於振中掌機實現的軟鍵盤的核心代碼,使用它的時候配合自己的應用層程序,可以在需要軟鍵盤的時候調用,不需要的時候關閉,方便高效。
寫在後面
其實最開始是想用C語言去做這個事情,但是用C寫到一半的時候,發現ASCII碼在設置大數組的時候,有些符號會當做特殊字符編譯,很是煩人。
比如我設置一個字符串數組
ASCII[] = {‘A’,”’,’!’};
我想顯示三個字符分別爲“A”,“ ’”,和“!”。但是編譯的時候就會報出在第二個字符單引號的時候編譯出錯。
所以爲了不必要的麻煩,改用了zzdBASE語言。
但後來一想,其實完全可以用ASCII源碼代替字符顯示,沒必要這樣,但是既然選擇了ZZDbase語言,就用了。相較與c語言,zzdbase語言有一個優點在於代碼寫起來更容易理解,讀起來也更順暢。因爲沒有沒有指針的概念,所以有些地方實現起來是有困難,但是總體代碼流暢度更高。當然c的可發揮空間更大,兩者相比見仁見智吧,適合項目的就是最好的,你覺得呢?