c++中的mfc数据通信 - CSDN
精华内容
参与话题
  • C++ MFC 简单 串口通信

    万次阅读 多人点赞 2017-08-20 10:15:12
    根据一款教程,使用MFC进行了串口通讯的上位机的软件编程,教程网址如下,十分简单。 http://download.csdn.net/download/peter_jjh/9937595 问题: 1) error LNK2001: 无法解析的外部符号 在进行编译时,出现如上...

    说来惭愧,自己看别人的API说明,想要鼓捣出一个串口通讯界面,结果失败了,最后还是看的教程。。。。

    使用MFC进行串口通讯的上位机的软件编程,教程网址如下,十分简单。

    http://download.csdn.net/download/peter_jjh/9938549

    1. 程序框架及代码分析:

    1.1 程序框架:

    (1) 初始化界面
    (2) 打开串口 (读取串口号,初始化串口参数(波特率、校验位、数据位等),若串口已经打开则关闭串口)
    (3) 发送数据 (更新控件状态,进入MSComm事件驱动函数,读缓冲区,数据转换,更新编辑框成员函数,更新编辑框内容)
    (4) 退出界面 (检测串口是否开启,若开启则关闭串口,再进行退出)

    1.2 关键代码分析:



    (1)初始化界面:除却MFC自动生成的界面初始化代码,这里的关键在于初始化参数,在BOOL xxxxx:OnInitDialog()中添加部分代码


    // 串口选择组合框
    	CString str;
    	int i;
    	for (i = 0; i<30; i++)
    	{
    		str.Format(_T("com %d"), i + 1);
    		m_ComNum.InsertString(i, str);
    	}
    	m_ComNum.SetCurSel(0);//预置COM口
    
    	//波特率选择组合框
    	CString str1[] = { _T("300"), _T("600"), _T("1200"), _T("2400"), _T("4800"), _T("9600"),
    		_T("19200"), _T("38400"), _T("43000"), _T("56000"), _T("57600"), _T("115200") };
    	
    	for (int i = 0; i<12; i++)	//使用AddString会无序排列,在Dialog中把这一ComboBox的Sorted改为False即可
    	{
    		int judge_tf = m_BaudRate.AddString(str1[i]);
    		if ((judge_tf == CB_ERR) || (judge_tf == CB_ERRSPACE))	
    			MessageBox(_T("build baud error!"));
    	}
    	/*for (int i = 0; i<12; i++)		//更换为使用InsertString
    	{
    		m_BaudRate.InsertString(i, str1[i]);		
    	}*/
    
    	m_BaudRate.SetCurSel(5);//预置波特率为"9600"

    (2) 打开串口:

    void CComCommunicateDlg::OnBnClickedButtonOpen()	//打开串口按钮
    {
    	CString str, str1, n;					//定义字符串
    	GetDlgItemText(IDC_BUTTON_OPEN, str);
    	CWnd *h1;
    	h1 = GetDlgItem(IDC_BUTTON_OPEN);		//指向控件的caption
    
    	if (!m_mscom.get_PortOpen())			
    	{
    		m_BaudRate.GetLBText(m_BaudRate.GetCurSel(), str1);//取得所选的字符串,并存放在str1里面
    		str1 = str1 + ',' + 'n' + ',' + '8' + ',' + '1';			//这句话很关键
    
    		m_mscom.put_CommPort((m_ComNum.GetCurSel() + 1));	//选择串口
    		m_mscom.put_InputMode(1);			//设置输入方式为二进制方式
    		m_mscom.put_Settings(str1);		//波特率为(波特率组Á合框)无校验,8数据位,1个停止位
    		m_mscom.put_InputLen(1024);		//设置当前接收区数据长度为1024
    		m_mscom.put_RThreshold(1);			//缓冲区一个字符引发事件
    		m_mscom.put_RTSEnable(1);			//设置RT允许
    
    		m_mscom.put_PortOpen(true);		//打开串口
    		if (m_mscom.get_PortOpen())
    		{
    			str = _T("关闭串口");
    			UpdateData(true);
    			h1->SetWindowText(str);			//改变按钮名称为‘’关闭串口”
    		}
    	}
    
    	else
    	{
    		m_mscom.put_PortOpen(false);		//关闭串口
    		if (str != _T("打开串口"))
    		{
    			str = _T("打开串口");
    			UpdateData(true);				//将控件的状态传给其关联的变量
    			h1->SetWindowText(str);			//改变按钮名称为打开串口
    		}
    	}
    
    }

    (3) 发送数据 

    void CComCommunicateDlg::OnBnClickedButtonSend()
    {
    	UpdateData(true);							//将控件的状态传给其关联的变量
    	m_mscom.put_Output(COleVariant(m_EditSend));//把发送编辑框的数据发送出去,跳转到OnCommMscomm1中
    }
    
    void CComCommunicateDlg::OnCommMscomm1()	//事件驱动
    {
    	if (m_mscom.get_CommEvent() == 2)	//事件值为2表示接收缓冲区内有字符
    	{
    		char str[1024] = { 0 };
    		long k;
    		VARIANT InputData = m_mscom.get_Input();	//读缓冲区
    		COleSafeArray fs;
    		fs = InputData;	//VARIANT型变量转换为COleSafeArray型变量
    		for (k = 0; k<fs.GetOneDimSize(); k++)
    			fs.GetElement(&k, str + k);	//转换为BYTE型数组
    
    		m_EditReveive += str;      //	接收到编辑框里面
    		//SetTimer(1,10,NULL);		//延时10ms
    		UpdateData(false);
    	}
    
    }

    (4) 退出界面

    void CComCommunicateDlg::OnBnClickedButtonClose()
    {
    	if (m_mscom.get_PortOpen())
    		m_mscom.put_PortOpen(false);	//先关闭串口再退出,否则串口一直被占用
    	CDialogEx::OnCancel();
    
    }

    2. 遇到的问题:

    2.1 缺少Microsoft Communications Control 控件

    MSComm 控件是一个串行通讯控件,作用为替程序员串口通讯编程节省时间,有关于MSComm空间的介绍可以参考这篇博客:串口通信-MSComm控件使用详解


    这一问题的解决方式很简单,下载压缩包解压复制就可以,下载网址:


    http://download.csdn.net/download/peter_jjh/9937696


    1.解压缩压缩包内包含3个文件:

    MSCOMM.SRG
    MSCOMM32.DEP
    mscomm32.ocx
    2.复制文件到指定路径:

    32位的系统,文件复制到C:\WINDOWS\SYSTEM32目录下;

    64位的系统,文件复制到C:\Windows\SysWOW64目录下。

    3.win+r输入cmd打开cmd窗口,在cmd中输入:

    32位:regsvr32 C:\Windows\System32\mscomm32.ocx
    64位:regsvr32 C:\Windows\SysWOW64\mscomm32.ocx

    如果失败,请以管理员身份打开cmd,再进行步骤3。


    2.2 error LNK2001: 无法解析的外部符号

    在进行编译时,出现如上错误的原因有两个,分别是
    (1)部分函数声明了却未定义
    (2)部分动态链接库的编译方式未统一

    针对第一种错误,只需要找到未定义的函数,注释掉或者删除就可以了,在我的测试程序中,这类问题主要出现在BoxEditor中,可能是由于我的误操作导致,添加了OnEnChangeEditRev函数,该OnEnChange***函数针对的是窗口中数据内容变化的响应函数,但是实际没有实现这个函数,所以导致了错误。
    参考:http://tieba.baidu.com/p/2049736254 

    针对第二种错误,需要将 MFC使用 和 运行库 都进行统一。注意先将右上角的配置选为 所有配置, 具体选择如下:



    参考:http://www.360doc.com/content/11/1031/14/4190063_160548608.shtml



    附录:

    在研究如何自动读取可用的串口号时,发现了一个十分完整的开源的串口通信项目。较为复杂,慢慢研究,该项目的地址如下:




    结语:

    本文存在诸多不足,希望大家多多指教!


    展开全文
  • 此程序是基于对话框的MFC程序,能够做到串口实时通信,并且将数据展示到编辑框,而且并对获得的数据进行解析,主要处理的数据是GPGGA报文,安装环境请对照安装包提示,有问题可以发邮件交流学习,liaoby@jmev.com
  • 本实例利用命名管道实现进程间通信,实现了不同进程间的发送数据和接收数据功能。
  • 采用C++和socket实现的网络通信上位机,具体用的是socket阻塞和多线程方式实现。可以监控基于网络通信的设备通信,四种通信方式可任意选择,包括:TCP 服务端,TCP客户端,UDP服务端,UDP客户端;通信部分代码封装成...

    采用C++和socket实现的网络通信上位机,具体用的是socket阻塞和多线程方式实现。可以监控基于网络通信的设备通信,四种通信方式可任意选择,包括:TCP 服务端,TCP客户端,UDP服务端,UDP客户端;通信部分代码封装成了库,可以方便移植。

      首先把各种模式封装到一个库,在库中实现各种通讯模式。 可以通过复选框任意切换想要的模式,切换前需要结束当前的模式的socket连接。连接和接收放在一个线程,发送放在另外一个线程,处理数据放在另外一个线程,采用多线程的方式接收和发送数据,以及处理数据。 以及结束当前线程也是在另外一个线程实现。这样就可以在不同的使用场合,根据不同的情况,对网络设备进行监控,非常方便。 如果想要把代码移植到别的工程中使用,也很方便,已经封装成库的形式了。

    代码地址:https://download.csdn.net/download/hill_guo/11139027

    展开全文
  • c++/MFC 极为简单的socket实例

    万次阅读 2012-11-20 11:50:56
    本实例,也是我在网上找到的。感觉很基础,新手很适合。所以,就加以备注,给大家分享下。我也是一新手,学习mfc也就2个星期,本来一直弄php的。...最简单的mfc socket实例,适合新手。里面有服务端

    本实例,也是我在网上找到的。感觉很基础,新手很适合。所以,就加以备注,给大家分享下。我也是一新手,学习mfc也就2个星期,本来一直弄php的。

    简单来说下服务端的socket工作流程。

    本实例代码下载,vs2010版本,打开就可以运行:http://download.csdn.net/detail/open520yin/4788263

    最简单的mfc socket实例,适合新手。里面有服务端和客户端代码,先运行服务端,再运行客户端。

    seocket 常用到的函数

        CSocket::Create 初始化(一般写服务器程序都不要用为好,用下面的 CSocket::Socket 初始化)
    
       CSocket::Socket初始化
    
        CSocket::SetSockOpt 设置socket选项
    
        CSocket::Bind 绑定地址端口
    
        CSocket::Connect 连接
    
        CSocket::Listen  监听
    
        CSocket::Accept 接收外部连接的socket
     
        CSocket::Send 发送内容
    
        CSocket::Receive 接收内容
    
        CSocket::Close 关闭(不等于delete)


    1,初始化一个Winsock  

           AfxSocketInit() 这个函数,在使用CSocket前一定要先调用该函数,否则使用CSocket会出错;并且该函数还有一个重要的使用方式,
           就是在某个线程下使用 CSocket 前一定要调用,就算主线程调用了该函数,在子线程下使用 CSocket 也要先调用该函数,要不会出错。

    2,创建2一个socket链接

           服务端最好不要使用aSocket.Create创建,因为容易会出现10048错误,直接用  Socket

          还要注意的是, Create 方法已经包含了 Bind 方法,如果是以 Create 方法初始化的前提下不能再调用 Bind ,要不一定出错。

    3,设置一些socket的选项,其实我也不知道这些什么意思,网上看到的。。能解决10048错误,是用SetSockOpt方法

    4,因为是用的socket创建,所以需要用bind方法绑定一个端口,这个端口要其他进程没有是用的。如果不知道哪些端口被是用,可以谷歌查询一下。

    5,绑定好了,就可以开始监听了。。是用脑listen方法

    6,是用循环,用Accept 来接收外部,链接。。。。

    7,如果接收到数据,用Receive 来接收参数,,然后用send发送参数,关闭接收socket链接。。继续监视。如果没有接收到数据,则跳出循环。


    服务端代码


    	//初始化Winscok
    	if (!AfxSocketInit())
    	{
    		AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
    		return 1;
    	}
    
    	m_exit = false;
    
    	CServerDlg *aDlg = (CServerDlg *)lParam;
    
    	//获取端口
    	CString strPort;
    	aDlg->GetDlgItemText(IDC_EDIT_PORT, strPort);
    	UINT nPort = atoi(strPort);
    	
    	//socket----创建2个socket--------------------------------------------
    	CSocket aSocket, serverSocket;
    	//最好不要使用aSocket.Create创建,因为容易会出现10048错误
    	if (!aSocket.Socket())
    	{
    		char szError[256] = {0};
    		sprintf(szError, "Create Faild: %d", GetLastError());
    		AfxMessageBox(szError);
    		return 1; 
    	}
    
    	BOOL bOptVal = TRUE;
    	int bOptLen = sizeof(BOOL);
    	//设置Socket的选项, 解决10048错误必须的步骤
    	aSocket.SetSockOpt(SO_REUSEADDR, (void *)&bOptVal, bOptLen, SOL_SOCKET);
    	
    	 //绑定
    	if (!aSocket.Bind(nPort))
    	{
    		char szError[256] = {0};
    		sprintf(szError, "Bind Faild: %d", GetLastError());
    		AfxMessageBox(szError);	
    		return 1; 
    	}
    
    	//监听
    	if(!aSocket.Listen(10))
    	{	
    		char szError[256] = {0};
    		sprintf(szError, "Listen Faild: %d", GetLastError());
    		AfxMessageBox(szError);
    		return 1;
    	}
    	
    	CString strText;
    	aDlg->GetDlgItemText(IDC_EDIT_LOG, strText);
    	strText += "服务已经开启! \r\n";
    	aDlg->SetDlgItemText(IDC_EDIT_LOG, strText);
    	while(!m_exit)
    	{
    		//接收外部连接
    		if(!aSocket.Accept(serverSocket))
    		{
    			continue;
    		}
    		else
    		{
    			char szRecvMsg[256] = {0};
    			char szOutMsg[256] = {0};	
    			serverSocket.Receive(szRecvMsg, 256); //接收客户端内容:阻塞
    			sprintf(szOutMsg, "接受到的参数是: %s \r\n", szRecvMsg);
    			aDlg->GetDlgItemText(IDC_EDIT_LOG, strText);
    			strText += szOutMsg;
    			aDlg->SetDlgItemText(IDC_EDIT_LOG, strText);
    			serverSocket.Send("服务器已经收到,已经做出操作!", 50);//发送内容给客户端
    			serverSocket.Close();//关闭
    		}
    		
    	}
    	
    	aSocket.Close();
    	serverSocket.Close();
    	aDlg->GetDlgItemText(IDC_EDIT_LOG, strText);
    	strText += "Have Close!";
    	aDlg->SetDlgItemText(IDC_EDIT_LOG, strText);
    	return 0;

    客户端代码


    1,初始化 CSocket 对象,客户端可以是用Create 因为客户端不需要绑定任何端口和地址, 所以用默认参数即可

    2,连接指定的地址和端口是用函数Connect函数

    3,发送内容给服务器是用send函数

    4,接收服务端发送的内容使用Receive函数

    	
    	AfxSocketInit();
    	CSocket aSocket;
    	CString strIP;
    	CString strPort;
    	CString strText;
    	this->GetDlgItem(IDC_EDIT_IP)->GetWindowText(strIP);
    	this->GetDlgItem(IDC_EDIT_PORT)->GetWindowText(strPort);
    	this->GetDlgItem(IDC_EDIT_TEXT)->GetWindowText(strText);
    	 //初始化 CSocket 对象, 因为客户端不需要绑定任何端口和地址, 所以用默认参数即可
    	if(!aSocket.Create())
    	{
    		char szMsg[1024] = {0};
    
    		sprintf(szMsg, "create faild: %d", aSocket.GetLastError());
    
    		AfxMessageBox(szMsg);
    		return;
    	}
    	//转换需要连接的端口内容类型
    	int nPort = atoi(strPort);
    	//连接指定的地址和端口
    	if(aSocket.Connect(strIP, nPort))
    	{
    		char szRecValue[1024] = {0};
    		aSocket.Send(strText, strText.GetLength()); //发送内容给服务器
    		aSocket.Receive((void *)szRecValue, 1024); //接收服务器发送回来的内容(该方法会阻塞, 在此等待有内容接收到才继续向下执行)
    		AfxMessageBox(szRecValue);
    	}
    	else
    	{
    		char szMsg[1024] = {0};
    		sprintf(szMsg, "create faild: %d", aSocket.GetLastError());
    		AfxMessageBox(szMsg);
    	}
    	aSocket.Close();



    展开全文
  • vs2013编写的MFC串口通信程序,支持modbus协议,如遇到C4996警告,请右击工程 - 属性 - 配置属性 - C/C++ - 命令行 命令行增加 /D _CRT_SECURE_NO_WARNINGS 可发送和接送串口数据,zip内含一个串口大师调试工具,...
  • C++ MFC界面读写USB HID设备数据程序 发一个简单易用的界面,用来对USB HID设备(比如说游戏手柄,控制面板等)读写数据,一般情况下面板上有一些LED,可以帮助我们测试读写是否正确。另外,需要可以修改vendorID和...

    C++ MFC界面读写USB HID设备数据程序 发一个简单易用的界面,用来对USB HID设备(比如说游戏手柄,控制面板等)读写数据,一般情况下面板上有一些LED,可以帮助我们测试读写是否正确。另外,需要可以修改vendorID和prodcutID,这样一个界面,可以用于测试多个HID设备。

    过程分成3步:1: 列举出所有的HID设备,2: 循环读取HID设备数据,3: 向HID设备写数据,下面我把三部分的程序单独分开,方便大家学习!

    在讲具体程序之前,先说一下visual studio的环境配置(我用的是2008版本)!
    <下面程序需要包含DDK一部分头文件和库文件>

    第一步:列举所有的HID设备:

    
    ```cpp
    m_ctllHIDdevices.ResetContent(); //这是MFC里面一个list控件,用来显示所有的HID设备的,如果你没有界面,可以不需要此行
    UpdateData(FALSE); //更新界面
    CString temp;
    int Count = 0; //Total number of devices found
    DWORD strSize=0,requiredSize=0;
    BOOL result1,result2;
    ULONG DeviceInterfaceDetailDataSize;
    //定义一些变量,以后会用到
    SP_DEVINFO_DATA DeviceInfoData;
    SP_DEVICE_INTERFACE_DATA  DeviceInterfaceData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
    //PSP_DEVICE_INTERFACE_DETAIL_DATA test;
    //第一步:获取deviceID
    GUID deviceId;
    HidD_GetHidGuid(&deviceId);
    
    //第二步:获取设备信息
    HDEVINFO handle;
    handle = SetupDiGetClassDevs(&deviceId, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); //Get only HID devices
    
    
    //第三步:对所有的设备进行枚举
    //SetupDiEnumDeviceInterfaces();
    result1=false; //定义一些变量
    result2=false;
    CString temp11="";
    do
    {
      
            DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
            result1 = SetupDiEnumDeviceInterfaces(
                            handle,
                            NULL, // IN PSP_DEVINFO_DATA  DeviceInfoData,  OPTIONAL
                            &deviceId,
                            Count,
                            &DeviceInterfaceData
                             );
           //获得设备详细数据(初步)
           SetupDiGetDeviceInterfaceDetail(handle,
              &DeviceInterfaceData,
              NULL,
              0,
              &strSize,
              NULL);
          requiredSize=strSize;
          DeviceInterfaceDetailData=(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiredSize);
          DeviceInterfaceDetailData->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
          DeviceInfoData.cbSize=sizeof(SP_DEVINFO_DATA);
    
          //再次获得详细数据
          result2=SetupDiGetDeviceInterfaceDetail(handle,
                &DeviceInterfaceData,
                DeviceInterfaceDetailData,
                strSize,
                &requiredSize,
                &DeviceInfoData);
    
           //获得设备路径(最重要的部分)
           temp=DeviceInterfaceDetailData->DevicePath;
           UpdateData(FALSE);
           m_ctllHIDdevices.AddString(temp);
           Count++;
       } while (result1);
    
    
          UpdateData(false);
    
    
    到这个时候为止,所有的设备路径,都会显示在窗口的listbox里面!
    
    
     
    
    第二步:循环读取HID设备数据(根据用户提供的HID的vendorID和productID),并且把字节解码成二进制,在MFC界面上用LED展示:
    
    为了不影响主线程的运行,我把读取数据的操作,放在一个子线程里!每隔50ms去读取一次数据!
    
    首先创建一个线程:
            HANDLE hThread1;
            bStopHID=false; //这个变量,以后用来停止线程
            UpdateData(true); //更新界面,获取变量
            UpdateData(false);
            hThread1 = CreateThread(NULL,0,Thread_Enable_Read,(LPVOID)this, NULL, NULL);
    
    在线程的程序里:
    
           CusbhidDlg *p = ( CusbhidDlg *)pvParam; //获取主窗口的指针,用来调用主窗口的变量和函数
            
            p->UpdateData(true);
            p->bStopHID=false;
    
    
            CString temp;
            CString DevicePath;
            temp="";
    
            int Count = 0; //Total number of devices found
            DWORD strSize=0,requiredSize=0;
            BOOL result1,result2;
            ULONG DeviceInterfaceDetailDataSize;        
            SP_DEVINFO_DATA DeviceInfoData;
            SP_DEVICE_INTERFACE_DATA  DeviceInterfaceData;
            PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
            //PSP_DEVICE_INTERFACE_DETAIL_DATA test;
            //1
            GUID deviceId;
            HidD_GetHidGuid(&deviceId);
    
    
    
            int venderID=p->v_eVendorID; //从窗口里获取用户输入的VendorID
            int productID=p->v_eProductID;//从窗口里获取用户输入的ProductID
    
            
            unsigned char inbuffer[2]; //用来存放读取的数据,请在这里定义你自己需要的长度,我每次读一个字节进来
            unsigned long numBytesReturned;
            HIDD_ATTRIBUTES devAttr;
            PHIDP_PREPARSED_DATA PreparsedData;
            HIDP_CAPS Capabilities;
            int readValue;
            bool LED;
            int flag=0;
            
            
            //2
            HDEVINFO handle;
            handle = SetupDiGetClassDevs(&deviceId, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); //Get only HID devices
            int i=0;
            int j=p->m_ctllHIDdevices.GetCount();
            for (i=0;i<p->m_ctllHIDdevices.GetCount();i++)
            {
                    p->m_ctllHIDdevices.GetText(i,temp);
                    DevicePath=temp;
    
                   //CreateFile是非常重要的一步,用来建立于HID通信的句柄
                    HANDLE hCom = CreateFile (
                    DevicePath,
                    GENERIC_READ | GENERIC_WRITE,
                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING, 0,
                    NULL);
    
                    if (hCom == INVALID_HANDLE_VALUE)
    
                    {             
                       //AfxMessageBox("Invalide Device Path...");
                       continue;
    
                    }
    
                    devAttr.Size=sizeof(HIDD_ATTRIBUTES);
    
                    if (!HidD_GetAttributes(hCom,&devAttr))
    
                    {
    
                            CloseHandle(hCom);
                            AfxMessageBox("Cannot get the parameters of the HID...");
                            return 0;   
    
                    }
    
                    //temp.Format("Vendor ID: %d, Product ID:%d",devAttr.VendorID,devAttr.ProductID); //Compare with the Vendor ID and Product ID from Nakamura-san
                    //AfxMessageBox(temp);
    
            
                    if (!HidD_GetPreparsedData(hCom,&PreparsedData))
                    {
    
                            CloseHandle(hCom);
                            AfxMessageBox("Cannot get the Preparsed Data...");
                            return 0;   
    
                    }
            
                    
                    if(!HidP_GetCaps(PreparsedData,&Capabilities))
                    {
    
                            CloseHandle(hCom);
                            AfxMessageBox("Cannot get the Cap Data...");
                            return 0;   
    
                    }
                   if (devAttr.VendorID == venderID && devAttr.ProductID == productID) 
                    {
                                    while(1)
                                    {
    
    
                                            result1 = ReadFile(hCom, &inbuffer[0], Capabilities.InputReportByteLength, &numBytesReturned, 0);
                                            temp=inbuffer;
    
                                            //p->m_eDataRead=CString(inbuffer);
                                            //p->UpdateData(false);
                                            if(!result1)
                                            {
                                                    AfxMessageBox("Cannot Read Data...");
                                                    return 0;   
    
                                            
                                            }
    
                                            readValue=inbuffer[1];
                                            p->m_eDataRead.Format("%d",readValue);
                                            //下面是我把数据从10进制转换成二进制,并且点亮LED (一个字节有8个bits,可以点亮8个LED
                                            for (int k=0;k<8;k++)
                                            {
                                                    
                                                    flag=readValue%2;
                                                    readValue=readValue/2;        
                                                    
                                                    if (k==0)
                                                    {
                                                            if (flag==0)
                                                                    p->m_sDynLED0.SwitchOff();
                                                            else
                                                                    p->m_sDynLED0.SwitchOn();
    
                                                    }
                                                    else if (k==1)
                                                    {
                                                            if (flag==0)
                                                                    p->m_sDynLED1.SwitchOff();
                                                            else
                                                                    p->m_sDynLED1.SwitchOn();
    
                                                    }
                                                    
    
                                                    else if (k==2)
                                                    {
                                                            if (flag==0)
                                                                    p->m_sDynLED2.SwitchOff();
                                                            else
                                                                    p->m_sDynLED2.SwitchOn();
    
                                                    }
                                                    
                                                    else if (k==3)
                                                    {
                                                            if (flag==0)
                                                                    p->m_sDynLED3.SwitchOff();
                                                            else
                                                                    p->m_sDynLED3.SwitchOn();
    
                                                    }
                                                    
    
                                                    else if (k==4)
                                                    {
                                                            if (flag==0)
                                                                    p->m_sDynLED4.SwitchOff();
                                                            else
                                                                    p->m_sDynLED4.SwitchOn();
    
                                                    }
                                                    
    
                                                    else if (k==5)
                                                    {
                                                            if (flag==0)
                                                                    p->m_sDynLED5.SwitchOff();
                                                            else
                                                                    p->m_sDynLED5.SwitchOn();
    
                                                    }
                                                    
    
                                                    else if (k==6)
                                                    {
                                                            if (flag==0)
                                                                    p->m_sDynLED6.SwitchOff();
                                                            else
                                                                    p->m_sDynLED6.SwitchOn();
    
                                                    }
                                                    
    
                                                    else if (k==7)
                                                    {
                                                            if (flag==0)
                                                                    p->m_sDynLED7.SwitchOff();
                                                            else
                                                                    p->m_sDynLED7.SwitchOn();
    
                                                    }
                                    
    
    
                                            }
    
                                            p->UpdateData(false);
                                            
    
                                            ::Sleep(50);
                                            //判断用户是否点击停止按钮,若是,则退出
                                            if(p->bStopHID) 
                                            {
    
                                            AfxMessageBox("stopped...");
                                            return 0;
    
                                            }
    
                                    }
                    }
            }
    
            if (i==j)
            {
                    AfxMessageBox("There is no such HID device...");
    
            }
            return 0;
    
    第三步:向HID设备写数据(根据用户提供的HID的vendorID和productID),用户输入的是二进制数据:
    
    与读的程序一样,唯一区别就是红色那部分!
    
    UpdateData(true);
    bStopHID=false;
    
    CString temp;
    CString DevicePath;
    temp="";
    int Count = 0; //Total number of devices found
    DWORD strSize=0,requiredSize=0;
    BOOL result1,result2;
    ULONG DeviceInterfaceDetailDataSize; 
    SP_DEVINFO_DATA DeviceInfoData;
    SP_DEVICE_INTERFACE_DATA  DeviceInterfaceData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
    //PSP_DEVICE_INTERFACE_DETAIL_DATA test;
    //1
    GUID deviceId;
    HidD_GetHidGuid(&deviceId);
    
    int venderID=v_eVendorID;
    int productID=v_eProductID;
    
    unsigned char inbuffer[2];
    unsigned long numBytesReturned;
    HIDD_ATTRIBUTES devAttr;
    PHIDP_PREPARSED_DATA PreparsedData;
    HIDP_CAPS Capabilities;
    int readValue;
    bool LED;
    int flag=0;
    inbuffer[0]=0;
    //把界面里的二进制转换成10进制
    inbuffer[1]=m_eByte0*1+m_eByte1*2+m_eByte2*4+m_eByte3*8+m_eByte4*16+m_eByte5*32+m_eByte6*64+m_eByte7*128;
    
    v_eDataToWrite=inbuffer[1];
    UpdateData(false);
    
    //2
    HDEVINFO handle;
    handle = SetupDiGetClassDevs(&deviceId, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); //Get only HID devices
    int i=0;
    int j=m_ctllHIDdevices.GetCount();
    for (i=0;i<m_ctllHIDdevices.GetCount();i++)
    {
      m_ctllHIDdevices.GetText(i,temp);
      DevicePath=temp;
      HANDLE hCom = CreateFile (
                  DevicePath,
                  GENERIC_READ | GENERIC_WRITE,
                  FILE_SHARE_READ | FILE_SHARE_WRITE,
                  NULL,
                  OPEN_EXISTING, 0,
                  NULL);
      if (hCom == INVALID_HANDLE_VALUE)
      {             
         //AfxMessageBox("Invalide Device Path...");
               continue;
      }
      devAttr.Size=sizeof(HIDD_ATTRIBUTES);
      if (!HidD_GetAttributes(hCom,&devAttr))
      {
       CloseHandle(hCom);
       AfxMessageBox("Cannot get the parameters of the HID...");
       return;   
      }
      //temp.Format("Vendor ID: %d, Product ID:%d",devAttr.VendorID,devAttr.ProductID); //Compare with the Vendor ID and Product ID from Nakamura-san
      //AfxMessageBox(temp);
    
      if (!HidD_GetPreparsedData(hCom,&PreparsedData))
      {
       CloseHandle(hCom);
       AfxMessageBox("Cannot get the Preparsed Data...");
       return;   
      }
    
      
      if(!HidP_GetCaps(PreparsedData,&Capabilities))
      {
       CloseHandle(hCom);
       AfxMessageBox("Cannot get the Cap Data...");
       return;   
      }
    
    
    // Write File
      if (devAttr.VendorID == venderID && devAttr.ProductID == productID) 
      {
       result1 = WriteFile(hCom, inbuffer, 2, &numBytesReturned, NULL);
       //temp=inbuffer;
       //p->m_eDataRead=CString(inbuffer);
       //p->UpdateData(false);
       if(!result1)
       {
          AfxMessageBox("Cannot Write Data...");
          return;   
         
       }
       AfxMessageBox("Suncess...");
       break;
       
      }
    }
    if (i==j)
    {
      AfxMessageBox("There is no such HID device...");
    }
    return;
    
    
     
    
    
    
    展开全文
  • MFC串口通信

    2020-07-27 23:30:39
    采用MFC控件来进行串口通信编程,主要针对初学者!包含源代码
  • MFC串口通信发送16进制数据

    千次阅读 2018-05-15 17:01:32
    MFC串口通信会使用m_mscomm控件。发送数据一般是在edit control 里输入自己想发送的内容,然后点击send button。如果直接发送字符串内容,通过下面代码(send button内写入)即可: UpdateData(true); //读取编辑框...
  • Visual C++/MFC入门教程

    万次阅读 2014-04-14 19:14:55
    Visual C++/MFC入门教程 VC开发指南  讲述Visual C++/MFC开发的基本知识,文档/视结构,窗体控件的使用和一些基本的网络开发知识。同时指出一些在开发容易犯的错误和一些注意事项。本教程主要侧重于讲解MFC...
  • 本实例利用匿名管道技术实现多进程之间的通信,实现了进程之间的发送数据和接收数据
  • MFC入门,想设计一个串口...请教一下MFC串口同步通信该怎样判断有数据传入? 当有数据传入会触发什么标志?或者产生什么事件? 如果是触发什么标志,程序在待机时怎样检测这个标志? 如果是事件,事件名称是什么?
  • C++ MFC框架结构的分析

    2019-09-03 12:56:36
    上一节我们基于MFC的框架结构,创建了一个默认的基于对话框的应用程序。没有添加一行代码,但是运行程序却弹出了一个对话框界面。本节将要介绍上一节所生成的框架代码,来更多地了解MFC应用程序,能更好地在MFC框架...
  • MFC实现UDP通信

    2020-07-29 14:20:21
    开发工具为vs2008,编程语言为C++,实现UDP通信,一个程序既可以作为服务器,也可以作为客户端
  • C++(MFC)和PLC使用TCP通信

    千次阅读 2019-06-24 12:14:51
    最近做的项目,MFC作为server,PLC作为client,搞了两天,还是基础太差,先记录一下遇到的问题吧。
  • C++MFC,与C#的.NET

    千次阅读 2016-08-22 19:54:26
    【1】MFC早已过时,现在C++多数是用来编写底层方法而不是开发桌面程序,桌面程序有Delphi,其控件库比MFC要多,微软早不维护MFC了。 【2】MFC学习曲线的陡峭是众所周知的,主要难点在于C++语言本身,和MFC使用了...
  • C++ MFC与三菱PLC通讯

    千次阅读 热门讨论 2019-12-04 18:18:55
    本篇文章讲述的是使用C++ mfc与三菱plc成功建立连接,并在程序实现与PLC的数据交换。 1.建立连接 三菱公司提供了三菱PLC和上位机的通讯辅助软件:MX Component 1. 下载并安装MX Component软件:网上搜索MX ...
  • 本人一位大三的学生,使用MFC做界面,为了提取串口来的数据,写了个简单的提取代码,希望对初学者有用。 工具版本:vs2013+mfc。 void CPORTMFCDlg::OnCommMscomm1() { m_strRXData = ""; m_strRXData2 = ""; ...
  • [Visual C++系列]Visual C++/MFC入门教程

    千次阅读 2011-08-06 11:18:56
    [Visual C++系列]Visual C++/MFC入门教程 目录 +-- 第一章 VC入门 |------ 1.1 如何学好VC |------ 1.2 理解Windows消息机制 |------ 1.3 利用Visual C++/MFC开发Windows程
1 2 3 4 5 ... 20
收藏数 12,497
精华内容 4,998
热门标签
关键字:

c++中的mfc数据通信