winform 监听扫码枪,上代码
private void cash_Load(object sender, EventArgs e)
{
ScanUseMethed use = new ScanUseMethed();
use.startScanLinster();
}
//这样是可以捕获到扫码信息的
{
ThreadStart thStart = new ThreadStart(aa);
Thread thread = new Thread(thStart);
thread.Start();
}
void aa()
{
ScanUseMethed use = new ScanUseMethed();
use.startScanLinster();
}
//放到线程中启动 就捕获不到扫码信息 这是为什么?
启动监听的主要代码如下
public event ScanerDelegate ScanerEvent;
delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
private int hKeyboardHook = 0;
private ScanerCodes codes = new ScanerCodes();
private HookProc hookproc;
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32", EntryPoint = "GetKeyNameText")]
private static extern int GetKeyNameText(int IParam, StringBuilder lpBuffer, int nSize);
[DllImport("user32", EntryPoint = "GetKeyboardState")]
private static extern int GetKeyboardState(byte[] pbKeyState);
[DllImport("user32", EntryPoint = "ToAscii")]
private static extern bool ToAscii(int VirtualKey, int ScanCode, byte[] lpKeySate, ref uint lpChar, int uFlags);
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name);
// 取得当前线程编号
[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId();
public ScanCodeHook222()
{
}
public bool Start()
{
if (hKeyboardHook == 0)
{
hookproc = new HookProc(KeyboardHookProc);
IntPtr modulePtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
hKeyboardHook = SetWindowsHookEx(13, hookproc, modulePtr, 0);
}
return (hKeyboardHook != 0);
}
public bool Stop()
{
if (hKeyboardHook != 0)
{
return UnhookWindowsHookEx(hKeyboardHook);
}
return true;
}
不是放到线程里面不管用,是因为放到线程里面之后你的aa()函数执行完线程结束了,整个线程资源包括实例化的use也被GC给回收掉了。你可以把你的aa函数改成这样试试:
void aa()
{
ScanUseMethed use = new ScanUseMethed();
use.startScanLinster();
while (true)
{
Application.DoEvents();
Thread.Sleep(1);
}
}
强制在函数末尾加一个死循环不让你实例化的线程结束。
之所以在UI线程不会出现这样的情况是因为UI线程本来就有一个消息死循环,你的Main函数里面肯定有:Application.Run(new Form1()),这个函数感兴趣的话你可以去看看里面是什么样子的,里面核心就是一个消息的死循环,所以UI线程才不会像你自己实例化的线程那样执行完函数立马结束回收。
A是主程序 B是新建的一个类库,我把启动监听的代码放到了B类库里面,然后在A主程序中去实例化这个类型中的方法去启动就不可以了,这是什么原因呢?
如果要把这些启动方法放到一个类库 应该怎么操作呢, 放到主程序可以 但是放到另外的一个类库就不行 是什么原理呢?谢谢指导