Преведствую All!
Такая у меня происходит история, пишу программку для PocketPC в C#, которая прослушивает COM порт на наличие данных от сканера штрих кодов. Доступ к порту получаю с помощью WinAPI. Но вот что происходит, когда я открываю порт и начинаю случать порт (и даже принимать данные), все замечательно работает, до тех пор, пока я не трону экран КПК стайлом, тогда больше он на это стайло реагировать не будет, как и на другие кнопки. При всем этом он весело будет продолжать сканировать и отображать отсканированное на экране. То, что отсканированное все-таки отображается на экране, не смотря на то что, на все другие потуги КПК не обращает внимание, породило во мне подозрение, что это не хардварное повисание, а просто отказ принимать события. Так это или не так, но я все равно в тупике.
Пример, который я набросал(сам код в самом низу), упрощен до состояния подходящего для изучения ошибки, которая все равно никуда не исчезла.
Вот какой порядок действий:
1. Создаю поток.
2. Открываю порт (CreateFile())
3. Устанавливаю фильтр (SetCommMask())
4. Начинаю ждать сообщений (WaitCommEvent())
5. Дожидаюсь и делаю ReadFile()
6. Закрываю порт.
Можно упростить еще больше, т.е. создавать поток и открывать порт и через промежуток времени закрывать в новом потоке, будет тоже самое, если я трону стойлом экран в промежутке, когда порт открыт, но если позже, все будет хорошо и нечего виснуть не будет.
Вот какое оборудование используется:
КПК: RoverPC P5, проц Intel SA1110, ОС Windows CE 3.0 сборка 11171.
Сканер (На всякий случай написал, чтоб был:о) Metrologic Pulsar MS6220
Пишу в Visual Studio 2003 проект для PocketPC (для WinCE .Net писал, тоже самое получается)
А вот измучивший меня код:
public class ComPort
{
// Эта функцая являтся точкой входа потока
private void BeginScan()
{
IntPtr hPort = CreateFile("COM1:", GENERIC_READ, 0, IntPtr.Zero,
OPEN_EXISTING, 0, IntPtr.Zero);
if((int)hPort == ERROR_FILE_NOT_FOUND)
throw new ApplicationException("Порт не откыт");
uint mskValue = EV_RXCHAR | EV_RXFLAG |
EV_TXEMPTY | EV_CTS |
EV_DSR | EV_RLSD |
EV_BREAK | EV_ERR |
EV_RING | EV_PERR;
if( ! SetCommMask(hPort, mskValue))
throw new ApplicationException("Ошибка при вызове SetCommMask()");
IntPtr uMask;
uMask = LocalAlloc(LMEM_FIXED | LMEM_MOVEABLE, 4);
Marshal.WriteInt32(uMask, 0);
if( ! WaitCommEvent(hPort, uMask, IntPtr.Zero))
throw new ApplicationException("Ошибка при вызове WaitCommEvent()");
uint recv = 0;
uint bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
ReadFile(hPort, buffer, bufferSize, out recv, IntPtr.Zero);
if( ! CloseHandle(hPort))
throw new ApplicationException("Ошибка при вызове CloseHandle()");
}
// Стартую поток
public void RunMe()
{
Thread aThread = new Thread(new ThreadStart(BeginScan));
aThread.Start();
}
//--------------- Имопорт из Win32 --------------------//
private const UInt32 GENERIC_READ = 0x80000000;
private const UInt32 GENERIC_WRITE = 0x40000000;
private const UInt32 OPEN_EXISTING = 3;
private const UInt32 ERROR_FILE_NOT_FOUND = 2;
[DllImport("coredll.dll", SetLastError=true)]
private static extern IntPtr CreateFile(
String lpFileName,
UInt32 dwDesiredAccess,
UInt32 dwShareMode,
IntPtr lpSecurityAttributes,
UInt32 dwCreationDisposition,
UInt32 dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("coredll.dll", SetLastError=true)]
private static extern Boolean ReadFile(
IntPtr hFile,
[Out] Byte[] lpBuffer,
UInt32 nNumberOfBytesToRead,
out UInt32 nNumberOfBytesRead,
IntPtr lpOverlapped);
[DllImport("coredll.dll", SetLastError=true)]
private static extern Boolean CloseHandle(IntPtr hObject);
private const UInt32 EV_RXCHAR = 0x0001;
private const UInt32 EV_RXFLAG = 0x0002;
private const UInt32 EV_TXEMPTY = 0x0004;
private const UInt32 EV_CTS = 0x0008;
private const UInt32 EV_DSR = 0x0010;
private const UInt32 EV_RLSD = 0x0020;
private const UInt32 EV_BREAK = 0x0040;
private const UInt32 EV_ERR = 0x0080;
private const UInt32 EV_RING = 0x0100;
private const UInt32 EV_PERR = 0x0200;
private const UInt32 EV_RX80FULL = 0x0400;
private const UInt32 EV_EVENT1 = 0x0800;
private const UInt32 EV_EVENT2 = 0x1000;
[DllImport("coredll.dll", SetLastError=true)]
private static extern Boolean WaitCommEvent(IntPtr hFile,
IntPtr lpEvtMask, IntPtr lpOverlapped);
[DllImport("coredll.dll")]
private static extern Boolean SetCommMask(IntPtr hFile,
UInt32 dwEvtMask);
[DllImport("coredll.dll",SetLastError=true)]
private static extern IntPtr LocalFree(IntPtr hMem);
[DllImport("coredll.dll",SetLastError=true)]
private static extern IntPtr LocalAlloc(uint uFlags, uint uBytes);
private const uint LMEM_FIXED = 0;
private const uint LMEM_MOVEABLE = 2;
}