⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialasdlg.cpp

📁 这是我仿照串口助手(龚建伟)作的一个例子并修正了其中的一些bug
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		GetLocalTime(&st); 
		str.Format("%02d:%02d:%02d",st.wHour,st.wMinute,st.wSecond);
		UpdateStatusBarInfo(m_StatusBar,2,str);
	}
	else if(nIDEvent==TIME_ID_REV)
	{
		if(m_bRevUpdate)
		{
			m_bRevUpdate = FALSE;
		}
	}
	else if(nIDEvent==TIME_ID_SEND)
	{
		if(m_bAutoSend)
		{
			::SetEvent(m_hSendEvent);
		}
	}
	CDialog::OnTimer(nIDEvent);
}

void CSerialAsDlg::OnSelectsendfile() 
{
	// TODO: Add your control notification handler code here
	static char BASED_CODE szSplitFilter[] = _T("(*.*)|*.*||");

	CFileDialog dlg(TRUE,
					NULL,
					NULL,
					OFN_HIDEREADONLY	| 
					OFN_OVERWRITEPROMPT ,
					szSplitFilter
					);

	if(dlg.DoModal()==IDOK)
	{
		GetDlgItem(IDC_EDITSENDFILEPATH)->SetWindowText(dlg.GetPathName());
		CFile file;
		file.Open(dlg.GetPathName(),CFile::modeRead,NULL);
		m_dwSendFileLen = file.GetLength();
		CString str;
		if(m_dwSendFileLen<1024)
			str.Format(_T("文件大小:%d字节,发送时间:%d秒"),m_dwSendFileLen,	int(m_dwSendFileLen/GetByteRate()+1));
		else if(m_dwSendFileLen>1024&&m_dwSendFileLen<1024*1024)
			str.Format(_T("文件大小:%.1fK,发送时间:%d秒"),m_dwSendFileLen/1024.0,	int(m_dwSendFileLen/GetByteRate()));
		else
			str.Format(_T("文件大小:%.2fM,发送时间:%d秒"),m_dwSendFileLen/1024.0/1024.0,	int(m_dwSendFileLen/GetByteRate()));

		this->UpdateStatusBarInfo(m_StatusBar,1,str);
		file.Close();
	}
}

void CSerialAsDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	BOOL bFlag = FALSE;
	CString str;
	str.Empty();
	if(m_hCom!=NULL)
		str = _T("处于连接状态,确实要退出吗?");
	if(m_bSendFlag)
		str = _T("正在发送文件,确实要退出吗?");

	if(str.IsEmpty()) 
	{
		CDialog::OnCancel();
	}
	else
	{
		if(MessageBox(str,_T("退出确认"),MB_OKCANCEL)==IDOK)
			bFlag = TRUE;
	}
		
	if(bFlag)
	{
		if(m_hCom!=NULL)
		{
			OnBtncloseport(); 
		}	
		CDialog::OnCancel();
	}
}

LRESULT CSerialAsDlg::OnSend(WPARAM wParam,LPARAM lParam)
{
	SEND *pSend = (SEND*)(lParam);
	m_dwSendCount += DWORD(wParam);
	CString str;
	str.Format(_T("TX:%d"),m_dwSendCount);
	GetDlgItem(IDC_EDITSENDCOUNT)->SetWindowText(str);
	if(pSend->bFlag)
	{
		str.Format(_T("正在发送:%.1f%%,剩余时间%d秒"),pSend->value,UINT(m_dwSendFileLen*(100-pSend->value)/100/GetByteRate()));
		UpdateStatusBarInfo(m_StatusBar,1,str);
	}
	if(pSend->bFlag==TRUE&&pSend->value < 0.000001)	 
	{
		UpdateStatusBar();
		str.Format(_T("已发送完毕!"));
		if(m_bCancelSend)
		{
			str.Format(_T("已取消发送!"));
			GetDlgItem(IDC_STARTSENDFILE)->SetWindowText(_T("发送文件"));
		}
		UpdateStatusBarInfo(m_StatusBar,1,str);
		GetDlgItem(IDC_BTNCLOSEPORT)->EnableWindow(TRUE);
		m_StatusBar.OnProgress(0);
	}
	if(pSend->value>0.0001&&pSend->value<1.1)
		pSend->value = 1.00001;
	if(pSend->bFlag) m_StatusBar.OnProgress(UINT(pSend->value));
	return 0;
}

LRESULT CSerialAsDlg::OnReceive(WPARAM wParam,LPARAM lParam)
{
	CString str,strTemp;
	str.Empty();
	m_bRevCS.Lock();
	int size = m_dequeRevData.size();
	for(int i=0;i<size;i++)
	{
		
		if(!m_bHexDisplay)
		{
			strTemp.Format("%c",m_dequeRevData[0]);
		}
		else
		{
			strTemp.Format(" %02x",m_dequeRevData[0]);
		}
		m_dequeRevData.pop_front();
		str += strTemp;
	}
	m_dwRevCount += size; 
	m_bRevCS.Unlock();
	COLORREF color;
	color = RGB(255,0,0);
	m_Rev.AddText(str,color);
//	m_bRevUpdate = TRUE;
	str.Format(_T("RX:%d"),m_dwRevCount);
	GetDlgItem(IDC_EDITREVCOUNT)->SetWindowText(str);
	if(m_bAutoClear)
	{
		if(m_Rev.GetLineCount()>35)
			OnClearrevdata();
	}
	return 0;
}

void CSerialAsDlg::OnBtnclearrevcount() 
{
	// TODO: Add your control notification handler code here
	m_dwRevCount = 0;
	CString str;
	str.Format(_T("RX:%d"),m_dwRevCount);
	GetDlgItem(IDC_EDITREVCOUNT)->SetWindowText(str);
}

void CSerialAsDlg::OnBtnclearsendcount() 
{
	// TODO: Add your control notification handler code here
	m_dwSendCount = 0;
	CString str;
	str.Format(_T("TX:%d"),m_dwSendCount);
	GetDlgItem(IDC_EDITSENDCOUNT)->SetWindowText(str);
}

void CSerialAsDlg::OnClearrevdata() 
{
	// TODO: Add your control notification handler code here
	m_sRev = _T("");
	m_Rev.SetWindowText(m_sRev);
}

void CSerialAsDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
    PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));
	CDialog::OnLButtonDown(nFlags, point);
}

void CSerialAsDlg::OnCheckhexdisplay() 
{
	// TODO: Add your control notification handler code here
	m_bHexDisplay = !m_bHexDisplay;
}

UINT CSerialAsDlg::SendThreadProc(LPVOID pParam)
{
	CSerialAsDlg *pDlg = (CSerialAsDlg *)pParam;
	HANDLE hEvent = 0;
	OVERLAPPED overlapped;
	DWORD dwWrite = 0;
	memset(&overlapped,0,sizeof(OVERLAPPED));
	static _SEND send;

	hEvent = CreateEvent( 
		NULL,         // no security attributes
		TRUE,         // manual-reset event
		FALSE,        // initial state is nosignaled
		NULL		  // object name
		); 
	overlapped.hEvent = hEvent;
	while(pDlg->m_bRun)
	{
		::WaitForSingleObject(pDlg->m_hSendEvent,0xFFFFFFFF);
		::ResetEvent(pDlg->m_hSendEvent);
		if(pDlg->m_hCom==NULL)
			return 0;
	CString str;
	pDlg->m_Send.GetWindowText(str);
	DWORD len = str.GetLength();
	DWORD dwBytesWrite = 0;
	BOOL bStatus;

	if(pDlg->m_bHEXSend)
	{
		BYTE *p = new BYTE[len+1];
		len = pDlg->StrToHex(str,p,len);
		bStatus = WriteFile(pDlg->m_hCom,p, 
						len	,&dwWrite, &overlapped);
	}
	else
	{
		bStatus = WriteFile(pDlg->m_hCom,str, 
							len	,&dwWrite, &overlapped);
	}
	if(!bStatus)
	{
		if(GetLastError()==ERROR_IO_PENDING)
		{
			
			while(!GetOverlappedResult(pDlg->m_hCom, 
				
				&overlapped, &dwBytesWrite, TRUE ))
			{ 
				if(GetLastError() == ERROR_IO_INCOMPLETE) 
					continue;
				
			}
			send.bFlag = false;
			send.value = 0;
			pDlg->PostMessage(WM_SEND,dwBytesWrite,(LPARAM)&send);
		}
	}
	else
	{
		send.bFlag = false;
		send.value = 0;
		pDlg->PostMessage(WM_SEND,len,(LPARAM)&send);
	}
	}
	return 0;
}

UINT CSerialAsDlg::SendFileThreadProc(LPVOID pParam)
{
	CSerialAsDlg *pDlg = (CSerialAsDlg *)pParam;
	HANDLE hEvent = 0;
	OVERLAPPED overlapped;
	DWORD dwWrite = 0;
	memset(&overlapped,0,sizeof(OVERLAPPED));
	static SEND send;
	
	hEvent = CreateEvent( 
		NULL,         // no security attributes
		TRUE,         // manual-reset event
		FALSE,        // initial state is nosignaled
		NULL		  // object name
		); 
	overlapped.hEvent = hEvent;
	
	CString sFilePathName;
	pDlg->GetDlgItem(IDC_EDITSENDFILEPATH)->GetWindowText(sFilePathName);
	
	DWORD dwAttr;
	dwAttr=GetFileAttributes(sFilePathName);
	if(dwAttr==0xFFFFFFFF)
	{
		::MessageBox(NULL,_T("文件路径不对"),"提示",MB_OK|MB_ICONERROR);

		pDlg->GetDlgItem(IDC_BTNCLOSEPORT)->EnableWindow(TRUE);
		pDlg->GetDlgItem(IDC_STARTSENDFILE)->SetWindowText(_T("发送文件"));
		pDlg->GetDlgItem(IDC_STARTSENDFILE)->EnableWindow(TRUE);
		pDlg->m_bSendFlag = FALSE;
		return 0;
	}
	
	CFile file(sFilePathName,CFile::modeRead);//只读方式打开
	file.Seek(0,CFile::begin);///从文件头开始往下移动0字节
	
#define LENGTH (1024)
	BYTE *pFile = new BYTE[LENGTH];
	DWORD dwLength = (long)file.GetLength();
	BOOL bFlag = TRUE;
	DWORD dwLeaveLen = dwLength;
	BOOL bStatus;
	DWORD dwBytesWrite = 0;
	pDlg->GetDlgItem(IDC_STARTSENDFILE)->EnableWindow(TRUE);
	while(bFlag&&pDlg->m_bSendFlag)
	{
		DWORD len = 0;
		if(dwLeaveLen<LENGTH)
		{
			len = dwLeaveLen;
			bFlag = FALSE;
		}
		else
		{
			dwLeaveLen -= LENGTH;
			len = LENGTH;
		}
		file.Read(pFile,len);
		bStatus = WriteFile(pDlg->m_hCom,pFile, 
			len,&dwWrite, &overlapped);
		if(!bStatus)
		{
			if(GetLastError()==ERROR_IO_PENDING)
			{
				
				while(!GetOverlappedResult(pDlg->m_hCom, 
					
					&overlapped, &dwBytesWrite, TRUE ))
				{ 
					if(GetLastError() == ERROR_IO_INCOMPLETE) 
						continue;
					
				}
				send.bFlag = true;
				send.value = (dwLength-dwLeaveLen)*100.0/dwLength;
				pDlg->PostMessage(WM_SEND,dwBytesWrite,(LPARAM)(&send.bFlag));
			}
		}
		else
		{
			send.bFlag = true;
			send.value = 0.0;
			pDlg->PostMessage(WM_SEND,len,(LPARAM)&send);
		}
		
	}
	file.Close();
	send.bFlag = true;
	send.value = 0.0;
	pDlg->PostMessage(WM_SEND,0,(LPARAM)&send);
	pDlg->m_bSendFlag = FALSE;
	SetEvent(pDlg->m_hEventSendFile);
	return 0;
}

void CSerialAsDlg::OnStartsendfile() 
{
	// TODO: Add your control notification handler code here
	static CWinThread* thread;
	if(!m_bSendFlag)
	{
		m_bSendFlag = TRUE;
		m_bCancelSend = FALSE;
		GetDlgItem(IDC_BTNCLOSEPORT)->EnableWindow(FALSE);
		GetDlgItem(IDC_STARTSENDFILE)->EnableWindow(FALSE);
		GetDlgItem(IDC_STARTSENDFILE)->SetWindowText(_T("取消发送"));
		ResetEvent(m_hEventSendFile);
		thread = AfxBeginThread(SendFileThreadProc,this,THREAD_PRIORITY_NORMAL,0,0,NULL);
	}
	else
	{
		m_bSendFlag = FALSE;
		m_bCancelSend = TRUE;
		DWORD st = WaitForSingleObject(m_hEventSendFile,2000);
		if(st==WAIT_TIMEOUT)
		{
			TerminateThread(thread,0);
		}
		GetDlgItem(IDC_BTNCLOSEPORT)->EnableWindow(TRUE);
		GetDlgItem(IDC_STARTSENDFILE)->SetWindowText(_T("发送文件"));
	}
}

void CSerialAsDlg::OnCheckautosend() 
{
	// TODO: Add your control notification handler code here
	CString str;
	GetDlgItem(IDC_EDITSENDPERIOD)->GetWindowText(str);
	int iPeriod = atoi(str);
	if(!m_bAutoSend)
	{
		if(iPeriod==0)
		{
			MessageBox(_T("请选择一个合适的周期!"),_T("提示!"),MB_ICONERROR);
			m_checkAutoSend.SetCheck(0);
			return ;
		}
	}

	m_bAutoSend = !m_bAutoSend;
	if(m_bAutoSend)
	{

		SetTimer(TIME_ID_SEND,iPeriod,NULL);
	}
	else
	{
		KillTimer(TIME_ID_SEND);
	}
}

void CSerialAsDlg::OnManualsend() 
{
	// TODO: Add your control notification handler code here
	SetEvent(m_hSendEvent);
}

void CSerialAsDlg::OnCheckautoclear() 
{
	// TODO: Add your control notification handler code here
	m_bAutoClear = !m_bAutoClear;
}

void CSerialAsDlg::OnClearsenddata() 
{
	// TODO: Add your control notification handler code here
	SetDlgItemText(IDC_RICHEDITSENDDATA,_T(""));
}

void CSerialAsDlg::OnCheckhexsend() 
{
	// TODO: Add your control notification handler code here
	m_bHEXSend = !m_bHEXSend;
}


DWORD CSerialAsDlg::StrToHex(CString str,BYTE *p,DWORD len)
{

	BYTE *pTemp = new BYTE[len];
	str.MakeLower();
	str.TrimLeft();
	str.TrimRight();
	str.Replace(_T('\n'),_T(' '));
	str.Replace(_T('\r'),_T(' '));
	len = str.GetLength();
	memcpy(pTemp,p,len);
	pTemp = (BYTE *)str.GetBuffer(len);
	DWORD dwStart = 0;
	BYTE value = 0;
	DWORD i=0;
	DWORD count = 0;
	for(i=0;i<len;i++)
	{
	
		if(('0'<=pTemp[i]&&pTemp[i]<='9')||('a'<=pTemp[i]&&pTemp[i]<='f')||pTemp[i]==' ')
		{
			continue;
		}
		else
		{
			str.ReleaseBuffer();
			return 0;
		}
	}
	BOOL bFlag= false;
    for(i=0;i<len;i++)
	{
		if(pTemp[i]!=' ')
		{
			if(!bFlag)
			{
				dwStart = i;
				bFlag = TRUE;  //新的一个数开始了
			}
		}
		else if(bFlag)
		{
			if(i-dwStart>2)
				{
					str.ReleaseBuffer();
					return 0;
				}
				else
				{
					if(i-dwStart==2)
					{
						p[count] = HEXToDec(pTemp[dwStart])*16;
						p[count++] += HEXToDec(pTemp[dwStart+1]);
					}
					else
					{
						p[count++] = HEXToDec(pTemp[dwStart]);
					}
				}
				bFlag = false;
				continue;
		}
		if(i==len-1)
		{
			i++;
			if(i-dwStart>2)
				{
					str.ReleaseBuffer();
					return 0;
				}
				else
				{
					if(i-dwStart==2)
					{
						p[count] = HEXToDec(pTemp[dwStart])*16;
						p[count++] += HEXToDec(pTemp[dwStart+1]);
					}
					else
					{
						p[count++] = HEXToDec(pTemp[dwStart]);
					}
				}
		}
	}

	str.ReleaseBuffer();
	return count;
}

//把一个字母或数字转换为十进制
BYTE CSerialAsDlg::HEXToDec(BYTE value)
{
	if('0'<=value&&value<='9')
	{
		return value-'0';
	}
	else if('a'<=value&&value<='f')
	{
		return value-'a'+10;
	}
	return 0;
}

void CSerialAsDlg::OnBtnsavefile() 
{
	// TODO: Add your control notification handler code here
	CString str;
	GetDlgItemText(IDC_RICHEDITREVDATA,str);
	DWORD len = str.GetLength();
	if(len ==0) 
	{
		MessageBox(_T("接受区无数据!"),_T("提示"),MB_ICONERROR);
		return; 
	}

	GetDlgItemText(IDC_STATICSAVEFILEPATH,str);
	if(!PathFileExists(m_sSaveDir))
	{
		if(MessageBox(_T("没有此目录,要创建吗?"),_T("提示"),MB_OKCANCEL)==IDOK)
		{
			if(!CFilePro::CreateFolder(m_sSaveDir))
				return;
		}
		else
		{
			return;
		}
	}
	WriteMyFile(str);
}

void CSerialAsDlg::OnBtnchangesavefilepath() 
{
	// TODO: Add your control notification handler code here
	LPITEMIDLIST  pidlBeginAt ;
    // 取得开始菜单或桌面的PIDL
    if(NOERROR !=SHGetSpecialFolderLocation( HWND_DESKTOP, 
            CSIDL_DESKTOP, 
			&pidlBeginAt) )
	{
		CFilePro::ReleasePIDL(&pidlBeginAt);
		return;
	}
	TCHAR szPath[ MAX_PATH] ;
	if(CFilePro::BrowseForFolder(m_hWnd,pidlBeginAt, szPath,_T("请选择要存放文件的目录:")))
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -