📄 _com.h
字号:
return write(buf, strlen(buf));
}
//异步写, 支持部分类型的流输出
template<typename T>
_asyn_com& operator << (T x)
{
strstream s;
s << x ;
write(s.str(), s.pcount());
return *this;
}
};
//当接受到数据送到窗口的消息
#define ON_COM_RECEIVE WM_USER + 618 // WPARAM 端口号
class _thread_com : public _asyn_com
{
protected:
volatile HANDLE _thread_handle; //辅助线程
volatile HANDLE _file_thread_handle; //文件辅助线程
CString m_filename; //文件名
volatile HWND _notify_hwnd; // 通知窗口
volatile long _notify_num;//接受多少字节(>_notify_num)发送通知消息
volatile bool _run_flag; //线程运行循环标志
void (*_func)(WPARAM wp, LPARAM lp);
// GPSParam gps; //存储临时gps返回参数
OVERLAPPED _wait_o; //WaitCommEvent use
//线程收到消息自动调用, 如窗口句柄有效, 送出消息, 包含窗口编号
virtual void on_receive()
{
char str[270];
memset(str,10,270);
this->read(str,270);
int j=0;
bool start=false;
char order[90];
for( int i=0; i<270; i++)
{
switch(str[i])
{
case '$':
start=true;
order[0]='$';
j=1;
break;
case 10:
if( start ) //得到一个完整指令
{
////////////////////////////////////
///如果,消息响应不及时,gps内存有可能泄露
GPSParam *gps=new GPSParam;
gps->SetParam(order,90);
if(gps->DataTransform())
{
if(_notify_hwnd)
{
PostMessage( _notify_hwnd, ON_COM_RECEIVE, WPARAM(gps), 0 );
}
else
; ///////////////////
}
//////////////////////////////////////////////////////
/*
//GPSParam gps(order,90);
gps.SetParam(order,j);
if(gps.DataTransform())
{
if(_notify_hwnd)
PostMessage( _notify_hwnd, ON_COM_RECEIVE, WPARAM(gps.X), LPARAM(gps.Y) );
else
; ///////////////////
}
*/
}
start=false;
j=0;
memset(order,0,90);
break;
default:
{
if( start )
{
order[j]=str[i];
j++;
}
}
}
}
/*
if(_notify_hwnd)
PostMessage(_notify_hwnd, ON_COM_RECEIVE, WPARAM(_port), LPARAM(0));
else
{
if(_func)
_func(_port);
}
*/
}
//打开串口,同时打开监视线程
virtual bool open_port()
{
if(_asyn_com::open_port())
{
_run_flag = true;
DWORD id;
_thread_handle = CreateThread(NULL, 0, com_thread, this, 0, &id); //辅助线程
assert(_thread_handle);
if(!_thread_handle)
{
CloseHandle(_com_handle);
_com_handle = INVALID_HANDLE_VALUE;
}
else
return true;
}
return false;
}
public:
_thread_com()
{
_notify_num = 250;
_notify_hwnd = NULL;
_thread_handle = NULL;
_file_thread_handle = NULL;
_func = NULL;
memset(&_wait_o, 0, sizeof(_wait_o));
_wait_o.hEvent = CreateEvent(NULL, true, false, NULL);
assert(_wait_o.hEvent != INVALID_HANDLE_VALUE);
}
~_thread_com()
{
close();
if(_wait_o.hEvent != INVALID_HANDLE_VALUE)
CloseHandle(_wait_o.hEvent);
}
//设定发送通知, 接受字符最小值
void set_notify_num(int num)
{
_notify_num = num;
}
int get_notify_num()
{
return _notify_num;
}
//送消息的窗口句柄
inline void set_hwnd(HWND hWnd)
{
_notify_hwnd = hWnd;
}
inline HWND get_hwnd()
{
return _notify_hwnd;
}
inline void set_func(void (*f)(WPARAM wp, LPARAM lp))
{
_func = f;
}
//关闭线程及串口
virtual void close()
{
if(is_open())
{
_run_flag = false;
SetCommMask(_com_handle, 0);
SetEvent(_wait_o.hEvent);
if(WaitForSingleObject(_thread_handle, 100) != WAIT_OBJECT_0)
TerminateThread(_thread_handle, 0);
CloseHandle(_com_handle);
CloseHandle(_thread_handle);
_thread_handle = NULL;
_com_handle = INVALID_HANDLE_VALUE;
ResetEvent(_wait_o.hEvent);
}
}
/*辅助线程控制*/
//获得线程句柄
HANDLE get_thread()
{
return _thread_handle;
}
//暂停监视线程
bool suspend()
{
return _thread_handle != NULL ? SuspendThread(_thread_handle) != 0xFFFFFFFF : false;
}
//恢复监视线程
bool resume()
{
return _thread_handle != NULL ? ResumeThread(_thread_handle) != 0xFFFFFFFF : false;
}
//重建监视线程
bool restart()
{
if(_thread_handle) /*只有已有存在线程时*/
{
_run_flag = false;
SetCommMask(_com_handle, 0);
SetEvent(_wait_o.hEvent);
if(WaitForSingleObject(_thread_handle, 100) != WAIT_OBJECT_0)
TerminateThread(_thread_handle, 0);
CloseHandle(_thread_handle);
_run_flag = true;
_thread_handle = NULL;
DWORD id;
_thread_handle = CreateThread(NULL, 0, com_thread, this, 0, &id);
return (_thread_handle != NULL); //辅助线程
}
return false;
}
bool Open_file(CString str)
{
if (_file_thread_handle ==NULL)
{
m_filename=str;
DWORD id;
_file_thread_handle=CreateThread(NULL,0,file_thread,this,0,&id);
return (_file_thread_handle != NULL);
}
return false;
}
private:
//监视线程
static DWORD WINAPI com_thread(LPVOID para)
{
_thread_com *pcom = (_thread_com *)para;
//制定串口的监视事件 接收到一个字符 或者出现错误
if(!SetCommMask(pcom->_com_handle, EV_RXCHAR | EV_ERR | EV_RXFLAG ) )
return 0;
COMSTAT stat;
DWORD error;
for(DWORD length, mask = 0; pcom->_run_flag && pcom->is_open(); mask = 0)
{
if(!WaitCommEvent(pcom->_com_handle, &mask, &pcom->_wait_o))
{
if(GetLastError() == ERROR_IO_PENDING)
{
GetOverlappedResult(pcom->_com_handle, &pcom->_wait_o, &length, true);
}
}
//错误处理
if ( mask & EV_ERR ) //线上错误
ClearCommError(pcom->_com_handle, &error, &stat);
//接收到事件字符
if( mask & EV_RXFLAG ) // EV_RXFLAG事件产生
{
ClearCommError(pcom->_com_handle, &error, &stat);
pcom->on_receive();
}
//接收到一个字符处理
if(mask & EV_RXCHAR) // == EV_RXCHAR
{
ClearCommError(pcom->_com_handle, &error, &stat);
if(stat.cbInQue > pcom->_notify_num)
pcom->on_receive();
}
}
return 0;
}
static DWORD WINAPI file_thread(LPVOID para)
{
_thread_com *pcom = (_thread_com *)para;
ifstream in;
in.open(pcom->m_filename);
while (true)
{
// Sleep(5);
char str[270];
memset(str,10,270);
if( !in.getline(str,270) )
break;
int j=0;
bool start=false;
char order[90]; //存储一条指令
for( int i=0; i<270; i++)
{
switch(str[i])
{
case '$':
start=true;
order[0]='$';
j=1;
break;
case 10:
if( start ) //得到一个完整指令
{
GPSParam *gps=new GPSParam;
gps->SetParam(order,90);
if(gps->DataTransform())
{
if(pcom->_notify_hwnd)
{
PostMessage( pcom->_notify_hwnd, ON_COM_RECEIVE, WPARAM(gps), 0 );
}
else
delete gps; ///////////////////
/*
if( pcom->_func )
{
// pcom->_func( (WPARAM)gps,(LPARAM)pcom->_notify_hwnd );
}
else
delete gps;
*/
}
else
delete gps;
// delete gps;
}
start=false;
j=0;
memset(order,0,90);
break;
default:
{
if( start )
{
order[j]=str[i];
j++;
}
}
}
}
}
return 0;
}
};
typedef _thread_com _com; //名称简化
#endif //_COM_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -