USBスキャンガンQRコード読み取り(一)——U 3 D編
5652 ワード
USBスキャナーガンはプラグアンドプレイで、キーボードのような方式でシステムと対話し、スキャンしたデータ取得方式には2つの実現方式がある.
(1)テキストボックスにフォーカスを入力し,スキャンしてテキストボックス内に自動的に表示する.
(2)キーボードフックを用いて,スキャンガンの仮想キーを引き,キーボード仮想コードとASCIIコードの変換を行ってデータを取得する.
プログラム開発においては,第2の方式が一般的に用いられているが,以下,U 3 D開発環境において,USBスキャナーガンのスキャンデータを受信する上での問題点を検討して共有する.
プログラム開発でシステムフックを実現するのは簡単で,Win 32のAPIを呼び出せばよい.
(1)SetWindowsHookEx フックを設定します.(カードを1本設け、必要な情報を調べる)
(2)CallNextHookEx フックを渡すために使用されます(メッセージは重要なので、メッセージを封鎖することを決めない限り、どこから来たら、どこに戻るべきですか).
(3)UnhookWindowsHookEx アンロードフック(アンロードが重要で、カードが多すぎると渋滞します)
最も重要な部分は2つあります.
1つは、受信したキーボードの数値の処理です.
私のスキャンガンがセットされた後のスキャンコードの場合は、例えば以下のようになります.
(1)shiftの仮想コード160を大文字の前に送信する
(2)第2機能キー送信shiftに対応する仮想コード
(3)送信終了キーボードコード13 40
例えば、160,187はキーボードの+に対応し、ASCIIコードは43
160,65対応はキーボードのA、ASCIIコードは65
shiftに対応する大文字と小文字の問題、および第2の機能キーの特殊な処理を処理する必要がある.
二つ目はスキャン終了の判断です.
プログラムでは、13回車を受信したキーボードコードを終了の判定フラグとし、受信後に「r」を判定フラグとして追加する.
私の処理テストコードU 3 Dで使用(C#)はここで
使用時
string str = myHook.getRet();すぐ
(1)テキストボックスにフォーカスを入力し,スキャンしてテキストボックス内に自動的に表示する.
(2)キーボードフックを用いて,スキャンガンの仮想キーを引き,キーボード仮想コードとASCIIコードの変換を行ってデータを取得する.
プログラム開発においては,第2の方式が一般的に用いられているが,以下,U 3 D開発環境において,USBスキャナーガンのスキャンデータを受信する上での問題点を検討して共有する.
プログラム開発でシステムフックを実現するのは簡単で,Win 32のAPIを呼び出せばよい.
(1)SetWindowsHookEx フックを設定します.(カードを1本設け、必要な情報を調べる)
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}
}
(2)CallNextHookEx フックを渡すために使用されます(メッセージは重要なので、メッセージを封鎖することを決めない限り、どこから来たら、どこに戻るべきですか).
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
(3)UnhookWindowsHookEx アンロードフック(アンロードが重要で、カードが多すぎると渋滞します)
void OnApplicationQuit()
{
UnhookWindowsHookEx(_hookID);
}
最も重要な部分は2つあります.
1つは、受信したキーボードの数値の処理です.
私のスキャンガンがセットされた後のスキャンコードの場合は、例えば以下のようになります.
(1)shiftの仮想コード160を大文字の前に送信する
(2)第2機能キー送信shiftに対応する仮想コード
(3)送信終了キーボードコード13 40
例えば、160,187はキーボードの+に対応し、ASCIIコードは43
160,65対応はキーボードのA、ASCIIコードは65
shiftに対応する大文字と小文字の問題、および第2の機能キーの特殊な処理を処理する必要がある.
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
bool isShift = false;
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
// UnityEngine.Debug.Log("ASCII:" + vkCode);
if (vkCode >= 65 && vkCode <= 90)
vkCode = vkCode + 32;//
if (myHook.m_hInstance.vkCodeLast == 160)
{
if (vkCode >= 48 && vkCode <= 57 )
{
if(vkCode==48)
vkCode= 41;//)
else if (vkCode == 49)
vkCode = 33; //!
else if (vkCode == 50)
vkCode = 64;// @
else if (vkCode == 51)
vkCode = 35;//#
else if (vkCode == 52)
vkCode = 36;//$
else if (vkCode == 53)
vkCode = 37;//%
else if (vkCode == 54)
vkCode = 94;//^
else if (vkCode == 55)
vkCode = 38;//&
else if (vkCode == 56)
vkCode = 42;//*
else if (vkCode == 57)
vkCode = 40;//)
else if (vkCode == 189)
vkCode = 95;//_
else if (vkCode == 187)
vkCode = 43;//+
}
else if (vkCode >= 97 && vkCode <= 122)
vkCode = vkCode - 32;//
if (vkCode == 186)//:
{
vkCode = 58;
}else if (vkCode == 187)
vkCode = 43;//+
else if (vkCode == 189)
vkCode = 95;//-
else if (vkCode == 190)
vkCode = 62;//>
else if (vkCode == 191)
vkCode = 63;//?
else if (vkCode == 219)
vkCode = 123;//{
else if (vkCode == 220)
vkCode = 124;//|
else if (vkCode == 221)
vkCode = 125;//}
}
if (vkCode == 186)// ;
{
vkCode = 59;
}
if (vkCode == 187)// =
{
vkCode = 61;
}
if (vkCode == 189)// -
{
vkCode = 45;
}
if (vkCode == 190)//.
{
vkCode = 46;
}
if (vkCode == 191)// /
{
vkCode = 47;
}
if (vkCode == 219)
vkCode = 91;//[
if (vkCode == 220)
vkCode = 92;//\
if (vkCode == 220)
vkCode = 93;//]
if (vkCode == 109)// -
{
vkCode = 45;
}
if (vkCode == 13)
{
myHook.m_hInstance._result.Add("\r
");
}
if (vkCode != 160 && vkCode!=13&&vkCode != 40)
{
myHook.m_hInstance.lenNow++;
string alpha = Convert.ToChar(vkCode).ToString();
myHook.m_hInstance._result.Add(alpha);
}
myHook.m_hInstance.vkCodeLast = vkCode;
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
二つ目はスキャン終了の判断です.
プログラムでは、13回車を受信したキーボードコードを終了の判定フラグとし、受信後に「r」を判定フラグとして追加する.
public static string getRet()
{
string s = string.Join("", myHook.m_hInstance._result.ToArray());
if (s.EndsWith("\r
"))
{
myHook.m_hInstance._result.Clear();
return s.Trim();
}
else
{
return "";
}
}
私の処理テストコードU 3 Dで使用(C#)はここで
使用時
string str = myHook.getRet();すぐ