![]() |
| BOOL CMultiThreadComApp::InitInstance() { AfxEnableControlContainer(); //打开并设置COM1 hComm1=CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 0, NULL ,OPEN_EXISTING, 0,NULL); if (hComm1==(HANDLE)-1) { AfxMessageBox("打开COM1失败"); return false; } else { DCB wdcb; GetCommState (hComm1,&wdcb); wdcb.BaudRate=9600; SetCommState (hComm1,&wdcb); PurgeComm(hComm1,PURGE_TXCLEAR); } //打开并设置COM2 hComm2=CreateFile("COM2", GENERIC_READ|GENERIC_WRITE, 0, NULL ,OPEN_EXISTING, 0,NULL); if (hComm2==(HANDLE)-1) { AfxMessageBox("打开COM2失败"); return false; } else { DCB wdcb; GetCommState (hComm2,&wdcb); wdcb.BaudRate=9600; SetCommState (hComm2,&wdcb); PurgeComm(hComm2,PURGE_TXCLEAR); } CMultiThreadComDlg dlg; m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } return FALSE; } |
| BOOL CMultiThreadComDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here //启动串口1处理线程 DWORD nThreadId1; hCommThread1 = ::CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0, (LPTHREAD_START_ROUTINE)Com1ThreadProcess, AfxGetMainWnd()->m_hWnd, 0, &nThreadId1); if (hCommThread1 == NULL) { AfxMessageBox("创建串口1处理线程失败"); return false; } //启动串口2处理线程 DWORD nThreadId2; hCommThread2 = ::CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0, (LPTHREAD_START_ROUTINE)Com2ThreadProcess, AfxGetMainWnd()->m_hWnd, 0, &nThreadId2); if (hCommThread2 == NULL) { AfxMessageBox("创建串口2处理线程失败"); return false; } return TRUE; // return TRUE unless you set the focus to a control } |
| DWORD WINAPI Com1ThreadProcess(HWND hWnd//主窗口句柄) { DWORD wEven; char str[10]; //读入数据 SetCommMask(hComm1, EV_RXCHAR | EV_TXEMPTY); while (TRUE) { WaitCommEvent(hComm1, &wEven, NULL); if(wEven = 0) { CloseHandle(hCommThread1); hCommThread1 = NULL; ExitThread(0); } else { switch (wEven) { case EV_TXEMPTY: if (wTxPos < wTxLen) { //在串口1写入数据 DWORD wCount; //写入的字节数 WriteFile(hComm1, com1Data.TxBuf[wTxPos], 1, &wCount, NULL); com1Data.wTxPos++; } break; case EV_RXCHAR: if (com1Data.wRxPos < com1Data.wRxLen) { //读取串口数据, 处理收到的数据 DWORD wCount; //读取的字节数 ReadFile(hComm1, com1Data.RxBuf[wRxPos], 1, &wCount, NULL); com1Data.wRxPos++; if(com1Data.wRxPos== com1Data.wRxLen); ::PostMessage(hWnd, COM_SENDCHAR, 0, 1); } break; } } } } return TRUE; } DWORD WINAPI Com2ThreadProcess(HWND hWnd //主窗口句柄) { DWORD wEven; char str[10]; //读入数据 SetCommMask(hComm2, EV_RXCHAR | EV_TXEMPTY); while (TRUE) { WaitCommEvent(hComm2, &wEven, NULL); if (wEven = 0) { CloseHandle(hCommThread2); hCommThread2 = NULL; ExitThread(0); } else { switch (wEven) { case EV_TXEMPTY: if (wTxPos < wTxLen) { //在串口2写入数据 DWORD wCount; //写入的字节数 WriteFile(hComm2, com2Data.TxBuf[wTxPos], 1, &wCount, NULL); com2Data.wTxPos++; } break; case EV_RXCHAR: if (com2Data.wRxPos < com2Data.wRxLen) { //读取串口数据, 处理收到的数据 DWORD wCount; //读取的字节数 ReadFile(hComm2, com2Data.RxBuf[wRxPos], 1, &wCount, NULL); com2Data.wRxPos++; if(com2Data.wRxPos== com2Data.wRxLen); ::PostMessage(hWnd, COM_SENDCHAR, 0, 1); } break; } } } return TRUE; } |
| typedef struct tagSerialPort { BYTE RxBuf[SPRX_BUFLEN];//接收Buffer WORD wRxPos; //当前接收字节位置 WORD wRxLen; //要接收的字节数 BYTE TxBuf[SPTX_BUFLEN];//发送Buffer WORD wTxPos; //当前发送字节位置 WORD wTxLen; //要发送的字节数 }SerialPort, * LPSerialPort; |