完整的已经发了邮件给你。
串口主程序:
#include<windows.h>
#include"StdAfx.h"
#include"ChuanKou.h"
HINSTANCE hInst;
DWORD Thread1;
DWORD Thread2;
HANDLE hEvent[2]; //事件对象句柄数组
HWND hMainWnd;
DWORD i=1;//线程1结束标志
DWORD j=1;//线程2结束标志
int ThreadPriority;
HANDLE hCom;
HANDLE hThread1; //线程句柄
HANDLE hThread2; //线程句柄
char text_buffer[1024];//编辑框字符缓冲区
char Buffer[1024];
char EditShow[1024];
DWORD WriteLength;
DWORD Writen;
char szAppName[]="这是个串口通信程序";
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow) //创建主窗口
{
//char szAppName[]="这是个串口通信程序";
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
hInst=hInstance;
////////////////定义窗口类
wndclass.cbSize =sizeof(wndclass);
wndclass.style =CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc =ChuanKouProc;
wndclass.cbClsExtra =0;
wndclass.cbWndExtra =0;
wndclass.hInstance =hInstance;
wndclass.hIcon =LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor =LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH);
wndclass.lpszClassName=szAppName;
wndclass.lpszMenuName =NULL;
wndclass.hIconSm =LoadIcon(NULL,IDI_WINLOGO);
RegisterClassEx(&wndclass); //注册窗口类
hwnd=CreateWindow(szAppName, //窗口类名
"ChuanKouAppication",//窗口标题
WS_SYSMENU|WS_MINIMIZEBOX,//窗口样式
CW_USEDEFAULT,//窗口起始位置x
CW_USEDEFAULT,//窗口起始位置y
//CW_USEDEFAULT,//用于缺省大小x
//CW_USEDEFAULT,//用于缺省大小y
300, //窗口长
100, //窗口宽
NULL,//无父事例句柄
NULL,//无菜单
hInstance,//当前事例句柄
NULL);//无参数
hMainWnd=hwnd;
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK ChuanKouProc(HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
static HWND hWndEdit1; //编辑框句柄1
static HWND hWndEdit2; //编辑框句柄1
static HWND hWndButton1; //按钮句柄
static HWND hWndButton2; //按钮句柄
static HWND hWndButton3; //按钮句柄
switch(msg)
{
case WM_CREATE:
hWndEdit1=CreateWindow("EDIT",NULL,
WS_CHILD|WS_VISIBLE|WS_BORDER|
ES_LEFT|ES_AUTOHSCROLL,
0,0,0,0,
hWnd,
(HMENU)IDE_EDIT1,
hInst,
NULL); //创建编辑框子窗口1
hWndEdit2=CreateWindow("EDIT",NULL,
WS_CHILD|WS_VISIBLE|WS_BORDER|
ES_LEFT|ES_AUTOHSCROLL,
0,0,0,0,
hWnd,
(HMENU)IDE_EDIT2,
hInst,
NULL); //创建编辑框子窗口2
hWndButton1=CreateWindow("BUTTON","Send",
BS_PUSHBUTTON|WS_CHILD|
WS_VISIBLE|BS_CENTER,
210,10,80,20,
hWnd,
(HMENU)IDB_BUT1,
hInst,
NULL); //创建按钮子窗口1
hWndButton2=CreateWindow("BUTTON","Exit",
BS_PUSHBUTTON|WS_CHILD|
WS_VISIBLE|BS_CENTER,
210,45,80,20,
hWnd,
(HMENU)IDB_BUT2,
hInst,
NULL); //创建按钮子窗口2
/* hWndButton3=CreateWindow("BUTTON","传送文件",
BS_PUSHBUTTON|WS_CHILD|
WS_VISIBLE|BS_CENTER,
280,225,80,25,
hWnd,
(HMENU)IDB_BUT3,
hInst,
NULL); ////创建按钮子窗口3
*/
///////////////打开串口资源
hCom=CreateFile("COM1", //打开com
GENERIC_READ|GENERIC_WRITE, //可读写
0, //应用程序可在不访问设备情况下查询设备
NULL, //无安全属性
OPEN_EXISTING, //打开方式:若文件不存在则函数失败
FILE_FLAG_OVERLAPPED, //异步通讯方式FILE_FLAG_OVERLAPPED
NULL); //打开串口
if(hCom!=INVALID_HANDLE_VALUE)
MessageBox(hWnd,"串口打开成功","Message",0);
SetupComm(hCom,1024,1024); //设置输入输出缓冲区
PurgeComm(hCom,
PURGE_TXCLEAR| //清空输出缓冲
PURGE_RXCLEAR //清空输入缓冲
); //清空输入输出缓冲区
COMMTIMEOUTS CommTimeOuts;//定义超时结构
CommTimeOuts.ReadIntervalTimeout=1000;
CommTimeOuts.ReadTotalTimeoutMultiplier=5000;
CommTimeOuts.ReadTotalTimeoutConstant=5000;
CommTimeOuts.WriteTotalTimeoutMultiplier=5000;
CommTimeOuts.WriteTotalTimeoutConstant=5000;
if(!SetCommTimeouts(hCom,&CommTimeOuts))
{
CloseHandle(hCom);
MessageBox(hWnd,"设置超时失败","Message",0);
return FALSE;
}
DCB dcb;
GetCommState(hCom,&dcb); //读串口原来的参数设置
/////////设置DCB块结构
dcb.BaudRate=9600; dcb.ByteSize=8; dcb.Parity=NOPARITY;
dcb.StopBits=ONESTOPBIT; dcb.fBinary=TRUE; dcb.fParity=FALSE;
////////设置DCB为:波特率9600,8字节数据位,无校验,1位停止位,
////////允许2进制位(必须为TUNE),无校验检查
SetCommState(hCom,&dcb);//配置串口参数
///////////建立工作者线程
if(!(hThread1=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadFunc1,//线程函数
NULL,
0,
&Thread1)))//建立线程1(读线程)
MessageBox(hWnd,"出现错误,不能建立读线程","Message",0);
if(!(hThread2=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadFunc2,//线程函数
NULL,
0,
&Thread2)))//建立线程2(写线程)
MessageBox(hWnd,"出现错误,不能建立写线程","Message",0);
ThreadPriority=GetThreadPriority(hThread1); //得到线程1的优先级
SetThreadPriority(hThread2,ThreadPriority+1);//设线程2优先级高于线程1
hEvent[0]=CreateEvent(NULL, //无安全属性
TRUE, //手动设定事件为无通知状态
FALSE, //初始值为无通知状态
NULL //无对象名
); //创建事件对象
SetEvent(hEvent[0]); //设置为通知状态
hEvent[1]=CreateEvent(NULL, //无安全属性
TRUE, //手动设定事件为无通知状态
FALSE, //初始值为无通知状态
NULL //无对象名
); //创建事件对象
break;
case WM_SETFOCUS:
SetFocus(hWndEdit1);
break;
case WM_SIZE: //显示编辑框使之可以随窗口变化而变化(本程序设置窗口不可变)
MoveWindow(hWndEdit1,5,45,200,20,FALSE);
MoveWindow(hWndEdit2,5,10,200,20,TRUE);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case 1111://按下发送文本键后由这里处理此消息
if((WriteLength=GetDlgItemText(hWnd,1114,text_buffer,1024))==0)
MessageBox(hMainWnd,"不能发空信息","Message",MB_OK);
else
{
SetEvent(hEvent[1]);
ResetEvent(hEvent[0]);
Writen=WriteLength;
}
SetFocus(hWndEdit1);
break;
case 1112:
PurgeComm(hCom,
PURGE_TXCLEAR| //清空输出缓冲
PURGE_RXCLEAR //清空输入缓冲
); //清空输入输出缓冲区
CloseHandle(hCom);
CloseHandle(hEvent[0]);
CloseHandle(hEvent[1]);
i=0;
j=0;
PostQuitMessage(0);
break;
}
break;//这里少了这个break造成很大麻烦
case 2222:
MessageBox(hMainWnd," 数据已读入","Message",MB_OK);
break;
case 3333:
MessageBox(hMainWnd," 数据已写入","Message",MB_OK);
break;
case WM_DESTROY:
PurgeComm(hCom,
PURGE_TXCLEAR| //清空输出缓冲
PURGE_RXCLEAR //清空输入缓冲
); //清空输入输出缓冲区
CloseHandle(hCom);
CloseHandle(hEvent[0]);
CloseHandle(hEvent[1]);
i=0;
j=0;
PostQuitMessage(0);
break;
default:
return(DefWindowProc (hWnd,msg,wParam,lParam));
}
return(0);
}
DWORD WINAPI ThreadFunc1(LPVOID lpParameter) //线程函数
{
DWORD dwEvtMask=0;
OVERLAPPED ReadOverLapped;
COMSTAT ComStat;
DWORD dwLength;
DWORD dwErrorFlags;
BOOL fReadStat;
DWORD dwBytesRead;
DWORD dwError;
DWORD NumberOfBytesTransferred;
ReadOverLapped.hEvent=CreateEvent(NULL, //无安全属性
TRUE, //手动设定事件为无通知状态
FALSE, //初始值为无通知状态
NULL //无对象名
); //创建事件对象
DWORD flag;
memset(&ReadOverLapped,0,sizeof(OVERLAPPED));
while(i)
{
WaitForSingleObject(hEvent[0],INFINITE);
SetCommMask(hCom,EV_RXCHAR); //设置监视类型
WaitCommEvent(hCom,&dwEvtMask,&ReadOverLapped);
flag=0;
if(dwEvtMask==EV_RXCHAR) //如果有数据到达
{
do
{
ClearCommError(hCom,&dwErrorFlags,&ComStat); //报告通信设备的当前状态
dwLength=ComStat.cbInQue; //接受到的且未读的数据的长度
memset(Buffer, 0, 1024);
if(dwLength>0)
{
fReadStat=ReadFile(hCom, //读的文件句柄
Buffer, //数据读入的缓冲区地址
dwLength, //要读的数据长度
&dwBytesRead, //指向一个变量,得到读入的长度
&ReadOverLapped //指向重叠结构的指针
);
strcat( EditShow, Buffer ); //数据可能要读几次到Buffer才能读完,
//所以要把读到的数据连接起来
dwError=GetLastError();
if(!fReadStat)
{
if(dwError==ERROR_IO_PENDING)
{
WaitForSingleObject(ReadOverLapped.hEvent,INFINITE);
while(!GetOverlappedResult(hCom,
&ReadOverLapped,
&NumberOfBytesTransferred,
FALSE));
ReadOverLapped.Offset+=NumberOfBytesTransferred;
}
}
else
{
ReadOverLapped.Offset+=dwBytesRead;
}
}
}while(dwLength>0); //循环结束时读操作完成
}
flag=strcmp(EditShow,"");
if(flag)
{
SetDlgItemText(hMainWnd,1115,EditShow);
}
SetEvent(hEvent[0]);
//PostMessage(hMainWnd,2222,0,0);
//Sleep(0);
}
return 0;
}
DWORD WINAPI ThreadFunc2(LPVOID lpParameter)//线程函数
{
DWORD dwEvtMask=0;
OVERLAPPED WriteOverLapped;
COMSTAT ComStat;
DWORD dwErrorFlags;
BOOL fWriteStat;
DWORD dwBytesWrite;
DWORD dwError;
DWORD NumberOfBytesTransferred = 0;
WriteOverLapped.hEvent=CreateEvent(NULL, //无安全属性
TRUE, //手动设定事件为无通知状态
FALSE, //初始值为无通知状态
NULL //无对象名
); //创建事件对象
DWORD dwLength;
while(j)
{
memset(&WriteOverLapped,0,sizeof(OVERLAPPED));
LPSTR pBuffer=text_buffer; //得到缓冲区的指针
WaitForSingleObject(hEvent[1],INFINITE);
memset(EditShow, 0, 1024); //将显示缓冲区清零
do
{
fWriteStat=WriteFile(hCom, //写的文件句柄
pBuffer, //要写入数据的缓冲区地址
WriteLength, //要写的数据长度
&dwBytesWrite,//指向一个变量,得到实际写入的长度
&WriteOverLapped //指向重叠结构的指针
);
dwError=GetLastError();
if(!fWriteStat)
{
if(dwError==ERROR_IO_PENDING)
{
WaitForSingleObject(WriteOverLapped.hEvent,INFINITE);
while(!GetOverlappedResult(hCom,
&WriteOverLapped,
&NumberOfBytesTransferred,
FALSE));
WriteLength=WriteLength-NumberOfBytesTransferred;
pBuffer+=NumberOfBytesTransferred;
}
}
else
{
WriteLength=0;
}
}while(WriteLength>0);//循环结束时写操作完成,下面要做些收尾工作
//PostMessage(hMainWnd,3333,0,0);
memset(text_buffer,0,1024);
SetDlgItemText(hMainWnd,1114,"");
ResetEvent(hEvent[1]);
SetEvent(hEvent[0]);
//Sleep(0);
}
return 0;
}
////////////////////////////////////头文件:
LRESULT CALLBACK ChuanKouProc(HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam);
DWORD WINAPI ThreadFunc1(LPVOID lpParameter);
DWORD WINAPI ThreadFunc2(LPVOID lpParameter);
#define IDB_BUT1 1111
#define IDB_BUT2 1112
#define IDB_BUT3 1113
#define IDE_EDIT1 1114
#define IDE_EDIT2 1115
//#define WM_JOB1 221
//#define WM_JOB2 222