📄 tcp2comdlg.cpp
字号:
// Tcp2ComDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "Tcp2Com.h"
#include "Tcp2ComDlg.h"
#include ".\tcp2comdlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
char Char2Hex( char ch )
{
if( 0<=ch && ch <= 9 )
ch += '0';
else if( 10<= ch && ch <= 15 )
{
ch -= 10;
ch += 'A';
}
return ch;
}
char Hex2Char( char ch )
{
if( '0'<=ch && ch<='9' )
ch -= '0';
else if( 'A'<=ch && ch<='F')
{
ch -= 'A';
ch += 10;
}
else if( 'a'<=ch && ch<='f' )
{
ch -= 'a';
ch += 10;
}
return ch;
}
CString Byte2HexStr( const char *pbuf, int nLen )
{
CString res;
for(int i=0; i<nLen; ++i)
{
unsigned char ch = static_cast<unsigned char>(pbuf[i]);
res.AppendChar( Char2Hex( 0x0F&(ch>>4) ) );
res.AppendChar( Char2Hex( 0x0F&ch ) );
}
return res;
}
int HexStr2Byte( const CString& str, char *pbuf )
{
int nLen = 0;
for( int i=0; i<str.GetLength()-1; i+=2 )
{
char hight = Hex2Char( str[i] );
if( str[i] == hight )
return 0;
char low = Hex2Char( str[i+1] );
if( str[i+1]==low )
return 0;
pbuf[nLen++] = ( (hight<<4)&0xF0 ) | (low&0x0F) ;
}
return nLen;
}
// 用于应用程序“关于”菜单项的 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()
// CTcp2ComDlg 对话框
CTcp2ComDlg::CTcp2ComDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTcp2ComDlg::IDD, pParent)
, m_strServer(_T("127.0.0.1"))
, m_nPort(1001)
, m_socket(this)
, m_strNO(_T("101"))
, m_nSerialRecvCnt(0)
, m_nTimer(0)
, m_tmrComRecv(0)
, m_nComRecvTimeout(2)
, m_bHex1(FALSE)
, m_bHex2(FALSE)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTcp2ComDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_SERVER, m_strServer);
DDX_Text(pDX, IDC_EDIT_PORT, m_nPort);
DDV_MinMaxInt(pDX, m_nPort, 0, 65535);
DDX_Text(pDX, IDC_EDIT_NO, m_strNO);
DDX_Control(pDX, IDC_COMBO_BAND, m_cbxBand);
DDX_Control(pDX, IDC_COMBO_DATABIT, m_cbxDataBit);
DDX_Control(pDX, IDC_COMBO_JYBIT, m_cbxJyBit);
DDX_Control(pDX, IDC_COMBO_STOPBIT, m_cbxStopBit);
DDX_Control(pDX, IDC_COMBO_SERIAL_PORT, m_cbxSerial);
DDX_Control(pDX, IDC_LIST1, m_lcTcpRecv);
DDX_Control(pDX, IDC_LIST2, m_lcComRecv);
DDX_Text(pDX, IDC_EDIT_RECV_TMR, m_nComRecvTimeout);
DDV_MinMaxInt(pDX, m_nComRecvTimeout, 1, 100);
DDX_Check(pDX, IDC_CHECK1, m_bHex1);
DDX_Check(pDX, IDC_CHECK2, m_bHex2);
DDX_Control(pDX, IDC_CHECK1, m_btnHex1);
DDX_Control(pDX, IDC_CHECK2, m_btnHex2);
}
BEGIN_MESSAGE_MAP(CTcp2ComDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON_START, OnBnClickedButtonStart)
ON_BN_CLICKED(IDC_BUTTON_STOP, OnBnClickedButtonStop)
ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
ON_MESSAGE(WM_COMM_RXCHAR, OnSerialRecvChar)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON_QUIT, OnBnClickedButtonQuit)
ON_NOTIFY(NM_DBLCLK, IDC_LIST1, OnNMDblclkList1)
ON_NOTIFY(NM_DBLCLK, IDC_LIST2, OnNMDblclkList2)
ON_BN_CLICKED(IDC_CHECK1, OnBnClickedCheck1)
ON_BN_CLICKED(IDC_CHECK2, OnBnClickedCheck2)
END_MESSAGE_MAP()
// CTcp2ComDlg 消息处理程序
BOOL CTcp2ComDlg::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: 在此添加额外的初始化代码
//
for(int i=1; i<=4; ++i )
{
CString tmp;
tmp.Format("COM%d", i);
m_cbxSerial.AddString(tmp);
}
m_cbxSerial.SelectString(0,"COM1");
//
for(long i=1200; i<=115200; i *=2 )
{
CString tmp;
tmp.Format("%d", i);
m_cbxBand.AddString(tmp);
}
m_cbxBand.SelectString(0, "2400");
//
for(int i=5; i<=8; ++i )
{
CString tmp;
tmp.Format("%d", i);
m_cbxDataBit.AddString(tmp);
}
m_cbxDataBit.SelectString(0,"8");
//
m_cbxJyBit.AddString("奇校验");
m_cbxJyBit.AddString("偶校验");
m_cbxJyBit.AddString("无");
m_cbxJyBit.SelectString(0,"无");
//
m_cbxStopBit.AddString("1");
m_cbxStopBit.AddString("2");
m_cbxStopBit.SelectString(0, "1");
//
m_lcTcpRecv.SetExtendedStyle(
LVS_EX_FLATSB
|LVS_EX_FULLROWSELECT
|LVS_EX_GRIDLINES
|LVS_EX_HEADERDRAGDROP
|LVS_EX_MULTIWORKAREAS);
i = 0;
m_lcTcpRecv.InsertColumn( i++, "文本形式内容", LVCFMT_LEFT, 200 );
m_lcTcpRecv.InsertColumn( i++, "十六进制内容", LVCFMT_LEFT, 400 );
//
m_lcComRecv.SetExtendedStyle(
LVS_EX_FLATSB
|LVS_EX_FULLROWSELECT
|LVS_EX_GRIDLINES
|LVS_EX_HEADERDRAGDROP
|LVS_EX_MULTIWORKAREAS);
i = 0;
m_lcComRecv.InsertColumn( i++, "文本形式内容", LVCFMT_LEFT, 200 );
m_lcComRecv.InsertColumn( i++, "十六进制内容", LVCFMT_LEFT, 400 );
return TRUE; // 除非设置了控件的焦点,否则返回 TRUE
}
void CTcp2ComDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CTcp2ComDlg::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 CTcp2ComDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CTcp2ComDlg::OnConnectSucess()
{
MessageBox("连接成功");
}
void CTcp2ComDlg::OnConnectFail()
{
m_socket.Close();
GetDlgItem(IDC_BUTTON_START)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
MessageBox("连接失败");
}
void CTcp2ComDlg::OnClose()
{
m_nSerialRecvCnt = 0;
m_socket.Close();
m_serial.StopMonitoring();
GetDlgItem(IDC_BUTTON_START)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(FALSE);
MessageBox("连接关闭");
}
void CTcp2ComDlg::OnBnClickedButtonStart()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData();
GetDlgItem(IDC_BUTTON_START)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE);
// 打开串口
CString tmp;
m_cbxSerial.GetWindowText(tmp);
unsigned int portnr = atoi( tmp.Right(1) );
//
m_cbxBand.GetWindowText(tmp);
unsigned int baud = atoi(tmp);
//
m_cbxJyBit.GetWindowText(tmp);
char parity = 'N';
if( "奇校验"==tmp )
parity = 'O';
else if( "偶校验"==tmp )
parity = 'E';
//
m_cbxDataBit.GetWindowText(tmp);
unsigned int databits = atoi(tmp);
//
m_cbxStopBit.GetWindowText(tmp);
unsigned int stopsbits = atoi(tmp);
//
if(FALSE==m_serial.InitPort(this, portnr, baud, parity, databits, stopsbits ))
{
m_cbxSerial.GetWindowText(tmp);
MessageBox(tmp+"打开失败");
GetDlgItem(IDC_BUTTON_START)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
return;
}
m_serial.StartMonitoring();
// 打开网络
m_socket.NO(m_strNO);
m_socket.Create( );
SOCKADDR_IN Addr;
memset( &Addr, 0, sizeof(SOCKADDR_IN) );
Addr.sin_family = AF_INET;
Addr.sin_port = htons(m_nPort);
Addr.sin_addr.S_un.S_addr = inet_addr(m_strServer);
m_socket.Connect( (SOCKADDR*)&Addr, sizeof(SOCKADDR_IN) );
m_nTimer = SetTimer(1, 50, NULL);
}
void CTcp2ComDlg::OnBnClickedButtonStop()
{
// TODO: 在此添加控件通知处理程序代码
m_socket.Close();
m_serial.KillMonitoring();
GetDlgItem(IDC_BUTTON_START)->EnableWindow(TRUE);
GetDlgItem(IDC_BUTTON_STOP)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE);
KillTimer(m_nTimer);
}
void CTcp2ComDlg::OnCancel()
{
// TODO: 在此添加专用代码和/或调用基类
}
void CTcp2ComDlg::OnOK()
{
// TODO: 在此添加专用代码和/或调用基类
}
void CTcp2ComDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CString s;
GetDlgItem(IDC_EDIT1)->GetWindowText(s);
char buf[CMySocket::MAX_BUF_LEN];
int nLen = 0;
if( m_btnHex1.GetCheck() )
{
nLen = HexStr2Byte( s, buf );
}
else
{
strcpy(buf, s);
nLen = s.GetLength();
}
if(nLen>0)
{
m_socket.SendSvr(buf, nLen);
GetDlgItem(IDC_EDIT1)->SetWindowText("");
}
else
{
MessageBox("没有要发送的字符或十六进制转换失败");
}
}
void CTcp2ComDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
CString s;
GetDlgItem(IDC_EDIT2)->GetWindowText(s);
char buf[CMySocket::MAX_BUF_LEN];
int nLen = 0;
if( m_btnHex2.GetCheck() )
{
nLen = HexStr2Byte( s, buf );
}
else
{
strcpy(buf, s);
nLen = s.GetLength();
}
if(nLen>0)
{
m_serial.WriteToPort(buf, nLen);
GetDlgItem(IDC_EDIT2)->SetWindowText("");
}
else
{
MessageBox("没有要发送的字符或十六进制转换失败");
}
}
LRESULT CTcp2ComDlg::OnSerialRecvChar( WPARAM wParam, LPARAM lParam )
{
CString tmp;
m_cbxSerial.GetWindowText(tmp);
unsigned int portnr = atoi( tmp.Right(1) );
if(portnr = (unsigned int)lParam)
{
// 收到一个字符
m_serialRecvBuf[m_nSerialRecvCnt++] = (char)wParam;
m_tmrComRecv = m_nComRecvTimeout;
}
return 0;
}
void CTcp2ComDlg::OnReceive()// TCP收到
{
char buf[CMySocket::MAX_BUF_LEN ];
int nLen = m_socket.RecvSvr(buf);
if( nLen>0 )
{
//
buf[nLen]=0;
TRACE("TCP Recv(cnt=%d)%s\n", nLen, buf);
int nItem = m_lcTcpRecv.GetItemCount();
m_lcTcpRecv.InsertItem(nItem, buf);
m_lcTcpRecv.SetItemText(nItem , 1, Byte2HexStr(buf, nLen));
m_lcTcpRecv.Scroll(CSize(0,25));
//
m_serial.WriteToPort(buf, nLen);
}
}
void CTcp2ComDlg::OnTimer(UINT nIDEvent)// COM收到
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if(m_tmrComRecv>0)
{
--m_tmrComRecv;
if(0==m_tmrComRecv)
{
if(m_nSerialRecvCnt>0)
{
//
m_serialRecvBuf[m_nSerialRecvCnt]=0;
TRACE("COM Recv(cnt=%d)%s\n", m_nSerialRecvCnt, m_serialRecvBuf);
int nItem = m_lcComRecv.GetItemCount();
m_lcComRecv.InsertItem(nItem, m_serialRecvBuf);
m_lcComRecv.SetItemText(nItem , 1, Byte2HexStr(m_serialRecvBuf, m_nSerialRecvCnt));
m_lcComRecv.Scroll(CSize(0,25));
//
m_socket.SendSvr(m_serialRecvBuf, m_nSerialRecvCnt);
m_nSerialRecvCnt = 0;
}
}
}
CDialog::OnTimer(nIDEvent);
}
void CTcp2ComDlg::OnBnClickedButtonQuit()
{
// TODO: 在此添加控件通知处理程序代码
OnBnClickedButtonStop( );
CDialog::OnCancel();
}
void CTcp2ComDlg::OnNMDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 在此添加控件通知处理程序代码
DWORD dwPos = ::GetMessagePos();
CPoint point((int)LOWORD(dwPos), (int)HIWORD(dwPos));
m_lcTcpRecv.ScreenToClient(&point);
int nCurSel = m_lcTcpRecv.HitTest(point);
if(-1!=nCurSel)
{
CString tmp;
if(m_bHex1)
{
tmp = m_lcTcpRecv.GetItemText( nCurSel, 1);
}
else
{
tmp = m_lcTcpRecv.GetItemText( nCurSel, 0);
}
GetDlgItem(IDC_EDIT1)->SetWindowText( tmp );
}
*pResult = 0;
}
void CTcp2ComDlg::OnNMDblclkList2(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 在此添加控件通知处理程序代码
DWORD dwPos = ::GetMessagePos();
CPoint point((int)LOWORD(dwPos), (int)HIWORD(dwPos));
m_lcComRecv.ScreenToClient(&point);
int nCurSel = m_lcComRecv.HitTest(point);
if(-1!=nCurSel)
{
CString tmp;
if(m_bHex2)
{
tmp = m_lcComRecv.GetItemText( nCurSel, 1);
}
else
{
tmp = m_lcComRecv.GetItemText( nCurSel, 0);
}
GetDlgItem(IDC_EDIT2)->SetWindowText( tmp );
}
*pResult = 0;
}
void CTcp2ComDlg::OnBnClickedCheck1()
{
// TODO: 在此添加控件通知处理程序代码
CString s;
GetDlgItem(IDC_EDIT1)->GetWindowText(s);
if( m_btnHex1.GetCheck() )
{
GetDlgItem(IDC_EDIT1)->SetWindowText( Byte2HexStr(s, s.GetLength()) );
}
else
{
char buf[CMySocket::MAX_BUF_LEN];
int nLen = HexStr2Byte( s, buf );
if(nLen>0)
{
buf[nLen]=0;
GetDlgItem(IDC_EDIT1)->SetWindowText(buf);
}
}
}
void CTcp2ComDlg::OnBnClickedCheck2()
{
// TODO: 在此添加控件通知处理程序代码
CString s;
GetDlgItem(IDC_EDIT2)->GetWindowText(s);
if( m_btnHex2.GetCheck() )
{
GetDlgItem(IDC_EDIT2)->SetWindowText( Byte2HexStr(s, s.GetLength()) );
}
else
{
char buf[CMySocket::MAX_BUF_LEN];
int nLen = HexStr2Byte( s, buf );
if(nLen>0)
{
buf[nLen]=0;
GetDlgItem(IDC_EDIT2)->SetWindowText(buf);
}
}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -