2012年10月22日 星期一

條碼輸入與手動輸入判別─WinCE為例(C#)

使用PDA作業都需要使用條碼輸入
但有時沒有標籤可讀取亦可能人員手動輸入
此時判斷讀取條碼或手動輸入這個需求出現了
我們都知道讀取條碼採用模擬鍵盤事件輸入
表示只要將焦點(Focus)在文字方塊上
按下PDA上的[Scan]鍵就會讀取到的條碼會自動輸入到文字方塊中
然而最後它會輸入[Enter]鍵
因此只要在文字方塊的keypress事件中
在判斷式if(e.keychar == 13)底下寫你想要做的事情就可以了
寫到這,看不出來為何要判別讀取條碼或手動輸入

以下就是關鍵所在了
若你要第二次輸入時,將焦點放回文字方塊中
按下[Scan]鍵,會發現第二次讀取條碼會輸在原本已輸入的第一個條碼後面
它不會自動清除第一次輸入的條碼
總不可能教育訓練時,跟客戶講說要輸第二次時,須將第一次輸的條碼文字清除
因此你要判斷若是條碼輸入,必須將文字方塊中的文字清除

目前遇到的PDA讀取條碼API有兩種處理方式:
1.一個字一個字輸入進去
2.會存在自己的內存後,按下[Ctrl+V]
以上兩種最後都會按下[Enter]鍵

因應兩種處理方式,各有不同方法去處理:
1.針對第一種方法,一個字一個字輸進去的
需要以時間間隔去判斷條碼或手動輸入
以下為代碼:
//GetTickCountFunc
        [DllImport("Coredll.dll", EntryPoint = "GetTickCount")]
        private static extern int GetTickCount();
//條碼與手動輸入判斷變數
        private int i = 0;
        private string tmp = "";  //暫存字串                
        private bool ManualInput = false;
        private bool AutoInput = false;
        private int dstart = GetTickCount(); 

private void txtMTL_ID_KeyPress(object sender, KeyPressEventArgs e)
        {
int dend = GetTickCount();//結束時間
                string strtime = (dend - dstart).ToString();//"毫秒"

                if (Convert.ToInt32(strtime) < 100)//判斷時間間隔,間隔小於50豪秒,TextBox清空
                {
                    txtMTL_ID.Text = "";
                    AutoInput = true;
                    ManualInput = false;
                }
                else
                {
                    tmp = "";
                    ManualInput = true;
                    AutoInput = false;
                }
                dstart = dend;

                if (e.KeyChar > 32 && e.KeyChar <= 126)
                {
                    i++;
                    tmp += e.KeyChar.ToString();
                }

if (e.KeyChar == 13)
{
 i = 0;
 if (AutoInput == true)
 {
  txtMTL_ID.Text = tmp;
 }
 if (ManualInput == true)
 {
  txtMTL_ID.Text = txtMTL_ID.Text;
 }

 //這裡寫想要做的事情
 //這裡寫想要做的事情

//清除存放資訊
 AutoInput = false;
 ManualInput = false;
 tmp = "";

         }
}
判斷原理是因為條碼輸入比人快且平均
因此以每個字輸入的時間間隔(毫秒)去判別
GetTickCount()Func是因WinCE的關係才需要
一般winform只需用DateTime.Now後用TotalMilliSeconds去判斷就可以了
ManualInput=true即手動輸入,AutoInput=true則是條碼輸入
範例中的[<100]也因每一台PDA而不同,需要自己去抓準那個時間

2.第二種會按下[Ctrl+V]的方式解方法更為簡單且準確
以下為代碼:
if (e.KeyChar == 22)
   txtMTL_ID.Text = "";

if (e.KeyChar == 13)
{
  //這裡寫想要做的事情
  //這裡寫想要做的事情
}
非常之簡單,判斷有按下[Ctrl+V]鍵將文字方塊內的文字清除
基本上PDA上面的按鍵,人員不可能會去按到這種Ctrl+V這種案件組合
因此這個方法應該是滿準確的

以上解決方式或許會有些瑕疵
但已經是可以解決我目前手邊出現的問題
當然你也可以仿照微軟的設計風格
根本不用判斷是條碼或手動輸入
只要一按到文字方塊將文字全選
這樣條碼輸入亦可蓋掉之前的
再點一下亦可將游標移至想要的位置進行輸入
這個方法最常在Excel當中見到
將selectall()方法寫在Textbox的MouseClick事件中即可
因為WinCE的Textbox中無MouseClick事件
暫時無想到其他方式
因此才會選擇使用上面兩種方式
下回見



沒有留言:

張貼留言