From 70f6305ec7d25c96ab4cfdd2b7140a891e0e847c Mon Sep 17 00:00:00 2001 From: TAO Cheng Date: Tue, 11 Nov 2014 16:40:22 +0800 Subject: [PATCH] Add Tcpip Server --- .../Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h | 1 + .../Msi/Hsi/SevenOcean/So7_TCPIP_Server.cpp | 529 ++++++++++++++++++ .../Msi/Hsi/SevenOcean/So7_TCPIP_Server.h | 121 ++++ .../Hsi/Tools/UsbUtility/UsbUtil/Mv_Util.rc | 80 ++- .../Tools/UsbUtility/UsbUtil/So7_Option.cpp | 23 +- .../UsbUtil/So7_Util_PLC_TCPIP_SERVER.cpp | 271 +++++++++ .../UsbUtil/So7_Util_PLC_TCPIP_SERVER.h | 40 ++ .../Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj | 6 +- .../UsbUtil/Usb_Util.vcxproj.filters | 12 + .../Hsi/Tools/UsbUtility/UsbUtil/resource.h | 17 +- .../Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo | Bin 150016 -> 159744 bytes 11 files changed, 1076 insertions(+), 24 deletions(-) create mode 100644 PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.cpp create mode 100644 PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.h create mode 100644 PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.cpp create mode 100644 PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.h diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h index 8568674..be66234 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP.h @@ -12,6 +12,7 @@ #include #define WM_SOCKET WM_USER + 0x060 #define WM_TCPIP_RECV_DATA WM_USER + 0x061 +#define WM_TCPIP_MSG WM_USER + 0x062 #define lChannelSize 2 #define CH_SEND 0 diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.cpp b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.cpp new file mode 100644 index 0000000..4f935af --- /dev/null +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.cpp @@ -0,0 +1,529 @@ +#include "StdAfx.h" +#include +#include +#include "So7_TCPIP_Server.h" + +const int WSA_MAJOR_VERSION = 1; +const int WSA_MINOR_VERSION = 1; +#define WSA_VERSION MAKEWORD(WSA_MAJOR_VERSION, WSA_MINOR_VERSION) +#define SOCKADDR_LEN sizeof(SOCKADDR_IN) + +const BYTE CommHeader[]={0x46,0x49,0x4E,0x53}; +const BYTE HandShaking[]={0X46,0X49,0X4E,0X53,0X00,0X00,0X00,0X10,0X00,0X00,0X00,0X01,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,0X00,0X00,0X05}; +const BYTE DRW_SData[]={0X46,0X49,0X4E,0X53,0X00,0X00,0X00,0X18,0X00,0X00,0X00,0X02,0X00,0X00,0X00,0X00,0XC0,0X00,0X02,0X00,0X03,0X00,0X00,0X05,0X00,0XFF,0X01,0X01,0X00,0X00}; + +const int DRW_SDataIndexDataSize=7; +const int DRW_SDataIndexData=30; + +const int DRW_RDataIndexDA1=20; +const int DRW_RDataIndexSA1=23; +const int DRW_RDataIndexCMD1=26; +const int DRW_RDataIndexCMD2=27; +const int DRW_RDataIndexAddr1=29; +const int DRW_RDataIndexAddr2=30; +const int DRW_RDataIndexCh1=32; +const int DRW_RDataIndexCh2=33; +const int DRW_RDataIndexData=34; +const int DRW_RDataCCLen=0x1A; + +const int DRW_RSDataIndexBufSize1=6; +const int DRW_RSDataIndexBufSize2=7; + + + + +struct_so7_tcpip_buff CSo7_TCPIP_Server::m_TCPIPBuf[lChannelSize]; + + +//================================================================ +CSo7_TCPIP_Server::CSo7_TCPIP_Server() +{ + m_hMsgWnd=NULL; + m_Socket=INVALID_SOCKET; + m_SreverIPAddress; + m_iServerPortNumber=static_cast(0); + for (int i=0;ih_addr_list[0],sizeof(in_addr)); + _IPAddress=m_SreverIPAddress; + first = FALSE; + } + _IPAddress=m_SreverIPAddress; + return TCPIP_CONNECT_OK; +} +//================================================================ +BOOL CSo7_TCPIP_Server::CreateAndListen() +{ + if(m_Socket == INVALID_SOCKET) + ::closesocket(m_Socket); + + // 创建套节字 + m_Socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if(m_Socket == INVALID_SOCKET) + return FALSE; + + // 填写要关联的本地地址 + sockaddr_in sin; + sin.sin_family = AF_INET; + sin.sin_port = htons(m_iServerPortNumber); + sin.sin_addr.s_addr = INADDR_ANY; + // 绑定端口 + if(::bind(m_Socket, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR) + { + return FALSE; + } + + // 设置socket为窗口通知消息类型 + ::WSAAsyncSelect(m_Socket, m_hMsgWnd, WM_SOCKET, FD_ACCEPT|FD_CLOSE); + // 进入监听模式 + ::listen(m_Socket, 5); + + return TRUE; +} +//================================================================ +BOOL CSo7_TCPIP_Server::AddClient(SOCKET s) +{ + if(m_nClients < MAX_SOCKET) + { + m_ClientSocket[m_nClients++] = s; + return TRUE; + } + return FALSE; +} +//================================================================ +void CSo7_TCPIP_Server::RemoveClient(SOCKET s) +{ + BOOL bFind = FALSE; + int i(0); + for(i=0; i>8) & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i+1]=iData & 0x0ff; + } + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDataSize]=static_cast(DRW_SDataIndexData+2*_datasize); + + SendBuffer(); + + return TRUE; +} +//================================================================ +BOOL CSo7_TCPIP_Server::Response_Sensor_State(short _datasize) +{ + if(m_ClientSocket[m_nActiveClient] == INVALID_SOCKET) + { + return FALSE; + } + m_ClearSendBuf(); + memcpy(m_TCPIPBuf[CH_SEND]._buffer,DRW_SData,sizeof(DRW_SData)); + + for (int i=0;i<_datasize;i++) + { + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+i]=m_TCPIPServerState._PLCSensorState[i]; + } + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDataSize]=static_cast(DRW_SDataIndexData+2*_datasize); + SendBuffer(); + return TRUE; + +} +//================================================================ +BOOL CSo7_TCPIP_Server::Response_CCD_DATA(short _Addr,short _datasize) +{ + if(m_ClientSocket[m_nActiveClient] == INVALID_SOCKET) + { + return FALSE; + } + m_ClearSendBuf(); + memcpy(m_TCPIPBuf[CH_SEND]._buffer,DRW_SData,sizeof(DRW_SData)); + + int iData(0); + for (int i=_Addr;i<_Addr+_datasize;i++) + { + iData=m_CCDData[i]; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i]=(iData>>8) & 0x0ff; + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexData+2*i+1]=iData & 0x0ff; + } + m_TCPIPBuf[CH_SEND]._buffer[DRW_SDataIndexDataSize]=static_cast(DRW_SDataIndexData+2*_datasize); + + SendBuffer(); + + return TRUE; +} +//================================================================ +BOOL CSo7_TCPIP_Server::_Send_Cmd_Write_State() +{ + if(m_ClientSocket[m_nActiveClient] == INVALID_SOCKET) + { + return FALSE; + } + m_ClearSendBuf(); + + SendBuffer(); + + return TRUE; +} +//================================================================ +LRESULT CSo7_TCPIP_Server::OnSocket(WPARAM wParam, LPARAM lParam) +{ + // 取得有事件发生的套节字句柄 + SOCKET s = wParam; + // 查看是否出错 + + int errorCode = WSAGETSELECTERROR(lParam); + if(errorCode) + { + RemoveClient(s); + ::closesocket(s); + return errorCode; + } + int event = WSAGETSELECTEVENT(lParam); + switch(event) + { + case FD_ACCEPT: + { + if(m_nClients < MAX_SOCKET) + { + SOCKET client = ::accept(s, NULL, NULL); + ::WSAAsyncSelect(client,m_hMsgWnd, WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE); + AddClient(client); + } + else + { + AfxMessageBox(_T("连接客户太多!")); + }; + ::PostMessage(m_hMsgWnd,WM_TCPIP_MSG,FD_ACCEPT,0); + } + break; + case FD_READ: + { + UpdateActiveClient(s); + + m_ProcessSocketReadEvent(s); + } + break; + case FD_WRITE: + //This event happens when the tcp buffers are ready for another send. + //So if there is not enough room for the first write the event will happen + //and then the buffers are ready for more. + m_ProcessSocketWriteEvent(); + ::PostMessage(m_hMsgWnd,WM_TCPIP_MSG,FD_WRITE,0); + break; + case FD_CLOSE: + { + RemoveClient(s); + ::closesocket(s); + ::PostMessage(m_hMsgWnd,WM_TCPIP_MSG,FD_CLOSE,0); + } + break; + } + return 0; +} +//================================================================ +void CSo7_TCPIP_Server::m_ClearSendBuf(void) +{ + int i; + for(i=0;i=m_TCPIPBuf[CH_SEND]._size) + { + m_TCPIPBuf[CH_SEND]._size = 0; + m_TCPIPBuf[CH_SEND]._CompletedSize = 0; + m_TCPIPBuf[CH_SEND]._hProtoPending=FALSE; + break; + } + } +} + +//================================================================ +void CSo7_TCPIP_Server::m_ProcessSocketWriteEvent(void) +{ + int errorCode, numBytesSent; + SOCKET s = m_Socket; + if(m_TCPIPBuf[CH_SEND]._size <= 0) + return; + char* sendBuf = m_TCPIPBuf[CH_SEND]._buffer; + + while(1) + { + numBytesSent = send(s, &(sendBuf[m_TCPIPBuf[CH_SEND]._CompletedSize]), m_TCPIPBuf[CH_SEND]._size-m_TCPIPBuf[CH_SEND]._CompletedSize, 0); + if(numBytesSent == SOCKET_ERROR) + { + errorCode = WSAGetLastError(); + if(errorCode == WSAEWOULDBLOCK) + { + return; //Should get a FD_WRITE event if this happens. Send the rest from there. + } + else + { + //showSocketError(errorCode); + return; + } + } + else + { + m_TCPIPBuf[CH_SEND]._CompletedSize += numBytesSent; + } + if(m_TCPIPBuf[CH_SEND]._CompletedSize>=m_TCPIPBuf[CH_SEND]._size) + { + m_TCPIPBuf[CH_SEND]._CompletedSize = 0; + m_ClearSendBuf(); + break; + } + } +} +//================================================================ +void CSo7_TCPIP_Server::m_ProcessSocketReadEvent(SOCKET s) +{ + int bytesReceived=0; + int errorCode; + + bytesReceived = recv(s, &(m_TCPIPBuf[CH_RECV]._buffer[0]), TCPIP_MAX_BUFF_SIZE, 0); + if(bytesReceived == SOCKET_ERROR) + { + errorCode = WSAGetLastError(); + if (errorCode == WSAEWOULDBLOCK) + { + //have to wait for the next receive event + return; + } + else + { + //showSocketError(errorCode); + return; + } + } + m_TCPIPBuf[CH_RECV]._CompletedSize += bytesReceived; + m_TCPIPBuf[CH_RECV]._size = m_TCPIPBuf[CH_RECV]._CompletedSize; + if (strstr(m_TCPIPBuf[CH_RECV]._buffer, "FINS")) + { + if (m_TCPIPBuf[CH_RECV]._buffer[7]==0x0C)//handshake + { + Response_Handshake(); + } + else if (m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexCMD1]==0x01 + &&m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexCMD2]==0x01) + { + short iAddr=(m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexAddr1]<<8)+m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexAddr2]; + short iDataSize=(m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexCh1]<<8)+m_TCPIPBuf[CH_RECV]._buffer[DRW_RDataIndexCh2]; + if (iAddr>=20000) + { + ;//errcode + } + else if (iAddr>=10000) + { + Response_CCD_DATA((iAddr-10060),iDataSize);//ccd data + } + else if (iAddr>=8000) + { + Response_PLC_State(1);//WRITE PLC STATE + } + else if (iAddr>=5000) + { + ;//READ PLC STATE + + } + else + { + ; + } + } + } + + m_TCPIPBuf[CH_RECV]._CompletedSize = 0; + m_TCPIPBuf[CH_RECV]._hProtoPending=FALSE; + ::PostMessage(m_hMsgWnd,WM_TCPIP_MSG,FD_READ,0); +} diff --git a/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.h b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.h new file mode 100644 index 0000000..9d8293e --- /dev/null +++ b/PcDmis/Base/Interfac/Msi/Hsi/SevenOcean/So7_TCPIP_Server.h @@ -0,0 +1,121 @@ +////////////////////////////////////////////////////////////////////// +#ifndef SO7_TCPIP_SERVER_H_INCLUDED_ +#define SO7_TCPIP_SERVER_H_INCLUDED_ + + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include +#include +#include +#include "So7_TCPIP.h" + +#define MAX_SOCKET 56 +#define PLC_MAX_SENSOR_STATE 20 +#define MAX_CCD_ADDR 120 + +enum OMRON_PLC_SENSOR +{ + OMRON_PLC_CCD1_CAMERA1=0, + OMRON_PLC_CCD1_CAMERA2, + OMRON_PLC_CCD2_CAMERA1, + OMRON_PLC_CCD2_CAMERA2, + OMRON_PLC_CCD3_CAMERA1, + OMRON_PLC_CCD3_CAMERA2, + OMRON_PLC_CCD4_CAMERA1, + OMRON_PLC_CCD4_CAMERA2, + OMRON_PLC_CCD5_CAMERA1, + OMRON_PLC_CCD5_CAMERA2, + OMRON_PLC_LASER1_HEADA, + OMRON_PLC_LASER1_HEADB, + OMRON_PLC_LASER2_HEADA, + OMRON_PLC_LASER2_HEADB, + OMRON_PLC_LASER3_HEADA, + OMRON_PLC_LASER3_HEADB, + OMRON_PLC_LASER4_HEADA, + OMRON_PLC_LASER4_HEADB, + OMRON_PLC_LASER5_HEADA, + OMRON_PLC_LASER5_HEADB, + OMRON_PLC_SENSOR_TOTAL=PLC_MAX_SENSOR_STATE +}; +struct s_tcpip_state +{ + TCPIP_RETURN_CODE _SendReturnCode; + TCPIP_RETURN_CODE _RecvReturnCode; + bool _ConnectionSuccessful; + bool _HandshakeSuccessful; + bool _WriteDataCompleted; + bool _ReadDataCompleted; + int _PLCRunningState; + BYTE _PLCSensorState[10]; + bool _PLCSensorTrigged[10]; + int _PCState; + int _PCMeasureResult; + s_tcpip_state() + { + _SendReturnCode=TCPIP_CONNECT_OK; + _RecvReturnCode=TCPIP_CONNECT_OK; + _ConnectionSuccessful=false; + _HandshakeSuccessful=false; + _WriteDataCompleted=true; + _ReadDataCompleted=true; + _PLCRunningState=0; + for(int i=0;iSetCheck(FALSE); ((CButton *)GetDlgItem(IDC_RADIO_TEST_IMAGE_DLL))->SetCheck(FALSE); ((CButton *)GetDlgItem(IDC_RADIO_ART_PCI8622))->SetCheck(FALSE); - ((CButton *)GetDlgItem(IDC_RADIO_SO7_OMRON_PLC))->SetCheck(TRUE); + ((CButton *)GetDlgItem(IDC_RADIO_SO7_OMRON_PLC))->SetCheck(FALSE); + ((CButton *)GetDlgItem(IDC_RADIO_SO7_OMRON_PLC_SERVER))->SetCheck(TRUE); #ifdef _RELEASE_SO7_CONTROLER_ONLY ((CButton *)GetDlgItem(IDC_RADIO_VIDEOCARD_SDK3000))->EnableWindow(FALSE); @@ -449,6 +455,21 @@ void CSo7_Option::OnBnClickedOk() g_pSo7_TCPIP=NULL; } } + else if(((CButton *)GetDlgItem(IDC_RADIO_SO7_OMRON_PLC_SERVER))->GetCheck()) + { + if (!g_pSo7_TCPIP_Server) + { + g_pSo7_TCPIP_Server=new CSo7_TCPIP_Server(); + } + CSo7_Util_PLC_TCPIP_SERVER* pSo7_Util_PLC_TCPIP_SERVER=new CSo7_Util_PLC_TCPIP_SERVER(); + pSo7_Util_PLC_TCPIP_SERVER->DoModal(); + delete pSo7_Util_PLC_TCPIP_SERVER; + if (g_pSo7_TCPIP_Server) + { + delete g_pSo7_TCPIP_Server; + g_pSo7_TCPIP=NULL; + } + } else if(((CButton *)GetDlgItem(IDC_RADIO_SO7_VERIFICATION_ALGORITHM))->GetCheck()) { CSO7_Verfication_Algorithm* pSO7_Verfication_Algorithm=new CSO7_Verfication_Algorithm(); diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.cpp b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.cpp new file mode 100644 index 0000000..de80d2e --- /dev/null +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.cpp @@ -0,0 +1,271 @@ +// So7_Util_PLC_TCPIP_SERVER.cpp : implementation file +// + +#include "stdafx.h" +#include "resource.h" +#include "EditableListCtrl.h" +#include "..\..\..\SevenOcean\So7_TCPIP_Server.h" +#include "So7_Util_PLC_TCPIP_SERVER.h" +#include "afxdialogex.h" + +enum E_UPDATE_LIST_CONTROL_TYPE +{ + E_LISTCTRL_TITLE, + E_LISTCTRL_CONTENT, + E_LISTCTRL_TOTAL +}; + +extern CSo7_TCPIP_Server* g_pSo7_TCPIP_Server; + +// CSo7_Util_PLC_TCPIP_SERVER dialog + +IMPLEMENT_DYNAMIC(CSo7_Util_PLC_TCPIP_SERVER, CDialog) + +CSo7_Util_PLC_TCPIP_SERVER::CSo7_Util_PLC_TCPIP_SERVER(CWnd* pParent /*=NULL*/) + : CDialog(CSo7_Util_PLC_TCPIP_SERVER::IDD, pParent) +{ + +} + +CSo7_Util_PLC_TCPIP_SERVER::~CSo7_Util_PLC_TCPIP_SERVER() +{ +} + +void CSo7_Util_PLC_TCPIP_SERVER::DoDataExchange(CDataExchange* pDX) +{ + DDX_Control(pDX, IDC_LIST_PLC_TCPIP_SERVER_CCDDATA, m_DataList); + CDialog::DoDataExchange(pDX); +} + + +BEGIN_MESSAGE_MAP(CSo7_Util_PLC_TCPIP_SERVER, CDialog) + ON_BN_CLICKED(IDC_BUTTON_PLC_TCPIP_SERVER_START, &CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedButtonPlcTcpipServerStart) + ON_BN_CLICKED(IDC_BUTTON_PLC_TCPIP_SERVER_STOP, &CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedButtonPlcTcpipServerStop) + ON_BN_CLICKED(IDC_BUTTON_PLC_TCPIP_SERVER_UPDATESTATE, &CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedButtonPlcTcpipServerUpdatestate) + ON_BN_CLICKED(IDC_BUTTON_CLEAR_MSG, &CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedButtonClearMsg) + ON_BN_CLICKED(IDCANCEL, &CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedCancel) + ON_MESSAGE(WM_SOCKET,&CSo7_Util_PLC_TCPIP_SERVER::OnSocket) + ON_MESSAGE(WM_TCPIP_MSG,&CSo7_Util_PLC_TCPIP_SERVER::OnTCPIPMsg) + ON_BN_CLICKED(IDC_BUTTON_PLC_TCPIP_SERVER_UPDATEDATA, &CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedButtonPlcTcpipServerUpdatedata) +END_MESSAGE_MAP() + + +// CSo7_Util_PLC_TCPIP_SERVER message handlers + +BOOL CSo7_Util_PLC_TCPIP_SERVER::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) + { + BOOL bNameValid; + CString strAboutMenu; + bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); + ASSERT(bNameValid); + if (!strAboutMenu.IsEmpty()) + { + pSysMenu->AppendMenu(MF_SEPARATOR); + pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); + } + } + + CString str; + str.Format(_T("%d"),g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCSensorState[OMRON_PLC_CCD1_CAMERA1]); + GetDlgItem(IDC_EDIT_PLC_TCPIP_SERVER_STATE_CCD1)->SetWindowTextW(str); + str.Format(_T("%d"),g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCSensorState[OMRON_PLC_CCD1_CAMERA2]); + GetDlgItem(IDC_EDIT_PLC_TCPIP_SERVER_STATE_CCD2)->SetWindowTextW(str); + str.Format(_T("%d"),g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCSensorState[IDC_EDIT_PLC_TCPIP_SERVER_STATE_LASER1]); + GetDlgItem(IDC_EDIT_PLC_TCPIP_SERVER_STATE_LASER1)->SetWindowTextW(str); + str.Format(_T("%d"),g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCSensorState[OMRON_PLC_CCD1_CAMERA1]); + GetDlgItem(IDC_EDIT_PLC_TCPIP_SERVER_STATE_LASER2)->SetWindowTextW(str); + str.Format(_T("%d"),g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCRunningState); + GetDlgItem(IDC_EDIT_PLC_TCPIP_SERVER_PLC_STATE)->SetWindowTextW(str); + + UpdateData(FALSE); + + return TRUE; // return TRUE unless you set the focus to a control +} + + +void CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedButtonPlcTcpipServerStart() +{ + ;// TODO: Add your control notification handler code here +} + + +void CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedButtonPlcTcpipServerStop() +{ + ;// TODO: Add your control notification handler code here +} + + +void CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedButtonPlcTcpipServerUpdatestate() +{ + CString str; + UpdateData(TRUE); + USES_CONVERSION; + GetDlgItem(IDC_EDIT_PLC_TCPIP_SERVER_STATE_CCD1)->GetWindowText(str); + const char* cTempValue=T2A(str); + g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCSensorState[OMRON_PLC_CCD1_CAMERA1]=static_cast(atoi(cTempValue)); + + GetDlgItem(IDC_EDIT_PLC_TCPIP_SERVER_STATE_CCD2)->GetWindowText(str); + cTempValue=T2A(str); + g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCSensorState[OMRON_PLC_CCD1_CAMERA2]=static_cast(atoi(cTempValue)); + + GetDlgItem(IDC_EDIT_PLC_TCPIP_SERVER_STATE_LASER1)->GetWindowText(str); + cTempValue=T2A(str); + g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCSensorState[OMRON_PLC_LASER1_HEADA]=static_cast(atoi(cTempValue)); + + GetDlgItem(IDC_EDIT_PLC_TCPIP_SERVER_STATE_LASER2)->GetWindowText(str); + cTempValue=T2A(str); + g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCSensorState[OMRON_PLC_LASER2_HEADA]=static_cast(atoi(cTempValue)); + + GetDlgItem(IDC_EDIT_PLC_TCPIP_SERVER_PLC_STATE)->GetWindowText(str); + cTempValue=T2A(str); + g_pSo7_TCPIP_Server->m_TCPIPServerState._PLCRunningState=static_cast(atoi(cTempValue)); + +} + + +void CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedButtonPlcTcpipServerUpdatedata() +{ + m_UpdateListControl(E_LISTCTRL_CONTENT); +} + +//===================================================================== +void CSo7_Util_PLC_TCPIP_SERVER::m_UpdateListControl(int _type) +{ + switch(_type) + { + case E_LISTCTRL_TITLE: + { + RECT m_rect; + m_DataList.GetClientRect(&m_rect); //获取list的客户区 + m_DataList.SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT); //设置list风格 + + m_DataList.InsertColumn(0,_T("CCD地址"),LVCFMT_LEFT, m_rect.right*1/2); + m_DataList.InsertColumn(1,_T("数据值"),LVCFMT_LEFT, m_rect.right*1/2); + + int iStartRow(0),iEndRow(0); + CString str; + + iStartRow=0; + iEndRow=MAX_CCD_ADDR; + for (int i=iStartRow; im_CCDData[iRow]=atoi(cTmp); + } + } + break; + } + default:break; + } +} +void CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedButtonClearMsg() +{ + ((CEdit *)GetDlgItem(IDC_EDIT_MSG))->SetWindowTextW(_T("")); +} + + +//===================================================================================== +void CSo7_Util_PLC_TCPIP_SERVER::OnBnClickedCancel() +{ + // TODO: Add your control notification handler code here + CDialog::OnCancel(); +} +//===================================================================================== +//Print message on edit control +void CSo7_Util_PLC_TCPIP_SERVER::OutputWithScroll(const CString &strNewText,CEdit &edtOutput) +{ + CString strOutput; + edtOutput.GetWindowText(strOutput); + strOutput += strNewText; + if ("\r\n" != strOutput.Right(2)) + { + strOutput += "\r\n"; + } + + int iCount = strOutput.GetLength(); + + edtOutput.SetRedraw(FALSE); + edtOutput.SetWindowText(strOutput); + int iLine = edtOutput.GetLineCount(); + edtOutput.LineScroll(iLine, 0); + edtOutput.SetSel(iCount, iCount); + edtOutput.SetRedraw(TRUE); +} +//===================================================================================== +LRESULT CSo7_Util_PLC_TCPIP_SERVER::OnSocket(WPARAM w, LPARAM p) +{ + LRESULT lResult=0; + if( g_pSo7_TCPIP_Server ) + lResult = g_pSo7_TCPIP_Server->OnSocket(w,p); + + return( lResult ); +} +//===================================================================================== +LRESULT CSo7_Util_PLC_TCPIP_SERVER::OnTCPIPMsg(WPARAM w, LPARAM p) +{ + UNREFERENCED_PARAMETER(p); + LRESULT lResult=0; + switch(w) + { + case FD_ACCEPT: + { + m_csMSG=_T("FD_ACCEPT"); + break; + } + case FD_READ: + { + m_csMSG=_T("FD_READ"); + break; + } + case FD_WRITE: + { + m_csMSG=_T("FD_WRITE"); + break; + } + case FD_CLOSE: + { + m_csMSG=_T("FD_CLOSE"); + break; + } + default: + { + m_csMSG=_T("[Unknown]"); + break; + } + } + m_csMSG+=_T("."); + OutputWithScroll(m_csMSG,m_edMSG); + return( lResult ); +} + diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.h b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.h new file mode 100644 index 0000000..10204ad --- /dev/null +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/So7_Util_PLC_TCPIP_SERVER.h @@ -0,0 +1,40 @@ +#pragma once + + +// CSo7_Util_PLC_TCPIP_SERVER dialog + +class CSo7_Util_PLC_TCPIP_SERVER : public CDialog +{ + DECLARE_DYNAMIC(CSo7_Util_PLC_TCPIP_SERVER) + +public: + CSo7_Util_PLC_TCPIP_SERVER(CWnd* pParent = NULL); // standard constructor + virtual ~CSo7_Util_PLC_TCPIP_SERVER(); + +// Dialog Data + enum { IDD = IDD_SO7_UTIL_PLC_TCPIP_SERVER }; + +protected: + CString m_csMSG; + CEdit m_edMSG; + CEditableListCtrl m_DataList; + + void OutputWithScroll(const CString &strNewText,CEdit &edtOutput); + + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL OnInitDialog(); + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnBnClickedButtonPlcTcpipServerStart(); + afx_msg void OnBnClickedButtonPlcTcpipServerStop(); + afx_msg void OnBnClickedButtonPlcTcpipServerUpdatestate(); + afx_msg void OnBnClickedButtonClearMsg(); + afx_msg void OnBnClickedCancel(); + + + LRESULT OnSocket(WPARAM w, LPARAM p); + LRESULT OnTCPIPMsg(WPARAM w, LPARAM p); + afx_msg void OnBnClickedButtonPlcTcpipServerUpdatedata(); + void m_UpdateListControl(int _type); + +}; diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj index 36eff43..e7cc54e 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj @@ -218,7 +218,7 @@ MaxSpeed true - WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;_RELEASE_SO7_CONTROLER_ONLY;%(PreprocessorDefinitions) + WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;_RELEASE_SO7_CONTROLER_ONLY;_REMOVE_DLLCHR;%(PreprocessorDefinitions) false MultiThreaded true @@ -324,6 +324,7 @@ + @@ -368,6 +369,7 @@ + @@ -417,6 +419,7 @@ + @@ -461,6 +464,7 @@ + diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj.filters b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj.filters index 9e9fbbb..d0f813b 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj.filters +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/Usb_Util.vcxproj.filters @@ -229,6 +229,12 @@ Sources Files + + Sources Files + + + Sources Files + @@ -492,6 +498,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h index 1d29563..ad71e99 100644 --- a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h +++ b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil/resource.h @@ -756,6 +756,8 @@ #define IDC_RADIO_TC4000_CHANNEL2 1605 #define IDC_RADIO_SO7_OMRON_PLC 1605 #define IDC_RADIO_TC4000_CHANNEL3 1606 +#define IDC_RADIO_SO7_OMRON_PLC2 1606 +#define IDC_RADIO_SO7_OMRON_PLC_SERVER 1606 #define IDC_RADIO_TC4000_CHANNEL4 1607 #define IDC_RADIO_SV2000E_CHANNEL1 1608 #define IDC_RADIO_SV2000E_CHANNEL2 1609 @@ -876,6 +878,7 @@ #define IDD_DIALOG_STIL_CCS_PRIMA 1722 #define IDD_SO7_VIDEOCARD_MV900 1723 #define IDD_SO7_UTIL_PLC_TCPIP 1724 +#define IDD_SO7_UTIL_PLC_TCPIP_SERVER 1725 #define IDC_RADIO_SPEED_SLOW 1770 #define IDC_RADIO_SCALE 1772 #define IDC_EDIT_SPEED_X 1773 @@ -1055,8 +1058,20 @@ #define IDC_EDIT_MSG 1888 #define IDC_EDIT_PLC_TCPIP_Data 1889 #define IDC_BUTTON_PLC_TCPIP_HANDSHAKING 1890 +#define IDC_EDIT_PLC_TCPIP_SERVER_STATE_LASER1 1890 #define IDC_EDIT_PLC_TCPIP_ADDR2 1891 #define IDC_EDIT_PLC_TCPIP_DATA_SIZE 1891 +#define IDC_EDIT_PLC_TCPIP_SERVER_STATE_CCD1 1892 +#define IDC_EDIT_PLC_TCPIP_SERVER_STATE_LASER2 1893 +#define IDC_EDIT_PLC_TCPIP_SERVER_STATE_CCD2 1894 +#define IDC_BUTTON_PLC_TCPIP_SERVER_START 1895 +#define IDC_BUTTON_PLC_TCPIP_SERVER_STOP 1896 +#define IDC_BUTTON_PLC_TCPIP_SERVER_UPDATESTATE 1897 +#define IDC_BUTTON_CLEAR_MSG 1898 +#define IDC_EDIT_PLC_TCPIP_SERVER_PLC_STATE 1899 +#define IDC_BUTTON_PLC_TCPIP_SERVER_UPDATESTATE2 1900 +#define IDC_BUTTON_PLC_TCPIP_SERVER_UPDATEDATA 1900 +#define IDC_LIST_PLC_TCPIP_SERVER_CCDDATA 1902 #define IDC_BUTTON_DIY_EXIT_BUTTON 32740 #define ID_EDIT_SO7_CONFIG_MOTION 32741 @@ -1066,7 +1081,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 193 #define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 1889 +#define _APS_NEXT_CONTROL_VALUE 1903 #define _APS_NEXT_SYMED_VALUE 104 #endif #endif diff --git a/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo b/PcDmis/Base/Interfac/Msi/Hsi/Tools/UsbUtility/UsbUtil_VS2010.suo index 30ac501d851b6b98d69813af9b44ee3a2b551210..7697f6c7b8fcddd663a6b13d0e92f1c89c24900b 100644 GIT binary patch delta 9527 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 delta 5822 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