// ModemDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "Modem.h"
#include "ModemDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialog
{
public:
 CAboutDlg();

// 对话框数据
 enum { IDD = IDD_ABOUTBOX };

protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()

// CModemDlg 对话框

CModemDlg::CModemDlg(CWnd* pParent /*=NULL*/)
 : CDialog(CModemDlg::IDD, pParent)
 , m_show(_T(""))
{
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CModemDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 DDX_Text(pDX, IDC_EDIT1, m_show);
}

BEGIN_MESSAGE_MAP(CModemDlg, CDialog)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 //}}AFX_MSG_MAP
 ON_BN_CLICKED(IDOK, OnBnClickedOk)
 ON_EN_CHANGE(IDC_EDIT1, OnEnChangeEdit1)
 ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

// CModemDlg 消息处理程序

BOOL CModemDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

// 将/“关于.../”菜单项添加到系统菜单中。

// IDM_ABOUTBOX 必须在系统命令范围内。
 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);
  }
 }

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
 //  执行此操作
 SetIcon(m_hIcon, TRUE);   // 设置大图标
 SetIcon(m_hIcon, FALSE);  // 设置小图标

// TODO:在此添加额外的初始化代码

threadHandle=AfxBeginThread(RUNTIME_CLASS(CmyThread));
 
 return TRUE;  // 除非设置了控件的焦点,否则返回 TRUE
}

void CModemDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CModemDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// 使图标在工作矩形中居中
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

// 绘制图标
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialog::OnPaint();
 }
}

//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CModemDlg::OnQueryDragIcon()
{
 return static_cast<HCURSOR>(m_hIcon);
}

void CModemDlg::OnBnClickedOk()
{
 TerminateThread(threadHandle,0);

OnOK();
}

void CModemDlg::OnEnChangeEdit1()
{
 UpdateData(true);
 
 AfxMessageBox(m_show);
}

BOOL CModemDlg::OnEraseBkgnd(CDC* pDC)
{
 CBrush brush;
 brush.CreateSolidBrush(RGB(255,255,255));
 CBrush *oldBrush=pDC->SelectObject(&brush);
 CRect rc;
 GetClientRect(&rc);
 pDC->Rectangle(&rc);
 pDC->SelectObject(oldBrush);
 return TRUE;

//return CDialog::OnEraseBkgnd(pDC);
}

// myThread.cpp : 实现文件
//

#include "stdafx.h"
#include "Modem.h"
#include "myThread.h"
#include <assert.h>

// CmyThread

IMPLEMENT_DYNCREATE(CmyThread, CWinThread)

CmyThread::CmyThread()
{
 m_receive="";
}

CmyThread::~CmyThread()
{
}

BOOL CmyThread::InitInstance()
{

//m_bEvtChar=EVENTCHAR;
 //m_fBinary=1;
 //m_bFlowCtrl = FC_XONXOFF ;
 //m_fXonXoff = FALSE;

m_edit=(CEdit *)GetMainWnd()->GetDlgItem(IDC_EDIT1);
 readOver.Offset=0;
 readOver.OffsetHigh=0;
 readOver.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
 assert(readOver.hEvent);

writeOver.Offset=0;
 writeOver.OffsetHigh=0;
 writeOver.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
 assert(writeOver.hEvent);

m_hCom=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED|FILE_ATTRIBUTE_NORMAL,NULL);
 if(m_hCom==INVALID_HANDLE_VALUE)
 {
  AfxMessageBox("打开串口失败!!");
  return FALSE;
 }

// SetCommMask(m_hCom,EV_RXCHAR);

SetupComm(m_hCom,4096,4096);

PurgeComm(m_hCom,PURGE_RXABORT|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_TXCLEAR);

time.ReadIntervalTimeout=0XFFFFFFFF;
 time.ReadTotalTimeoutConstant=1000;
 time.ReadTotalTimeoutMultiplier=0;
 time.WriteTotalTimeoutConstant=1000;
 time.WriteTotalTimeoutMultiplier=0;
 SetCommTimeouts(m_hCom,&time);

dcb.DCBlength=sizeof(DCB);
 GetCommState(m_hCom,&dcb);
 dcb.ByteSize=8;
 dcb.StopBits=ONESTOPBIT;
 dcb.Parity=NOPARITY;
 dcb.BaudRate=9600;
 // dcb.EvtChar=EVENTCHAR;

dcb.fOutxDsrFlow=FALSE;
 dcb.fDtrControl=DTR_CONTROL_ENABLE;
 dcb.fOutxCtsFlow=FALSE;
 dcb.fRtsControl=RTS_CONTROL_ENABLE;
 dcb.fInX=TRUE;
 dcb.fOutX=TRUE;

dcb.XonChar=0x11;
 dcb.XoffChar=0x13;
 dcb.XonLim=100;
 dcb.XoffLim=100;

dcb.fBinary=TRUE;
 dcb.fParity=TRUE;
 SetCommState(m_hCom,&dcb);

EscapeCommFunction(m_hCom,SETDTR);

BOOL fWriteStat;
 DWORD dwBytesWritten;
 DWORD dwErrorFlags;
 DWORD dwError;
 DWORD dwBytesSent=0;
 char szError[128];

fWriteStat=WriteFile(m_hCom,"AT+VCID=1+FCLASS=8/r",40,&dwBytesWritten,&writeOver);

if (!fWriteStat)
 {
  if(GetLastError() == ERROR_IO_PENDING)
  {
   while(!GetOverlappedResult(m_hCom,&writeOver,&dwBytesWritten,TRUE))
   {
    dwError = GetLastError();
    if(dwError == ERROR_IO_INCOMPLETE)
    {
     dwBytesSent += dwBytesWritten;
     continue;
    }
    else
    {
     wsprintf( szError, "<CE-%u>", dwError ) ;
     ClearCommError(m_hCom, &dwErrorFlags, &ComStat ) ;
     break;
    }
   }
   dwBytesSent += dwBytesWritten;
   if( dwBytesSent != 40 )
    wsprintf(szError,"/nProbable Write Timeout: Total of %ld bytes sent", dwBytesSent);
   else
    wsprintf(szError,"/n%ld bytes written", dwBytesSent);
   OutputDebugString(szError);
  }
  else
  {
   ClearCommError(m_hCom, &dwErrorFlags, &ComStat ) ;
   return FALSE;
  }
 }
 PurgeComm(m_hCom,PURGE_RXCLEAR|PURGE_TXCLEAR);

return TRUE;
}

int CmyThread::Run()
{
 char buffer[1024];
 memset(buffer,0,sizeof(buffer));
 buffer[0]='/0';

while(1)
 {
  BOOL fReadStat ;
  DWORD dwErrorFlags;
  DWORD dwLength;
  DWORD dwError;
  char szError[10];

ClearCommError(m_hCom, &dwErrorFlags, &ComStat) ;
  dwLength =ComStat.cbInQue;

if (dwLength > 0)
  {
   fReadStat = ReadFile(m_hCom,buffer,dwLength, &dwLength,&readOver) ;
   if (!fReadStat)
   {
    if (GetLastError() == ERROR_IO_PENDING)
    {
     OutputDebugString("/n/rIO Pending");

while(!GetOverlappedResult(m_hCom,&readOver,&dwLength, TRUE ))
     {
      dwError = GetLastError();
      if(dwError == ERROR_IO_INCOMPLETE)
       continue;
      else
      {
       wsprintf( szError, "<CE-%u>", dwError ) ;
       ClearCommError(m_hCom , &dwErrorFlags, &ComStat ) ;
       break;
      }

}

}
    else
    {
     dwLength = 0 ;
     ClearCommError(m_hCom , &dwErrorFlags, &ComStat ) ;
    }
   }
  }

if(dwLength!=0)
  {
   CString temp,temp2;
   temp.Format("%s",buffer);
   temp2=temp.GetAt(1);
   m_receive+=temp2;
   ShowNumber(m_receive);
  }

}

}

void CmyThread::ShowNumber(CString &str)
{
 CString result;
 int begin=str.Find("RD");
 int end=str.Find("C");
 int count=end-begin-2;
 if(begin!=-1 && end!=-1)
 {
  result=str.Mid(begin+2,count);
  m_edit->SetWindowText(result);
  str="";
 }
}

int CmyThread::ExitInstance()
{

SetCommMask(m_hCom,0);
 EscapeCommFunction(m_hCom,CLRDTR);

PurgeComm(m_hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);

CloseHandle(m_hCom);
 m_hCom = NULL;

CloseHandle(readOver.hEvent);
 CloseHandle(writeOver.hEvent);

return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CmyThread, CWinThread)
END_MESSAGE_MAP()

// CmyThread 消息处理程序

多线程 MODEN 串口编程相关推荐

  1. C——Linux下的串口编程

    原 C--Linux下的串口编程 2017年06月06日 19:30:50 C_Aya 阅读数:11537 <span class="tags-box artic-tag-box&qu ...

  2. CSerialPort多线程串口编程工具详解

    1.前言 既然有了MSComm这种简单粗暴的控件,为什么还需要CSerialPort类?这是因为与前者相比,这个类在程序的发布上不需要加入其他的文件,而且CSerialPort提供给我们的函数都是开放 ...

  3. linux 多线程串口编程总结

    最近在玩DJI M100,调用API获取GPS位置时发现高程定位完全是错的(负的几百多米),查了一下文档说高程数据是由气压计得到的,而飞行控制时又需要比较可靠的高度信息,于是乎决定用上我们实验室的搭载 ...

  4. Qt 多线程串口编程

    一.问题 以前串口编程使用第三方的CnComm.h编程,CnComm作者博客链接,使用起来还蛮好的,不过既然用qt了就想着用qt自带的QSerialPort,移植性更好一些,结果折腾了好几天,主要遇到 ...

  5. 基于MFC串口编程和曲线图绘制(visual studio2008,Teechart绘图控件)的程序总结

    前言 今年刚进入公司按经理的要求为底盘测控机写了一个小小的console.这也是第一次教认真的完成整个程序的编写.程序不大,所用技术比较基础也不前卫,属于初级程序员的练手程序(知识的整理和搬运).虽然 ...

  6. Win32 API串口编程

    在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...

  7. 深入浅出VC++串口编程--第三方类

    串口类 从本系列文章连载三.四可以看出,与通过WIN32 API进行串口访问相比,通过MScomm这个Activex控件进行串口访问要来的方便许多,它基本上可以向用户屏蔽多线程的细节,以事件(发出On ...

  8. 多线程的串口通信-1

    多线程的串口通信 1 下位机STM32发送的数据格式与串口参数 1.1下位机上传的数据格式: 1.2串口参数 2 上位机程序 2.1Future: ~~2.2串口参数同上~~ 3 QT程序设计 QT走 ...

  9. 【C++】多线程与异步编程【四】

    文章目录 [C++]多线程与异步编程[四] 0.三问 1.什么是异步编程? 1.1同步与异步 1.2 **阻塞与非阻塞** 2.如何使用异步编程 2.1 使用全局变量与条件变量传递结果 实例1: 2. ...

最新文章

  1. SSL证书如何工作?
  2. 互联网1分钟 | 0110 腾讯联手拳头游戏成立腾竞体育;百度智能云发布中国首款智能边缘计算产品BIE...
  3. 插入和shell排序
  4. fillstyle属性_html设置或返回用于填充绘画的颜色渐变或模式的属性fillStyle
  5. C4C Product Price List的模型中和有效期相关的两个字段
  6. 使用iperf进行设备吞吐量测试
  7. java调用go接口_go语言调用API实线分词
  8. spring—第一个spring程序
  9. tickcount()修改成小时分钟_银行核心系统24小时机制实现总结
  10. 音视频开发(22)---基于RTMP推送实时AAC+H264流(三)
  11. 【学习笔记】函数高级使用技巧:建立函数队列
  12. 拜托,面试别再问我基数排序了!!!
  13. 杰里之AC897N_AD697N_earphone_release_ V2.0.1 开立体声左右声道数据对调【篇】
  14. 常见服务器故障有哪些?如何预防服务器发生故障?服务器故障后如何恢复数据?
  15. window 10 局域网同步时间(解决错误:This scheduler instance is still active but was recovered by another instanc)
  16. mysql的组内排序生成序号_sql 分组查询,组内排序, 组内添加序号 (SQL Server 排序函数 ROW_NUMBER和RANK 用法总结)...
  17. XUL 用户界面语言介绍
  18. 交互组件滚动条,搜索框,上传组件,翻页的微创新
  19. bottom sheets_使用Sheetson建立由Google Sheets支持的免费电子邮件列表
  20. Centos Stream 9安装docker-ce

热门文章

  1. GhostXP_SP2电脑公司特别版_v7.8[修正版]
  2. 高级软件工程课程总结报告
  3. “中国90后系列研究:社交浪潮中的90后”.pdf
  4. 中国的手机号码格式化/分类工具
  5. 欧姆龙CP1H如何进行PLC远程编程及数据采集
  6. 从Excel到Smartbi,国内头部企业的报表是这样进阶的!
  7. OJB中的多表查询和更新
  8. JAVA实现Freemarker生成动态数据的Word文档下载到浏览器
  9. 中国自主研发的USB2.0 HUB芯片,即将发布CH334 和CH335工业级
  10. 怎么用显卡计算_显卡性能的软件 3dmark怎么用