分享
 
 
 

工控串口通讯实现

王朝other·作者佚名  2006-05-27
窄屏简体版  字體: |||超大  

/*************************************************************

EasySoft easycomm v2.0

(c) 2001-2004 EasySoft Corporation. All Rights Reserved.

@doc easycomm.rtf

@module easycomm.h | easycomm interface file

@devnote jdzwq 2003.01 - 2004.10

*************************************************************/

#ifndef _EASYCOMM_H

#define _EASYCOMM_H

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <assert.h>

#include <windows.h>

#include <commctrl.h>

#include <tchar.h>

#ifdef __cplusplus

extern "C" {

#endif

typedef enum{

NC_COMMBREAK = 110,

NC_COMMERROR = 111,

NC_COMMMONITOR = 112,

NC_COMMACK = 113,

NC_COMMRECIVE = 114,

NC_COMMSENT = 115

}NotifyCode;

typedef struct tagNMHDR_COMM{

HWND hwndFrom;

UINT idFrom;

UINT code;

LPARAM lParam;

WPARAM wParam;

}NMHDR_COMM;

#define WM_COMMMSG WM_USER + 10

#define COMMCTRLCLASS _T("CommCtrl")

ATOM RegisterCommCtrlClass(HINSTANCE hInstance);

#define COM_SETPORT WM_COMMMSG + 150

#define COM_GETPORT WM_COMMMSG + 151

#define COM_SETBAUDRATE WM_COMMMSG + 152

#define COM_GETBAUDRATE WM_COMMMSG + 153

#define COM_SETBYTESIZE WM_COMMMSG + 154

#define COM_GETBYTESIZE WM_COMMMSG + 155

#define COM_SETSTOPBITS WM_COMMMSG + 156

#define COM_GETSTOPBITS WM_COMMMSG + 157

#define COM_SETPARITY WM_COMMMSG + 158

#define COM_GETPARITY WM_COMMMSG + 159

#define COM_SETFCTRL WM_COMMMSG + 160

#define COM_GETFCTRL WM_COMMMSG + 161

#define COM_SETTIMEOUTS WM_COMMMSG + 162

#define COM_GETTIMEOUTS WM_COMMMSG + 163

#define COM_SETACKCHAR WM_COMMMSG + 164

#define COM_GETACKCHAR WM_COMMMSG + 165

#define COM_SETLISTIMER WM_COMMMSG + 166

#define COM_GETLISTIMER WM_COMMMSG + 167

#define COM_SETACTIVE WM_COMMMSG + 168

#define COM_GETACTIVE WM_COMMMSG + 169

#define COM_SETDATA WM_COMMMSG + 170

#define COM_GETDATA WM_COMMMSG + 171

#define COM_SETQUEUE WM_COMMMSG + 172

#define COM_POSTERROR WM_COMMMSG + 175

#define COM_POSTRECIVE WM_COMMMSG + 176

#define COM_POSTSENT WM_COMMMSG + 177

#define COM_POSTBREAK WM_COMMMSG + 178

#define COM_POSTACK WM_COMMMSG + 179

#define COM_POSTMONITOR WM_COMMMSG + 180

#define COM_QUERYSEND WM_COMMMSG + 181

#define PY_NONE 0 /*无奇偶校验*/

#define PY_EVEN 1 /*偶校验*/

#define PY_ODD 2 /*奇校验*/

#define PY_MARK 3

#define PY_SPACE 4

#define STOPBITS_ONE 1 /*1位停止位*/

#define STOPBITS_TWO 2 /*2位停止位*/

#define STOPBITS_ONEHALF 3 /*1.5停止位*/

#define FLOWCTRL_NONE 0 /*无流控制*/

#define FLOWCTRL_HARD 1 /*硬件控制*/

#define FLOWCTRL_SOFT 2 /*软件控制*/

#define CE_PARAM -1

#define READ_SUCCESS 0

#define READ_TIMEOUTS 1

#define WRITE_SUCCESS 0

#define WRITE_TIMEOUTS 1

/*端口状态*/

typedef struct _CommMonitor{

BOOL bRLSDHold;

BOOL bCTSHold;

BOOL bDSRHold;

BOOL bXOFFHold;

BOOL bXOFFSent;

int nInQueue;

int nOutQueue;

}CommMonitor;

#ifdef _CHS

#define ERROR_PARAM _T("参数错误")

#define ERROR_BREAK _T("硬件中断")

#define ERROR_FRAME _T("硬件幀错误")

#define ERROR_IOE _T("通讯I/O错误")

#define ERROR_OVERRUM _T("数据丢失")

#define ERROR_RXOVER _T("输入缓冲区溢出")

#define ERROR_RXPARITY _T("硬件校验错误")

#define ERROR_TXFULL _T("输出缓冲区溢出")

#define ERROR_UNKNOWN _T("其他错误")

#else

#define ERROR_PARAM _T("The parameter setup error")

#define ERROR_BREAK _T("The hardware detected a break condition.")

#define ERROR_FRAME _T("The hardware detected a framing error.")

#define ERROR_IOE _T("An I/O error occurred during communications with the device.")

#define ERROR_OVERRUN _T("A character-buffer overrun has occurred. The next character is lost.")

#define ERROR_RXOVER _T("An input buffer overflow has occurred. There is either no room in the input buffer, or a character was received after the end-of-file (EOF) character.")

#define ERROR_RXPARITY _T("The hardware detected a parity error.")

#define ERROR_TXFULL _T("The application tried to transmit a character, but the output buffer was full.")

#define ERROR_UNKNOWN _T("Other error occurred")

#endif

extern void InitCommControl(HINSTANCE hInstance);

extern void UnInitCommControl(HINSTANCE hInstance);

#ifdef __cplusplus

}

#endif

#endif

/*************************************************************

EasySoft easycomm v2.0

(c) 2001-2004 EasySoft Corporation. All Rights Reserved.

@doc easycomm.rtf

@module easycomm.c | easycomm impliment file

@devnote jdzwq 2003.01 - 2004.10

*************************************************************/

#include "easycomm.h"

typedef struct tagCommDelta{

HWND hWnd;

BOOL bActive; /*侦听标志*/

BOOL bReady; /*串口可写标志*/

HANDLE hListen; /*侦听线程句柄*/

DWORD dwListen; /*侦听线程ID*/

OVERLAPPED ovListen; /*用于侦听的重叠操作结构*/

HANDLE hCom; /*端口句柄*/

CRITICAL_SECTION cs; /* 同步临界区*/

short nFlowCtrl; /*流控制模式*/

short nAckChar; /*回应字符*/

short nParity; /*校验方式*/

short nStopBits; /*停止位*/

short nByteSize; /*位长*/

short nReadTimeoutPerByte; /*读每字节超时参数*/

short nWriteTimeoutPerByte; /*写每字节超时参数*/

long nListenTimeout; /*侦听超时*/

long nBaudRate; /*波特率*/

long nInQueue; /*输入缓冲区大小*/

long nOutQueue; /*输出缓冲区大小*/

TCHAR szPort[10]; /*端口*/

}CommDelta;

/*定义线程操作结构*/

typedef struct _OperaParam

{

HANDLE hCom; /*串口句柄*/

LPCRITICAL_SECTION pcs; /*临界区引用*/

DWORD dwDataBytes; /*请求操作字节数*/

DWORD dwOperaBytes; /*实际操作字节数*/

BYTE* data; /*读写数据指针*/

short nRetCode;

}OperaParam;

#define GETCOMMDELTA(hWnd) ((CommDelta*)GetWindowLong(hWnd,GWL_USERDATA))

#define SETCOMMDELTA(hWnd,ptd) SetWindowLong(hWnd,GWL_USERDATA,(LONG)ptd)

LRESULT CALLBACK CommCtrlProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

void COM_Paint(HWND hWnd,HDC hDC);

int COM_SendSign(HWND hWnd,UINT sign, WPARAM wParam,LPARAM lParam);

BOOL COM_Active(HWND hWnd,BOOL bActive);

long COM_SendData(HWND hWnd,long size,BYTE* data);

long COM_ReciveData(HWND hWnd,long size,BYTE* data);

DWORD WINAPI ListenProc(LPVOID lpParam);

DWORD WINAPI WriteProc(LPVOID lpParam);

void* _CommAlloc(long size);

void _CommFree(void* data);

ATOM RegisterCommCtrlClass(HINSTANCE hInstance)

{

WNDCLASS wcex;

#ifdef _WINDOWS

wcex.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;

#else

wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;

#endif

wcex.lpfnWndProc = (WNDPROC)CommCtrlProc;

wcex.cbClsExtra = 0;

wcex.cbWndExtra = 0;

wcex.hInstance = hInstance;

wcex.hIcon = NULL;

wcex.hCursor = LoadCursor(NULL, IDC_ARROW);

wcex.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);

wcex.lpszMenuName = NULL;

wcex.lpszClassName = COMMCTRLCLASS;

return RegisterClass(&wcex);

}

LRESULT CALLBACK CommCtrlProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

CommDelta* ptd = GETCOMMDELTA(hWnd);

PAINTSTRUCT ps;

int n;

switch(message)

{

case WM_CREATE:

ptd = (CommDelta*)calloc(1,sizeof(CommDelta));

ptd->hWnd = hWnd;

/*默认参数配置*/

lstrcpy(ptd->szPort,_T("COM1"));

ptd->nReadTimeoutPerByte = ptd->nWriteTimeoutPerByte = 10;

ptd->nListenTimeout = 5000;

ptd->nFlowCtrl = 0;

ptd->nAckChar = 0;

ptd->nParity = 0;

ptd->nStopBits = 1;

ptd->nByteSize = 8;

ptd->nBaudRate = 1200;

ptd->bReady = FALSE;

ptd->bActive = FALSE;

ptd->hCom = INVALID_HANDLE_VALUE;

ptd->hListen = NULL;

InitializeCriticalSection(&ptd->cs);

SETCOMMDELTA(hWnd,ptd);

break;

case WM_DESTROY:

if(ptd->bActive)

SendMessage(hWnd,COM_SETACTIVE,(WPARAM)FALSE,0);

DeleteCriticalSection(&ptd->cs);

free(ptd);

break;

case WM_PAINT:

if(GetUpdateRect(hWnd,NULL,TRUE))

{

BeginPaint(hWnd,&ps);

COM_Paint(hWnd,ps.hdc);

EndPaint(hWnd,&ps);

}

case COM_SETPORT:

if(lParam)

{

n = _tcslen((TCHAR*)lParam);

n = (n < 9)? n : 9;

_tcsncpy(ptd->szPort,(TCHAR*)lParam,n);

(ptd->szPort)[n] = _T('\0');

}

return 0;

case COM_GETPORT:

if(lParam)

{

n = _tcslen(ptd->szPort);

n = (n < (int)wParam)? n : (int)wParam;

_tcsncpy((TCHAR*)lParam,ptd->szPort,n);

((TCHAR*)lParam)[n] = _T('\0');

}

return 0;

case COM_GETBAUDRATE:

return (LRESULT)ptd->nBaudRate;

case COM_SETBAUDRATE:

ptd->nBaudRate = (long)wParam;

return 0;

case COM_GETBYTESIZE:

return (LRESULT)ptd->nByteSize;

case COM_SETBYTESIZE:

ptd->nByteSize = (short)wParam;

return 0;

case COM_GETSTOPBITS:

return (LRESULT)ptd->nStopBits;

case COM_SETSTOPBITS:

ptd->nStopBits = (short)wParam;

return 0;

case COM_GETPARITY:

return (LRESULT)ptd->nParity;

case COM_SETPARITY:

ptd->nParity = (short)wParam;

return 0;

case COM_GETFCTRL:

return ptd->nFlowCtrl;

case COM_SETFCTRL:

ptd->nFlowCtrl = (short)wParam;

return 0;

case COM_GETTIMEOUTS:

return (LRESULT)MAKEWPARAM((WORD)ptd->nReadTimeoutPerByte,(WORD)ptd->nWriteTimeoutPerByte);

case COM_SETTIMEOUTS:

ptd->nReadTimeoutPerByte = (short)LOWORD(wParam);

ptd->nWriteTimeoutPerByte = (short)HIWORD(wParam);

return 0;

case COM_GETACKCHAR:

return (LRESULT)ptd->nAckChar;

case COM_SETACKCHAR:

ptd->nAckChar = (short)wParam;

return 0;

case COM_GETLISTIMER:

return (LRESULT)ptd->nListenTimeout;

case COM_SETLISTIMER:

ptd->nListenTimeout = (long)wParam;

return 0;

case COM_SETQUEUE:

ptd->nInQueue = (long)wParam;

ptd->nOutQueue = (long)lParam;

return 0;

case COM_GETACTIVE:

return (LRESULT)ptd->bActive;

case COM_SETACTIVE:

return (LRESULT)COM_Active(hWnd,(BOOL)wParam);

case COM_SETDATA:

return (LRESULT)COM_SendData(hWnd,(long)wParam,(BYTE*)lParam);

case COM_GETDATA:

return (LRESULT)COM_ReciveData(hWnd,(long)wParam,(BYTE*)lParam);

case COM_POSTBREAK:

COM_SendSign(hWnd,NC_COMMBREAK,0,0);

return 0;

case COM_POSTERROR:

COM_SendSign(hWnd,NC_COMMERROR,wParam,lParam);

if(lParam)

_CommFree((void*)lParam);

return 0;

case COM_POSTMONITOR:

COM_SendSign(hWnd,NC_COMMMONITOR,wParam,lParam);

if(lParam)

_CommFree((void*)lParam);

return 0;

case COM_POSTACK:

COM_SendSign(hWnd,NC_COMMACK,(long)wParam,0);

return 0;

case COM_POSTRECIVE:

COM_SendSign(hWnd,NC_COMMRECIVE,(long)wParam,0);

return 0;

case COM_POSTSENT:

COM_SendSign(hWnd,NC_COMMSENT,(long)wParam,0);

return 0;

case COM_QUERYSEND:

return (LRESULT)ptd->bReady;

}

return DefWindowProc(hWnd,message,wParam,lParam);

}

void* _CommAlloc(long size)

{

return (TCHAR*)GlobalLock(GlobalAlloc(GHND,size));

}

void _CommFree(void* data)

{

GlobalUnlock((HGLOBAL)data);

GlobalFree((HGLOBAL)data);

}

void _FormatCommError(DWORD errcode,TCHAR* buf)

{

switch(errcode)

{

case CE_PARAM:

_tcscpy(buf,ERROR_PARAM);

break;

case CE_BREAK:

_tcscpy(buf,ERROR_BREAK);

break;

case CE_FRAME:

_tcscpy(buf,ERROR_FRAME);

break;

case CE_IOE:

_tcscpy(buf,ERROR_IOE);

break;

case CE_OVERRUN:

_tcscpy(buf,ERROR_OVERRUN);

break;

case CE_RXOVER:

_tcscpy(buf,ERROR_RXOVER);

break;

case CE_RXPARITY:

_tcscpy(buf,ERROR_RXPARITY);

break;

case CE_TXFULL:

_tcscpy(buf,ERROR_TXFULL);

break;

default:

_tcscpy(buf,ERROR_UNKNOWN);

break;

}

}

DWORD _InternalRead(HWND hWnd,DWORD size, void *buf)

{

CommDelta* ptd = GETCOMMDELTA(hWnd);

DWORD dwOperaBytes = 0;

if(ptd->hCom == INVALID_HANDLE_VALUE)

return 0;

ReadFile(ptd->hCom,buf,size,&dwOperaBytes,NULL);

return dwOperaBytes;

}

BOOL _InternalOpen(HWND hWnd)

{

CommDelta* ptd = GETCOMMDELTA(hWnd);

TCHAR szFile[20];

DCB dcb;

COMMTIMEOUTS to;

TCHAR* mem;

_stprintf(szFile,_T("\\\\.\\%s"),ptd->szPort);

/*打开端口文件*/

ptd->hCom = CreateFile(szFile,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,NULL);

if(ptd->hCom == INVALID_HANDLE_VALUE)

return FALSE;

/*配置端口参数*/

memset((void*)&dcb,0,sizeof(DCB));

dcb.DCBlength = sizeof(DCB);

GetCommState(ptd->hCom,&dcb);

switch(ptd->nBaudRate)

{

case 110:

dcb.BaudRate = CBR_110;

break;

case 300:

dcb.BaudRate = CBR_300;

break;

case 600:

dcb.BaudRate = CBR_600;

break;

case 1200:

dcb.BaudRate = CBR_1200;

break;

case 2400:

dcb.BaudRate = CBR_2400;

break;

case 4800:

dcb.BaudRate = CBR_4800;

break;

case 9600:

dcb.BaudRate = CBR_9600;

break;

case 14400:

dcb.BaudRate = CBR_14400;

break;

case 19200:

dcb.BaudRate = CBR_19200;

break;

case 38400:

dcb.BaudRate = CBR_38400;

break;

case 56000:

dcb.BaudRate = CBR_56000;

break;

case 57600 :

dcb.BaudRate = CBR_57600;

break;

case 115200 :

dcb.BaudRate = CBR_115200;

break;

case 128000 :

dcb.BaudRate = CBR_128000;

break;

case 256000 :

dcb.BaudRate = CBR_256000;

break;

default:

ptd->nBaudRate = 1200;

dcb.BaudRate = CBR_1200;

}

switch(ptd->nByteSize)

{

case 5:

case 6:

case 7:

case 8:

dcb.ByteSize = (BYTE)ptd->nByteSize;

break;

default:

ptd->nByteSize = 8;

dcb.ByteSize = 8;

}

switch(ptd->nStopBits)

{

case STOPBITS_ONE:

dcb.StopBits = ONESTOPBIT;

break;

case STOPBITS_TWO:

dcb.StopBits = TWOSTOPBITS;

break;

case STOPBITS_ONEHALF:

dcb.StopBits = ONE5STOPBITS;

break;

default:

ptd->nStopBits = STOPBITS_ONE;

dcb.StopBits = ONESTOPBIT;

break;

}

switch(ptd->nParity)

{

case PY_NONE:

dcb.Parity = NOPARITY;

break;

case PY_EVEN:

dcb.Parity = EVENPARITY;

break;

case PY_ODD:

dcb.Parity = ODDPARITY;

break;

case PY_MARK:

dcb.Parity = MARKPARITY;

break;

case PY_SPACE:

dcb.Parity = SPACEPARITY;

break;

default:

ptd->nParity = PY_NONE;

dcb.Parity = NOPARITY;

break;

}

switch(ptd->nFlowCtrl)

{

case FLOWCTRL_NONE:

dcb.fInX = FALSE;

dcb.fOutX = FALSE;

dcb.fOutxDsrFlow = FALSE;

dcb.fOutxCtsFlow = FALSE;

dcb.fDtrControl = DTR_CONTROL_ENABLE;

dcb.fRtsControl = RTS_CONTROL_ENABLE;

break;

case FLOWCTRL_HARD:

dcb.fInX = FALSE;

dcb.fOutX = FALSE;

dcb.fOutxDsrFlow = TRUE;

dcb.fOutxCtsFlow = TRUE;

dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;

dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;

break;

case FLOWCTRL_SOFT:

dcb.fInX = TRUE;

dcb.fOutX = TRUE;

dcb.fOutxDsrFlow = FALSE;

dcb.fOutxCtsFlow = FALSE;

dcb.fDtrControl = DTR_CONTROL_ENABLE;

dcb.fRtsControl = RTS_CONTROL_ENABLE;

break;

default:

ptd->nFlowCtrl = FLOWCTRL_NONE;

dcb.fInX = FALSE;

dcb.fOutX = FALSE;

dcb.fOutxDsrFlow = FALSE;

dcb.fOutxCtsFlow = FALSE;

dcb.fDtrControl = DTR_CONTROL_ENABLE;

dcb.fRtsControl = RTS_CONTROL_ENABLE;

break;

}

if(ptd->nAckChar)

dcb.EvtChar = (char)ptd->nAckChar;

if(!SetCommState(ptd->hCom,&dcb))

{

mem = (TCHAR*)_CommAlloc(256 * sizeof(TCHAR));

_FormatCommError(CE_PARAM,mem);

PostMessage(hWnd,COM_POSTERROR,(WPARAM)_tcslen(mem),(LPARAM)mem);

}

GetCommTimeouts(ptd->hCom,&to);

to.ReadTotalTimeoutConstant = 500;

to.WriteTotalTimeoutConstant = 500;

to.ReadTotalTimeoutMultiplier = ptd->nReadTimeoutPerByte;

to.WriteTotalTimeoutMultiplier = ptd->nWriteTimeoutPerByte;

if(!SetCommTimeouts(ptd->hCom,&to))

{

mem = (TCHAR*)_CommAlloc(256 * sizeof(TCHAR));

_FormatCommError(CE_PARAM,mem);

PostMessage(hWnd,COM_POSTERROR,(WPARAM)_tcslen(mem),(LPARAM)mem);

}

return TRUE;

}

BOOL _InternalClose(HWND hWnd)

{

CommDelta* ptd = GETCOMMDELTA(hWnd);

if(ptd->hCom != INVALID_HANDLE_VALUE)

{

CloseHandle(ptd->hCom);

}

ptd->hCom = INVALID_HANDLE_VALUE;

return TRUE;

}

BOOL COM_Active(HWND hWnd,BOOL newVal)

{

CommDelta* ptd = GETCOMMDELTA(hWnd);

if(newVal)

{

if(ptd->bActive)

return TRUE;

/*打开端口*/

if(!_InternalOpen(hWnd))

return FALSE;

ptd->ovListen.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

ptd->bActive = TRUE;

/*创建侦听线程*/

ptd->hListen = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ListenProc,(LPVOID)ptd,0,&ptd->dwListen);

if(ptd->hListen == NULL)

{

_InternalClose(hWnd);

CloseHandle(ptd->ovListen.hEvent);

memset((void*)&ptd->ovListen,0,sizeof(OVERLAPPED));

ptd->bActive = FALSE;

return FALSE;

}

ptd->bReady = TRUE;

Sleep(100); /*让线程运行*/

return TRUE;

}else

{

if(!ptd->bActive)

return TRUE;

EnterCriticalSection(&ptd->cs);

ptd->bActive = FALSE;

ptd->bReady = FALSE;

LeaveCriticalSection(&ptd->cs);

Sleep(100); /*让线程终止*/

/*等待侦听线程中止*/

WaitForSingleObject(ptd->ovListen.hEvent,ptd->nListenTimeout);

/*关闭线程句柄*/

TerminateThread(ptd->hListen,0);

CloseHandle(ptd->hListen);

CloseHandle(ptd->ovListen.hEvent);

memset((void*)&ptd->ovListen,0,sizeof(OVERLAPPED));

/*关闭端口*/

_InternalClose(hWnd);

return TRUE;

}

}

DWORD WINAPI ListenProc(LPVOID lpParam)

{

CommDelta* pCom = (CommDelta*)lpParam;

DWORD dwMask,dwError;

COMSTAT cst;

TCHAR* err;

CommMonitor* pm;

BOOL bActive;

EnterCriticalSection(&pCom->cs);

/*清空输入流和输出流*/

PurgeComm(pCom->hCom,PURGE_TXABORT | PURGE_TXCLEAR);

PurgeComm(pCom->hCom,PURGE_RXABORT | PURGE_RXCLEAR);

switch(pCom->nFlowCtrl)

{

case FLOWCTRL_NONE: /*无流控制*/

dwMask = EV_BREAK | EV_RXCHAR | EV_RXFLAG | EV_ERR | EV_TXEMPTY;

SetCommMask(pCom->hCom,dwMask);

break;

case FLOWCTRL_HARD: /*硬件控制*/

dwMask = EV_BREAK | EV_CTS | EV_DSR | EV_RXCHAR | EV_RXFLAG | EV_ERR | EV_TXEMPTY;

SetCommMask(pCom->hCom,dwMask);

/*通知DCE可以输出数据*/

EscapeCommFunction(pCom->hCom,SETRTS);

EscapeCommFunction(pCom->hCom,SETDTR);

break;

case FLOWCTRL_SOFT: /*Xon/Xoff控制*/

dwMask = EV_BREAK | EV_RXCHAR | EV_RXFLAG | EV_ERR | EV_TXEMPTY;

SetCommMask(pCom->hCom,dwMask);

break;

default:

dwMask = EV_BREAK | EV_RXCHAR |EV_RXFLAG | EV_ERR | EV_TXEMPTY;

SetCommMask(pCom->hCom,dwMask);

break;

}

LeaveCriticalSection(&pCom->cs);

bActive = pCom->bActive;

while(bActive)

{

/*异步等待端口事件*/

dwMask = 0;

/*重制信号*/

ResetEvent(pCom->ovListen.hEvent);

EnterCriticalSection(&pCom->cs);

WaitCommEvent(pCom->hCom,&dwMask,&pCom->ovListen);

LeaveCriticalSection(&pCom->cs);

WaitForSingleObject(pCom->ovListen.hEvent,INFINITE);

switch(dwMask)

{

case EV_BREAK:

PostMessage(pCom->hWnd,COM_POSTBREAK,0,0);

break;

case EV_CTS:

case EV_DSR:

ClearCommError(pCom->hCom,&dwError,&cst);

pm = (CommMonitor*)_CommAlloc(sizeof(CommMonitor));

pm->bCTSHold = cst.fCtsHold;

pm->bDSRHold = cst.fDsrHold;

pm->bRLSDHold = cst.fRlsdHold;

pm->bXOFFHold = cst.fXoffHold;

pm->bXOFFSent = cst.fXoffSent;

pm->nInQueue = cst.cbInQue;

pm->nOutQueue = cst.cbOutQue;

PostMessage(pCom->hCom,COM_POSTMONITOR,(WPARAM)sizeof(CommMonitor),(LPARAM)pm);

break;

case EV_ERR:

ClearCommError(pCom->hCom,&dwError,&cst);

if(dwError == CE_RXOVER)

{

PurgeComm(pCom->hCom,PURGE_RXCLEAR);

}else if(dwError == CE_TXFULL)

{

PurgeComm(pCom->hCom,PURGE_TXCLEAR);

}else

{

PurgeComm(pCom->hCom,PURGE_TXABORT | PURGE_TXCLEAR);

PurgeComm(pCom->hCom,PURGE_RXABORT | PURGE_RXCLEAR);

}

err = (TCHAR*)_CommAlloc(256 * sizeof(TCHAR));

_FormatCommError(dwError,err);

PostMessage(pCom->hWnd,COM_POSTERROR,(WPARAM)dwError,(LPARAM)err);

break;

case EV_RXFLAG:

case EV_RXCHAR:

ClearCommError(pCom->hCom,&dwError,&cst);

if(dwMask == EV_RXCHAR)

PostMessage(pCom->hWnd,COM_POSTRECIVE,(WPARAM)cst.cbInQue,0);

else

PostMessage(pCom->hWnd,COM_POSTACK,(WPARAM)cst.cbInQue,0);

break;

case EV_TXEMPTY:

EnterCriticalSection(&pCom->cs);

/*允许后继写入*/

pCom->bReady = TRUE;

LeaveCriticalSection(&pCom->cs);

PostMessage(pCom->hWnd,COM_POSTSENT,0,0); /*通知端口可写*/

break;

}

/*查询主线程终止信号*/

EnterCriticalSection(&pCom->cs);

bActive = pCom->bActive;

LeaveCriticalSection(&pCom->cs);

}

EnterCriticalSection(&pCom->cs);

/*通知DCE停止数据传输*/

if(pCom->nFlowCtrl == FLOWCTRL_HARD)

{

EscapeCommFunction(pCom->hCom,CLRRTS);

EscapeCommFunction(pCom->hCom,CLRDTR);

}

/*撤销输入流和输出流*/

PurgeComm(pCom->hCom,PURGE_TXABORT | PURGE_TXCLEAR);

PurgeComm(pCom->hCom,PURGE_RXABORT | PURGE_RXCLEAR);

LeaveCriticalSection(&pCom->cs);

/*通知主线程,本线程结束*/

SetEvent(pCom->ovListen.hEvent);

return 0;

}

DWORD WINAPI ReadProc(LPVOID lpParam)

{

OperaParam* pop = (OperaParam*)lpParam;

OVERLAPPED ov;

COMMTIMEOUTS to;

/*取读超时参数*/

GetCommTimeouts(pop->hCom,&to);

/*创建异步写事件*/

memset((void*)&ov,0,sizeof(OVERLAPPED));

ov.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

/*端口异步读*/

EnterCriticalSection(pop->pcs);

ReadFile(pop->hCom,(void*)pop->data,pop->dwDataBytes,&(pop->dwOperaBytes),&ov);

LeaveCriticalSection(pop->pcs);

/*等待异步读结果*/

if(WAIT_OBJECT_0 != WaitForSingleObject(ov.hEvent,to.ReadTotalTimeoutConstant + to.ReadTotalTimeoutMultiplier * pop->dwDataBytes))

{

/*中止未完成的异步读*/

PurgeComm(pop->hCom,PURGE_RXABORT | PURGE_RXCLEAR);

pop->nRetCode = READ_TIMEOUTS;

}else

{

pop->nRetCode = READ_SUCCESS;

}

/*取读结果*/

GetOverlappedResult(pop->hCom,&ov,&(pop->dwOperaBytes),FALSE);

CloseHandle(ov.hEvent);

return 0;

}

DWORD WINAPI WriteProc(LPVOID lpParam)

{

OperaParam* pop = (OperaParam*)lpParam;

OVERLAPPED ov;

COMMTIMEOUTS to;

/*取写超时参数*/

GetCommTimeouts(pop->hCom,&to);

/*创建异步写事件*/

memset((void*)&ov,0,sizeof(OVERLAPPED));

ov.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

/*端口异步写*/

EnterCriticalSection(pop->pcs);

WriteFile(pop->hCom,(void*)pop->data,pop->dwDataBytes,&(pop->dwOperaBytes),&ov);

LeaveCriticalSection(pop->pcs);

/*等待异步写结果*/

if(WAIT_OBJECT_0 != WaitForSingleObject(ov.hEvent,to.WriteTotalTimeoutConstant + to.WriteTotalTimeoutMultiplier * pop->dwDataBytes))

{

/*中止未完成的异步写*/

PurgeComm(pop->hCom,PURGE_TXABORT | PURGE_TXCLEAR);

pop->nRetCode = WRITE_TIMEOUTS;

}else

{

pop->nRetCode = WRITE_SUCCESS;

}

/*取写结果*/

GetOverlappedResult(pop->hCom,&ov,&(pop->dwOperaBytes),FALSE);

CloseHandle(ov.hEvent);

return 0;

}

long COM_SendData(HWND hWnd,long size, BYTE* data)

{

CommDelta* pCom = GETCOMMDELTA(hWnd);

HANDLE hWrite;

DWORD dw;

OperaParam op;

if(!pCom->bActive)

return -1;

if(!pCom->bReady)

return -1;

//禁止后继写入

pCom->bReady = FALSE;

memset((void*)&op,0,sizeof(OperaParam));

op.hCom = pCom->hCom;

op.pcs = &pCom->cs;

op.data = data;

op.dwDataBytes = size;

/*异步写线程*/

hWrite = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WriteProc,(void*)&op,0,&dw);

if(hWrite)

{

/*等待线程结束*/

WaitForSingleObject(hWrite,INFINITE);

CloseHandle(hWrite);

}else

op.dwOperaBytes = -1;

return op.dwOperaBytes;

}

long COM_ReciveData(HWND hWnd,long size, BYTE* data)

{

CommDelta* pCom = GETCOMMDELTA(hWnd);

HANDLE hRead;

DWORD dw;

OperaParam op;

if(!pCom->bActive)

return -1;

memset((void*)&op,0,sizeof(OperaParam));

op.hCom = pCom->hCom;

op.pcs = &pCom->cs;

op.data = data;

op.dwDataBytes = size;

/*异步读线程*/

hRead = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ReadProc,(void*)&op,0,&dw);

if(hRead)

{

/*等待线程结束*/

WaitForSingleObject(hRead,INFINITE);

CloseHandle(hRead);

}else

op.dwOperaBytes = -1;

return op.dwOperaBytes;

}

int COM_SendSign(HWND hWnd,UINT sign, WPARAM wParam,LPARAM lParam)

{

CommDelta* ptd = GETCOMMDELTA(hWnd);

NMHDR_COMM hdr;

hdr.hwndFrom = hWnd;

hdr.idFrom = GetWindowLong(hWnd,GWL_ID);

hdr.code = sign;

hdr.wParam = wParam;

hdr.lParam = lParam;

return (int)SendMessage(GetParent(hWnd),WM_NOTIFY,hdr.idFrom,(LPARAM)&hdr);

}

void COM_Paint(HWND hWnd,HDC hDC)

{

RECT rt;

GetClientRect(hWnd,&rt);

DrawText(hDC,_T("EasyComm"),-1,&rt,DT_CENTER | DT_SINGLELINE | DT_VCENTER);

}

void InitCommControl(HINSTANCE hInstance)

{

HINSTANCE hInst = (hInstance)? hInstance : GetModuleHandle(NULL);

RegisterCommCtrlClass(hInst);

}

void UnInitCommControl(HINSTANCE hInstance)

{

HINSTANCE hInst = (hInstance)? hInstance : GetModuleHandle(NULL);

UnregisterClass(COMMCTRLCLASS,hInst);

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有