[摘要]需要说明的是:这是程序的一部分,因此有一些与具体应用无关的部分。 关键是原理,而不是程序本身.后面有些使用介绍,帮助理解这长的程序。 头文件(.H) #include "StdAfx.h&...
需要说明的是:这是程序的一部分,因此有一些与具体应用无关的部分。 
关键是原理,而不是程序本身.后面有些使用介绍,帮助理解这长的程序。 
头文件(.H) 
#include "StdAfx.h" 
#define GWL_PGPSINFO 0 
#define GPSEXTRABYTES sizeof( LONG ) 
#define MAXPORTS 4 
#define CN_SEND WM_USER+100 
#define RXQUEUE 4096 
#define TXQUEUE 4096 
// cursor states 
#define CS_HIDE 0x00 
#define CS_SHOW 0x01 
// Flow control flags 
#define FC_DTRDSR 0x01 
#define FC_RTSCTS 0x02 
#define FC_XONXOFF 0x04 
// ascii definitions 
#define ASCII_BEL 0x07 
#define ASCII_BS 0x08 
#define ASCII_LF 0x0A 
#define ASCII_CR 0x0D 
#define ASCII_XON 0x11 
#define ASCII_XOFF 0x13 
// data structures 
typedef struct tagGPSINFO 
{ 
HANDLE idComDev; 
BYTE bPort; 
BOOL fConnected; 
BYTE bByteSize,bParity,bStopBits; 
DWORD dwBaudRate; 
HANDLE hPostEvent,hWatchThread,hWatchEvent; 
HWND hTermWnd; 
DWORD dwThreadID; 
OVERLAPPED osWrite,osRead; 
} GPSINFO, *PGPSINFO ; 
#define COMDEV( x ) (x -> idComDev) 
#define PORT( x ) (x -> bPort) 
#define CONNECTED( x ) (x -> fConnected) 
#define BYTESIZE( x ) (x -> bByteSize) 
#define PARITY( x ) (x -> bParity) 
#define STOPBITS( x ) (x -> bStopBits) 
#define BAUDRATE( x ) (x -> dwBaudRate) 
#define POSTEVENT( x ) (x -> hPostEvent) 
#define HTHREAD( x ) (x -> hWatchThread) 
#define THREADID( x ) (x -> dwThreadID) 
#define WRITE_OS( x ) (x -> osWrite) 
#define READ_OS( x ) (x -> osRead) 
// function prototypes (private) 
LRESULT NEAR CreateGPSInfo(HWND,BYTE nPort=1); 
BOOL NEAR DestroyGPSInfo(); 
int NEAR ReadCommBlock(LPSTR,int); 
BOOL NEAR WriteCommBlock(LPSTR,DWORD); 
BOOL NEAR OpenConnection(); 
BOOL NEAR SetupConnection(); 
BOOL NEAR CloseConnection(); 
// function prototypes (public) 
DWORD FAR PASCAL CommWatchProc(LPSTR); 
具体实现请看下文(为了这文章,我都段线2次了) 
CPP实现部分: 
#include "StdAfx.h" 
#include "Com.h" 
HWND hGPSWnd=NULL; 
PGPSINFO npGPSInfo=NULL; 
LRESULT NEAR CreateGPSInfo(HWND hWnd,BYTE nPort) 
{ 
if (NULL==(npGPSInfo=(PGPSINFO)LocalAlloc(LPTR,sizeof(GPSINFO)))) 
return ((LRESULT)-1) ; 
hGPSWnd=hWnd; 
COMDEV(npGPSInfo)=0; 
CONNECTED(npGPSInfo)=FALSE; 
PORT(npGPSInfo)=nPort; 
BAUDRATE(npGPSInfo)=CBR_9600; 
BYTESIZE(npGPSInfo)=8; 
PARITY(npGPSInfo)=NOPARITY; 
STOPBITS(npGPSInfo)=ONESTOPBIT; 
WRITE_OS(npGPSInfo).Offset=0; 
WRITE_OS(npGPSInfo).OffsetHigh=0; 
READ_OS(npGPSInfo).Offset=0; 
READ_OS(npGPSInfo).OffsetHigh=0; 
// create I/O event used for overlapped reads / writes 
READ_OS(npGPSInfo).hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); 
if (READ_OS(npGPSInfo).hEvent==NULL) 
{ LocalFree( npGPSInfo ) ; 
return ( -1 ) ; 
} 
WRITE_OS(npGPSInfo).hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); 
if (NULL==WRITE_OS(npGPSInfo).hEvent) 
{ CloseHandle(READ_OS(npGPSInfo).hEvent); 
LocalFree(npGPSInfo) ; 
return (-1) ; 
} 
return ( (LRESULT) TRUE ) ; 
} 
BOOL NEAR DestroyGPSInfo() 
{ 
if (!npGPSInfo) return (FALSE); 
if (CONNECTED(npGPSInfo)) CloseConnection(); 
CloseHandle(READ_OS(npGPSInfo).hEvent); 
CloseHandle(WRITE_OS(npGPSInfo).hEvent); 
CloseHandle(POSTEVENT(npGPSInfo)); 
LocalFree(npGPSInfo); 
return (TRUE); 
} 
BOOL NEAR OpenConnection() 
{ 
char szPort[15]; 
BOOL fRetVal; 
HCURSOR hOldCursor,hWaitCursor; 
HANDLE hCommWatchThread; 
DWORD dwThreadID; 
COMMTIMEOUTS CommTimeOuts; 
if (!npGPSInfo) return (FALSE); 
hWaitCursor=LoadCursor(NULL,IDC_WAIT) ; 
hOldCursor=SetCursor(hWaitCursor) ; 
wsprintf(szPort,"COM%d",PORT(npGPSInfo)); 
if 
((COMDEV(npGPSInfo)=CreateFile(szPort,GENERIC_READ GENERIC_WRITE, 
0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL FILE_FLAG_OVERLAPPED, 
NULL))==(HANDLE)-1) 
return ( FALSE ) ; 
else 
{ SetCommMask(COMDEV(npGPSInfo),EV_RXCHAR); 
SetupComm(COMDEV(npGPSInfo),4096,4096); 
PurgeComm(COMDEV(npGPSInfo),PURGE_TXABORT PURGE_RXABORT PURGE_TXCLEAR  
PURGE_R 
XCLEAR); 
CommTimeOuts.ReadIntervalTimeout=0xFFFFFFFF; 
CommTimeOuts.ReadTotalTimeoutMultiplier=0; 
CommTimeOuts.ReadTotalTimeoutConstant=1000; 
CommTimeOuts.WriteTotalTimeoutMultiplier=0; 
CommTimeOuts.WriteTotalTimeoutConstant=1000; 
SetCommTimeouts(COMDEV(npGPSInfo),&CommTimeOuts); 
} 
fRetVal=SetupConnection(); 
if (fRetVal) 
{ CONNECTED(npGPSInfo)=TRUE; 
if 
(NULL==(hCommWatchThread=CreateThread((LPSECURITY_ATTRIBUTES)NULL, 
0,(LPTHREAD_START_ROUTINE)CommWatchProc, 
(LPVOID)NULL,0,&dwThreadID))) 
{ CONNECTED(npGPSInfo)=FALSE; 
CloseHandle(COMDEV(npGPSInfo)); 
fRetVal=FALSE; 
} 
else 
{ THREADID(npGPSInfo)=dwThreadID; 
HTHREAD(npGPSInfo)=hCommWatchThread; 
EscapeCommFunction(COMDEV(npGPSInfo),SETDTR); 
} 
} 
else 
{ CONNECTED(npGPSInfo)=FALSE; 
CloseHandle(COMDEV(npGPSInfo)); 
} 
SetCursor(hOldCursor); 
return (fRetVal); 
} 
BOOL NEAR SetupConnection() 
{ BOOL fRetVal; 
DCB dcb; 
if (!npGPSInfo) return(FALSE); 
dcb.DCBlength=sizeof(DCB); 
GetCommState(COMDEV(npGPSInfo),&dcb); 
dcb.BaudRate=BAUDRATE(npGPSInfo); 
dcb.ByteSize=BYTESIZE(npGPSInfo); 
dcb.Parity=PARITY(npGPSInfo); 
dcb.StopBits=STOPBITS(npGPSInfo); 
dcb.fOutxDsrFlow=FALSE; 
dcb.fDtrControl=DTR_CONTROL_ENABLE; 
dcb.fOutxCtsFlow=FALSE; 
dcb.fRtsControl=RTS_CONTROL_ENABLE; 
dcb.fInX=dcb.fOutX=FALSE; 
dcb.fBinary=TRUE; 
dcb.fParity=TRUE; 
fRetVal=SetCommState(COMDEV(npGPSInfo),&dcb); 
return (fRetVal); 
} 
BOOL NEAR CloseConnection() 
{ 
if (!npGPSInfo) return(FALSE); 
CONNECTED(npGPSInfo)=FALSE; 
SetCommMask(COMDEV(npGPSInfo),0); 
while(THREADID(npGPSInfo)!=0); 
EscapeCommFunction(COMDEV(npGPSInfo),CLRDTR); 
PurgeComm(COMDEV(npGPSInfo),PURGE_TXABORT PURGE_RXABORT  
PURGE_TXCLEAR PURGE_RXCLEAR); 
CloseHandle(COMDEV(npGPSInfo)); 
return (TRUE); 
} 
int NEAR ReadCommBlock(LPSTR lpszBlock,int nMaxLength) 
{ 
BOOL fReadStat ; 
COMSTAT ComStat ; 
DWORD dwErrorFlags; 
DWORD dwLength; 
DWORD dwError; 
if (!npGPSInfo) return(FALSE); 
ClearCommError(COMDEV(npGPSInfo),&dwErrorFlags,&ComStat); 
dwLength=min((DWORD)nMaxLength,ComStat.cbInQue); 
if (dwLength>0) 
{ fReadStat=ReadFile(COMDEV(npGPSInfo),lpszBlock, 
dwLength,&dwLength,&READ_OS(npGPSInfo)); 
if (!fReadStat) 
{ if (GetLastError()==ERROR_IO_PENDING) 
{ OutputDebugString("\n\rIO Pending"); 
while(!GetOverlappedResult(COMDEV(npGPSInfo),&READ_OS(npGPSInfo),&dwLe 
ngth,TR 
UE)) 
UE)) 
{ dwError=GetLastError(); 
if(dwError == ERROR_IO_INCOMPLETE) 
continue; 
} 
} 
else 
{ dwLength=0; 
ClearCommError(COMDEV(npGPSInfo),&dwErrorFlags,&ComStat); 
} 
} 
} 
return ( dwLength ) ; 
} 
BOOL NEAR WriteCommBlock(LPSTR lpByte,DWORD dwBytesToWrite) 
{ BOOL fWriteStat; 
DWORD dwBytesWritten; 
DWORD dwErrorFlags; 
DWORD dwError; 
COMSTAT ComStat; 
if (!npGPSInfo) return(FALSE); 
fWriteStat=WriteFile(COMDEV(npGPSInfo),lpByte,dwBytesToWrite, 
&dwBytesWritten,&WRITE_OS(npGPSInfo)); 
if (!fWriteStat) 
{ if(GetLastError()==ERROR_IO_PENDING) 
{ while(!GetOverlappedResult(COMDEV(npGPSInfo), 
&WRITE_OS(npGPSInfo),&dwBytesWritten,TRUE)) 
{ dwError=GetLastError(); 
if(dwError == ERROR_IO_INCOMPLETE) 
continue; 
else 
{ 
ClearCommError(COMDEV(npGPSInfo),&dwErrorFlags,&ComStat); 
break; 
} 
} 
} 
else 
{ 
{ 
ClearCommError(COMDEV(npGPSInfo),&dwErrorFlags,&ComStat); 
return ( FALSE ); 
} 
} 
return ( TRUE ) ; 
} 
DWORD FAR PASCAL CommWatchProc(LPSTR) 
{ DWORD dwEvtMask; 
OVERLAPPED os; 
int nLength; 
BYTE abIn[1024]; 
memset(&os,0,sizeof(OVERLAPPED)); 
// create I/O event used for overlapped read 
os.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); 
if (os.hEvent==NULL) 
{ MessageBox(NULL,"Failed to create event for thread!","GPS 
Error!",MB_ICONEXCLAMATION MB_OK); 
return ( FALSE ) ; 
} 
if (!SetCommMask(COMDEV(npGPSInfo),EV_RXCHAR)) return (FALSE); 
while (CONNECTED( npGPSInfo)) 
{ dwEvtMask=0 ; 
WaitCommEvent(COMDEV(npGPSInfo),&dwEvtMask,NULL); 
if ((dwEvtMask&EV_RXCHAR)==EV_RXCHAR) 
{ do 
{ if 
(nLength=ReadCommBlock((LPSTR)abIn,1024)) 
{ 
//WriteCommBlock((LPSTR)abIn,nLength ); 
*(abIn+nLength)=0; 
::SendMessage(hGPSWnd,CN_SEND,nLength,(LONG)(LPSTR)abIn); 
} 
} 
while ((nLength>0)&&(CONNECTED( npGPSInfo))); 
} 
} 
} 
CloseHandle(os.hEvent); 
THREADID(npGPSInfo)=0; 
HTHREAD(npGPSInfo)=NULL; 
return(TRUE); 
} 
就这些了,希望能对问这些问题的朋友有所帮助! 
一般使用的顺序是: 
CreateGPSInfo(被通知的窗口句柄,串口端口号1或2); 
OpenConnection();//建立联结它会调用SetupConnection 
DestroyGPSInfo();//解除联结它会调用CloseConnection 
可以用ReadCommBlock/WriteCommBlock来读/写串口 
CommWatchProc是监视串口的线程,由OpenConnection建立 
当串口有数据来的时侯,它会通知'被通知的窗口句柄'的窗口数据传到的消息(自 
定义的) 
SendMessage(hGPSWnd,CN_SEND,nLength,(LONG)(LPSTR)abIn); 
好了,文章结束了!希望能帮助你!   
关键词:Window 95串口通讯函数集合