스캐너 스캐너 데이터를 캡처하는 사례

35036 단어 데이터
배경:
최근에는 스캐너를 잡고 바코드를 스캔해서 바코드 데이터를 얻는 기능을 해야 한다. 이전에는 스캐너를 해 본 적이 없지만 다른 방면의 외부 기기에서 데이터를 얻는 프로젝트를 많이 했기 때문에 원리도 알다시피 모두 키보드 입력에 해당하기 때문에 키보드 입력을 얻는 방안을 통해 이루어진다. 왜냐하면 이 기능점은 전체 pc의 모든 스캐너 프로그램의 데이터를 캡처하는 데 사용되기 때문이다.다른 프로그램도 스캐너를 사용한다. 내가 하는 이 프로그램도 데이터를 캡처하고 데이터에 대해 상응하는 처리를 할 수 있다. 데이터 처리는 뒤에 자신이 하는 업무 수요의 처리이다. 스캐너 스캐너의 데이터를 캡처하는 것과 무관하기 때문에 전역 키보드 갈고리를 통해 키보드의 입력을 캡처해서 실현할 수 있다. 이렇게 하면 모든 키보드의 입력 값을 얻을 수 있다. 생각이 생겼다. 바로 기능을 실현하는 것이다.코드에 대해서요!Windows 클라이언트의 기능으로 C#에 익숙하기 때문에 다음 프레젠테이션은 WPF를 통해 보여 드리겠습니다.
Solution:
생각이 나면 반드시 실제적으로 조작해야 한다. 먼저 전역 키보드 갈고리를 통해 키보드에 입력한 데이터를 캡처하는 것을 알고 Win32Api를 호출하여 키보드 갈고리 Hook을 만들어서 실현한다. 이 기능 실현 코드는 인터넷에서 찾아보면 너무 쉽다. 블로그 정원에도 있지만 완전한 기능은 스스로 Copy해야 한다.안의 주석은 매우 전면적이어서 모두 알아볼 수 있다!
  1 using System;

  2 using System.Collections.Generic;

  3 using System.Linq;

  4 using System.Runtime.InteropServices;

  5 using System.Text;

  6 using System.Threading.Tasks;

  7 using System.Windows.Forms;

  8 

  9 namespace MedicalMain

 10 {

 11     public class KeyboardHook

 12     {

 13         public event KeyEventHandler KeyDownEvent;

 14         public event KeyPressEventHandler KeyPressEvent;

 15         public event KeyEventHandler KeyUpEvent;

 16 

 17         public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

 18         static int hKeyboardHook = 0; //            

 19         //  Microsoft SDK Winuser.h   

 20         public const int WH_KEYBOARD_LL = 13;   //              2,            13

 21         HookProc KeyboardHookProcedure; //  KeyboardHookProcedure  HookProc  

 22         //     

 23         [StructLayout(LayoutKind.Sequential)]

 24         public class KeyboardHookStruct

 25         {

 26             public int vkCode;  //       。             1 254

 27             public int scanCode; //            

 28             public int flags;  //    

 29             public int time; //             

 30             public int dwExtraInfo; //            

 31         }

 32         //

 33         [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

 34         public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

 35 

 36 

 37         //         

 38         [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

 39         public static extern bool UnhookWindowsHookEx(int idHook);

 40 

 41 

 42         //

 43         [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

 44         public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

 45 

 46         //         (        ) 

 47         [DllImport("kernel32.dll")]

 48         static extern int GetCurrentThreadId();

 49 

 50         //  WINDOWS API             ,      

 51         [DllImport("kernel32.dll")]

 52         public static extern IntPtr GetModuleHandle(string name);

 53 

 54         public void Start()

 55         {

 56             //       

 57             if (hKeyboardHook == 0)

 58             {

 59                 KeyboardHookProcedure = new HookProc(KeyboardHookProc);

 60                 hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);

 61                 //hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);

 62                 //************************************ 

 63                 //       

 64                 //SetWindowsHookEx( 2,KeyboardHookProcedure, IntPtr.Zero, GetCurrentThreadId());//        idGetCurrentThreadId(),

 65                 //      ,      (using System.Reflection;) 

 66                 //SetWindowsHookEx( 13,MouseHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0); 

 67                 // 

 68                 //  SetWindowsHookEx (int idHook, HookProc lpfn, IntPtr hInstance, int threadId)             ,        : 

 69                 //idHook     ,           ,        2,              ,                13, 

 70                 //            7,            14。lpfn          。  dwThreadId   0              

 71                 //     ,lpfn    DLL      。     ,lpfn                 。         ,        

 72                 //          。hInstance         。    lpfn      DLL。  threadId              ,    

 73                 //         ,hInstance   NULL。                    。threaded                   

 74                 //   0,            ,      

 75                 //************************************ 

 76                 //  SetWindowsHookEx  

 77                 if (hKeyboardHook == 0)

 78                 {

 79                     Stop();

 80                     throw new Exception("        ");

 81                 }

 82             }

 83         }

 84         public void Stop()

 85         {

 86             bool retKeyboard = true;

 87 

 88 

 89             if (hKeyboardHook != 0)

 90             {

 91                 retKeyboard = UnhookWindowsHookEx(hKeyboardHook);

 92                 hKeyboardHook = 0;

 93             }

 94 

 95             if (!(retKeyboard)) throw new Exception("");

 96         }

 97         //ToAscii                         

 98         [DllImport("user32")]

 99         public static extern int ToAscii(int uVirtKey, //[in]             。 

100                                          int uScanCode, // [in]                  。            ,   (  )

101                                          byte[] lpbKeyState, // [in]   , 256    ,         。    (  )            。           ,     (  )。    ,      ,      。    ,     CAPS LOCK     。      NUM           。

102                                          byte[] lpwTransKey, // [out]                。 

103                                          int fuState); // [in] Specifies whether a menu is active. This parameter must be 1 if a menu is active, or 0 otherwise. 

104 

105         //       

106         [DllImport("user32")]

107         public static extern int GetKeyboardState(byte[] pbKeyState);

108 

109 

110         [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

111         private static extern short GetKeyState(int vKey);

112 

113         private const int WM_KEYDOWN = 0x100;//KEYDOWN 

114         private const int WM_KEYUP = 0x101;//KEYUP

115         private const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWN

116         private const int WM_SYSKEYUP = 0x105;//SYSKEYUP

117 

118         private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)

119         {

120             //       

121             if ((nCode >= 0) && (KeyDownEvent != null || KeyUpEvent != null || KeyPressEvent != null))

122             {

123                 KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

124                 // raise KeyDown

125                 if (KeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))

126                 {

127                     Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;

128                     KeyEventArgs e = new KeyEventArgs(keyData);

129                     KeyDownEvent(this, e);

130                 }

131 

132                 //    

133                 if (KeyPressEvent != null && wParam == WM_KEYDOWN)

134                 {

135                     byte[] keyState = new byte[256];

136                     GetKeyboardState(keyState);

137 

138                     byte[] inBuffer = new byte[2];

139                     if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1)

140                     {

141                         KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);

142                         KeyPressEvent(this, e);

143                     }

144                 }

145 

146                 //      

147                 if (KeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))

148                 {

149                     Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;

150                     KeyEventArgs e = new KeyEventArgs(keyData);

151                     KeyUpEvent(this, e);

152                 }

153 

154             }

155             //    1,     ,        ,    。

156             //    0   CallNextHookEx                 ,              

157             return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);

158         }

159 

160         ~KeyboardHook()

161         {

162             Stop();

163         }

164 

165     }

166 }

키보드 갈고리 기능 클래스가 실현되었습니다. 다음은 이 클래스를 호출하여 키보드의 입력 값을 잡을 수 있습니다.
eyboardHook k_hook = new KeyboardHook();

  k_hook.KeyDownEvent += new System.Windows.Forms.KeyEventHandler(hook_KeyDown);//     

private void hook_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)

{

///

}

      hook_KeyDown 방법은 매번 버튼을 눌렀을 때 터치하고 매개 변수 e를 통해 매번 키보드에 입력된 키 값을 얻을 수 있다. 이렇게 키보드 갈고리는 실현되었지만 우리가 정상적으로 사용하는 과정에서 진실한 키보드 키를 통해 입력할 때도 있고 스캐닝 총을 통해 입력할 수도 있다. 그러면 이럴 때 스캐닝 총을 통해 입력할지 키보드를 통해 입력할지 어떻게 구분해야 하는가!나중에 도랑을 통해 한 가지 해결 방안을 찾았지만 이 해결 방안은 판단이 정확하지 않다. 버튼의 간격을 통해 판단하면 다음 코드의 실현은 다음과 같다.
   private StringBuilder inputKey=new StringBuilder();

           /// <summary>

 2         ///         

 3         /// </summary>

 4         /// <param name="sender"></param>

 5         /// <param name="e"></param>

 6         private void hook_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)

 7         {

 8            string temp=string.Empty;

 9            DateTime nowTime = DateTime.Now;

10            if ((e.KeyData >= Keys.D0 && e.KeyData <= Keys.D9) || (e.KeyData >= Keys.NumPad0 && e.KeyData <= Keys.NumPad9))//           

11                temp = (e.KeyData.ToString()).Last().ToString();

12            else

13                temp = e.KeyData.ToString();

14             if((nowTime-previewTime).Milliseconds<20)//                           

15             {

16                 if (e.KeyValue == (int)Keys.Return&&inputKey.Length>2)

17                 {

18                     this.tb_Key.Text = inputKey.ToString();

19                     inputKey = new StringBuilder();

20                     previewTime = DateTime.Now;

21                     return;

22                 }

23                 inputKey.Append(temp);  

24               

25             }

26             else

27             {

28                 inputKey=new StringBuilder(temp);

29             }

30             previewTime = DateTime.Now;

31         }

 
스캐너가 마지막에 스캔이 끝난 후에 리턴 키가 되돌아오기 때문에 우리는 리턴 키와 각 버튼의 시간 간격을 통해 판단한다. 동료가 어떤 키와 리턴 키를 누르는 것을 방지하기 위해 그들의 시간 간격도 매우 작기 때문에 마지막에 입력한 문자열의 길이를 통해 판단할 수 있다. 바코드는 한두 글자밖에 없는 것이기 때문에 개인의 요구를 보자!
요약:
스캐너 스캐너 데이터의 실현은 매우 간단하고 심오한 기술도 없다. 바로 자신의 실현 기능에 대한 기록이고 다른 사람에게 더 정확한 방안이 있는지 가르쳐 주려고 한다. 왜냐하면 pc에 외부 장치만 연결된 것은 아니기 때문에 많은 다른 외부 장치도 데이터를 입력할 수 있다. 그러면 스캐너인지 다른 외부 장치가 입력한 데이터인지 구분할 수 없다!더 좋은 조언이 있으면 댓글로 알려주시면 감사합니다!

좋은 웹페이지 즐겨찾기