在一个dll中定义了消息发送的函数,
bool StartMonitor(HANDLE hComm, HWND hOwner)
{
DWORD dwThreadId;
CommInfo.hComm = hComm;
CommInfo.hOwner = hOwner; hThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0, ThreadProc, &CommInfo, 0, &dwThreadId);
if (hThread == NULL)
return false; return true;
}DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
COMMINFO *pCommInfo;
DWORD Bytes = 0;
DWORD BytesToRead = 0;
DWORD ErrorFlags = 0;
char CnfMsg[MAX_BUF_SIZE] = "\0";
char szReadBuf[MAX_BUF_SIZE] = "\0";
DWORD dwEvtMask = 0;
DWORD dwSignal = 0;
pCommInfo = (COMMINFO *)lpParameter; //清除串口缓冲区
PurgeComm(pCommInfo->hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
//哪些串口事件需要监视
SetCommMask(pCommInfo->hComm, EV_ERR | EV_RLSD | EV_RING | EV_RXCHAR | EV_TXEMPTY);
while (1) {
WaitCommEvent(pCommInfo->hComm, &dwEvtMask, &Overlapped);
dwSignal = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); if (dwSignal == WAIT_OBJECT_0) {
if((dwEvtMask & EV_RXCHAR) == EV_RXCHAR) {
Sleep(100);
RecvChar(pCommInfo->hComm);
if (strlen(RecvBuf) != 0) { strupr(RecvBuf);#ifdef SMS_DLL_DEBUG
sprintf(RecvDebugInfo, "<-- %s", RecvBuf);
if (strncmp(RecvBuf, "ATWITS", 6))
PostMessage(pCommInfo->hOwner, WM_RECVDATA, 1, (LPARAM)&RecvDebugInfo);
else
if (DispFlag)
PostMessage(pCommInfo->hOwner, WM_RECVDATA, 1, (LPARAM)&RecvDebugInfo);
#endif if (!strncmp(RecvBuf, "ATWITS+CMTI:1", 13)) {
if (pCommInfo->hOwner != NULL)
PostMessage(pCommInfo->hOwner, WM_RECVSMS, (LPARAM)pCommInfo->hComm, 0);
}
// else if (!strncmp(RecvBuf, "ATWITS", 6)) {
// if (pCommInfo->hOwner != NULL)
// PostMessage(pCommInfo->hOwner, WM_POWERON, 0, 0);
// }
else if (strlen(RecvBuf) != 0) {
//增加临界区控制
memset(RetInfo, 0, MAX_BUF_SIZE);
strcpy(RetInfo, RecvBuf);
SetEvent(hRecvEvent);
}
memset(RecvBuf, 0, MAX_BUF_SIZE);
}
} ResetEvent(Overlapped.hEvent);
}
else if(dwSignal == WAIT_OBJECT_0 + 1) {
SendChar(pCommInfo->hComm);
}
} return 0;
}在c#程序中调用StartMonitor,就可开启对com口的监视,但是程序中需要对一台电脑上的多个串口设备进行监视,因此在c#中重载了winproc函数,RecvSMS((IntPtr)m.WParam, phoneNum, msg);对上面消息进行接收,不能够很好的接收不知大家有没好办法
bool StartMonitor(HANDLE hComm, HWND hOwner)
{
DWORD dwThreadId;
CommInfo.hComm = hComm;
CommInfo.hOwner = hOwner; hThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0, ThreadProc, &CommInfo, 0, &dwThreadId);
if (hThread == NULL)
return false; return true;
}DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
COMMINFO *pCommInfo;
DWORD Bytes = 0;
DWORD BytesToRead = 0;
DWORD ErrorFlags = 0;
char CnfMsg[MAX_BUF_SIZE] = "\0";
char szReadBuf[MAX_BUF_SIZE] = "\0";
DWORD dwEvtMask = 0;
DWORD dwSignal = 0;
pCommInfo = (COMMINFO *)lpParameter; //清除串口缓冲区
PurgeComm(pCommInfo->hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
//哪些串口事件需要监视
SetCommMask(pCommInfo->hComm, EV_ERR | EV_RLSD | EV_RING | EV_RXCHAR | EV_TXEMPTY);
while (1) {
WaitCommEvent(pCommInfo->hComm, &dwEvtMask, &Overlapped);
dwSignal = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); if (dwSignal == WAIT_OBJECT_0) {
if((dwEvtMask & EV_RXCHAR) == EV_RXCHAR) {
Sleep(100);
RecvChar(pCommInfo->hComm);
if (strlen(RecvBuf) != 0) { strupr(RecvBuf);#ifdef SMS_DLL_DEBUG
sprintf(RecvDebugInfo, "<-- %s", RecvBuf);
if (strncmp(RecvBuf, "ATWITS", 6))
PostMessage(pCommInfo->hOwner, WM_RECVDATA, 1, (LPARAM)&RecvDebugInfo);
else
if (DispFlag)
PostMessage(pCommInfo->hOwner, WM_RECVDATA, 1, (LPARAM)&RecvDebugInfo);
#endif if (!strncmp(RecvBuf, "ATWITS+CMTI:1", 13)) {
if (pCommInfo->hOwner != NULL)
PostMessage(pCommInfo->hOwner, WM_RECVSMS, (LPARAM)pCommInfo->hComm, 0);
}
// else if (!strncmp(RecvBuf, "ATWITS", 6)) {
// if (pCommInfo->hOwner != NULL)
// PostMessage(pCommInfo->hOwner, WM_POWERON, 0, 0);
// }
else if (strlen(RecvBuf) != 0) {
//增加临界区控制
memset(RetInfo, 0, MAX_BUF_SIZE);
strcpy(RetInfo, RecvBuf);
SetEvent(hRecvEvent);
}
memset(RecvBuf, 0, MAX_BUF_SIZE);
}
} ResetEvent(Overlapped.hEvent);
}
else if(dwSignal == WAIT_OBJECT_0 + 1) {
SendChar(pCommInfo->hComm);
}
} return 0;
}在c#程序中调用StartMonitor,就可开启对com口的监视,但是程序中需要对一台电脑上的多个串口设备进行监视,因此在c#中重载了winproc函数,RecvSMS((IntPtr)m.WParam, phoneNum, msg);对上面消息进行接收,不能够很好的接收不知大家有没好办法
class threadCom
{
private string _com;
private IntPtr _handle; public threadCom()
{ } public threadCom(string com,IntPtr handle)
{
this._com = com;
this._handle = handle;
} private void openCom()
{
operateCom.OpenComm(_com, _handle);
} public void startThread()
{
ThreadStart thr_star_fun = new ThreadStart(openCom);
Thread fthread = new Thread(thr_star_fun);
fthread.Start();
} }
在主函数中调用
foreach (string s in avaliableEquipment) 其中s是com1和com2
{
threadCom tCom=new threadCom(s,this.Handle);
tCom.startThread();
}
但是我还是不能接收到第一个com口的消息,只能收到com2的不知道怎么回事?
threadCom[] tcom = new threadCom[avaliableEquipment.Length];
int i = 0; foreach (string s in avaliableEquipment)
{
tcom[i] = new threadCom(s, this.Handle);
//threadCom tCom=new threadCom(s,this.Handle);
tcom[i].startThread();
}
#region Usingusing System;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;
using System.ComponentModel;#endregion Usingnamespace LoMaN.IO { public class SerialStream : Stream {
#region Attributes private IOCompletionCallback m_IOCompletionCallback;
private IntPtr m_hFile = IntPtr.Zero;
private string m_sPort;
private bool m_bRead;
private bool m_bWrite; #endregion Attributes #region Properties public string Port {
get {
return m_sPort;
}
set {
if (m_sPort != value) {
Close();
Open(value);
}
}
} public override bool CanRead {
get {
return m_bRead;
}
} public override bool CanWrite {
get {
return m_bWrite;
}
} public override bool CanSeek {
get {
return false;
}
} public bool Closed {
get {
return m_hFile.ToInt32() 0;
}
} public bool Dsr {
get {
uint status;
if (!GetCommModemStatus(m_hFile, out status)) {
throw new Win32Exception();
}
return (status & MS_DSR_ON) > 0;
}
} public bool Ring {
get {
uint status;
if (!GetCommModemStatus(m_hFile, out status)) {
throw new Win32Exception();
}
return (status & MS_RING_ON) > 0;
}
} public bool Rlsd {
get {
uint status;
if (!GetCommModemStatus(m_hFile, out status)) {
throw new Win32Exception();
}
return (status & MS_RLSD_ON) > 0;
}
} #endregion Properties接下:
} public SerialStream(FileAccess access) {
m_bRead = ((int)access & (int)FileAccess.Read) != 0;
m_bWrite = ((int)access & (int)FileAccess.Write) != 0;
unsafe {
m_IOCompletionCallback = new IOCompletionCallback(AsyncFSCallback);
}
} public SerialStream(string port) : this(FileAccess.ReadWrite) {
Open(port);
} public SerialStream(string port, FileAccess access) : this(access) {
Open(port);
} #endregion Constructors #region Methods public void Open(string port) {
if (m_hFile != IntPtr.Zero) {
throw new IOException("Stream already opened.");
}
m_sPort = port;
m_hFile = CreateFile(port, (uint)((m_bRead?GENERIC_READ:0)|(m_bWrite?GENERIC_WRITE:0)), 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (m_hFile.ToInt32() == INVALID_HANDLE_VALUE) {
m_hFile = IntPtr.Zero;
throw new FileNotFoundException("Unable to open " + port);
} ThreadPool.BindHandle(m_hFile); SetTimeouts(0, 0, 0, 0, 0);
} public override void Close() {
CloseHandle(m_hFile);
m_hFile = IntPtr.Zero;
m_sPort = null;
} public IAsyncResult BeginRead(byte[] buffer) {
return BeginRead(buffer, 0, buffer.Length, null, null);
} public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) {
GCHandle gchBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
SerialAsyncResult sar = new SerialAsyncResult(this, state, callback, true, gchBuffer);
Overlapped ov = new Overlapped(0, 0, sar.AsyncWaitHandle.Handle.ToInt32(), sar);
unsafe {
NativeOverlapped* nov = ov.Pack(m_IOCompletionCallback);
byte* data = (byte*)((int)gchBuffer.AddrOfPinnedObject() + offset); uint read = 0;
if (ReadFile(m_hFile, data, (uint)count, out read, nov)) {
sar.m_bCompletedSynchronously = true;
return sar;
}
else if (GetLastError() == ERROR_IO_PENDING) {
return sar;
}
else
throw new Exception("Unable to initialize read. Errorcode: " + GetLastError().ToString());
}
} public IAsyncResult BeginWrite(byte[] buffer) {
return BeginWrite(buffer, 0, buffer.Length, null, null);
} public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) {
GCHandle gchBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
SerialAsyncResult sar = new SerialAsyncResult(this, state, callback, false, gchBuffer);
Overlapped ov = new Overlapped(0, 0, sar.AsyncWaitHandle.Handle.ToInt32(), sar);
unsafe {
NativeOverlapped* nov = ov.Pack(m_IOCompletionCallback);
byte* data = (byte*)((int)gchBuffer.AddrOfPinnedObject() + offset); uint written = 0;
if (WriteFile(m_hFile, data, (uint)count, out written, nov)) {
sar.m_bCompletedSynchronously = true;
return sar;
}
else if (GetLastError() == ERROR_IO_PENDING) {
return sar;
}
else
throw new Exception("Unable to initialize write. Errorcode: " + GetLastError().ToString());
}
} private int EndOperation(IAsyncResult asyncResult, bool isRead) {
SerialAsyncResult sar = (SerialAsyncResult)asyncResult;
if (sar.m_bIsRead != isRead)
throw new IOException("Invalid parameter: IAsyncResult is not from a " + (isRead ? "read" : "write"));
if (sar.EndOperationCalled) {
throw new IOException("End" + (isRead ? "Read" : "Write") + " called twice for the same operation.");
}
else {
sar.m_bEndOperationCalled = true;
} while (!sar.m_bCompleted) {
sar.AsyncWaitHandle.WaitOne();
} sar.Dispose(); if (sar.m_nErrorCode != ERROR_SUCCESS && sar.m_nErrorCode != ERROR_OPERATION_ABORTED) {
throw new IOException("Operation finished with errorcode: " + sar.m_nErrorCode);
} return sar.m_nReadWritten;
}
public override int EndRead(IAsyncResult asyncResult) {
return EndOperation(asyncResult, true);
}
接下:
EndOperation(asyncResult, false);
} public int EndWriteEx(IAsyncResult asyncResult) {
return EndOperation(asyncResult, false);
} public override int Read(byte[] buffer, int offset, int count) {
return EndRead(BeginRead(buffer, offset, count, null, null));
} public override void Write(byte[] buffer, int offset, int count) {
EndWrite(BeginWrite(buffer, offset, count, null, null));
} public int WriteEx(byte[] buffer, int offset, int count) {
return EndWriteEx(BeginWrite(buffer, offset, count, null, null));
} public int Read(byte[] buffer) {
return EndRead(BeginRead(buffer, 0, buffer.Length, null, null));
} public int Write(byte[] buffer) {
return EndOperation(BeginWrite(buffer, 0, buffer.Length, null, null), false);
} public override void Flush() {
FlushFileBuffers(m_hFile);
} public bool PurgeRead() {
return PurgeComm(m_hFile, PURGE_RXCLEAR);
} public bool PurgeWrite() {
return PurgeComm(m_hFile, PURGE_TXCLEAR);
} public bool Purge() {
return PurgeRead() && PurgeWrite();
} public bool CancelRead() {
return PurgeComm(m_hFile, PURGE_RXABORT);
} public bool CancelWrite() {
return PurgeComm(m_hFile, PURGE_TXABORT);
} public bool CancelAll() {
return CancelRead() && CancelWrite();
} public override void SetLength(long nLength) {
throw new NotSupportedException("SetLength isn't supported on serial ports.");
} public override long Seek(long offset, SeekOrigin origin) {
throw new NotSupportedException("Seek isn't supported on serial ports.");
} public void SetTimeouts(int ReadIntervalTimeout,
int ReadTotalTimeoutMultiplier,
int ReadTotalTimeoutConstant,
int WriteTotalTimeoutMultiplier,
int WriteTotalTimeoutConstant) {
SerialTimeouts Timeouts = new SerialTimeouts(ReadIntervalTimeout,
ReadTotalTimeoutMultiplier,
ReadTotalTimeoutConstant,
WriteTotalTimeoutMultiplier,
WriteTotalTimeoutConstant);
unsafe { SetCommTimeouts(m_hFile, ref Timeouts); }
} public bool SetPortSettings(uint baudrate) {
return SetPortSettings(baudrate, FlowControl.Hardware);
} public bool SetPortSettings(uint baudrate, FlowControl flowControl) {
return SetPortSettings(baudrate, flowControl, Parity.None);
} public bool SetPortSettings(uint baudrate, FlowControl flowControl, Parity parity) {
return SetPortSettings(baudrate, flowControl, parity, 8, StopBits.One);
} public bool SetPortSettings(uint baudrate, FlowControl flowControl, Parity parity, byte databits, StopBits stopbits) {
unsafe {
DCB dcb = new DCB();
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = baudrate;
dcb.ByteSize = databits;
dcb.StopBits = (byte)stopbits;
dcb.Parity = (byte)parity;
dcb.fParity = (parity > 0)? 1U : 0U;
dcb.fBinary = dcb.fDtrControl = dcb.fTXContinueOnXoff = 1;
dcb.fOutxCtsFlow = dcb.fAbortOnError = (flowControl == FlowControl.Hardware)? 1U : 0U;
dcb.fOutX = dcb.fInX = (flowControl == FlowControl.XOnXOff)? 1U : 0U;
dcb.fRtsControl = (flowControl == FlowControl.Hardware)? 2U : 1U;
dcb.XonLim = 2048;
dcb.XoffLim = 512;
dcb.XonChar = 0x11; // Ctrl-Q
dcb.XoffChar = 0x13; // Ctrl-S
return SetCommState(m_hFile, ref dcb);
}
} public bool SetPortSettings(DCB dcb) {
return SetCommState(m_hFile, ref dcb);
} public bool GetPortSettings(out DCB dcb) {
unsafe {
DCB dcb2 = new DCB();
dcb2.DCBlength = sizeof(DCB);
bool ret = GetCommState(m_hFile, ref dcb2);
dcb = dcb2;
return ret;
}
}接下:
我给你发过去!