--- /dev/null
+///////////////////////////////////////\r
+// ClientDialog.cpp\r
+\r
+#include "stdafx.h"\r
+#include "ClientDialog.h"\r
+#include "resource.h"\r
+\r
+\r
+// Definitions for the CMyDialog class\r
+CClientDialog::CClientDialog(UINT nResID, CWnd* pParent) :\r
+ CDialog(nResID, pParent), m_bClientConnected(FALSE), m_SocketType(SOCK_STREAM)\r
+{\r
+ // Add support for the IP Address control\r
+ // It requires Win95 with IE4 intergrated or a later version of Windows OS.\r
+ LoadCommonControlsEx();\r
+}\r
+\r
+CClientDialog::~CClientDialog()\r
+{\r
+}\r
+\r
+void CClientDialog::Append(int nID, LPCTSTR buf)\r
+{\r
+ // This function appends text to an edit control\r
+\r
+ // Append Line Feed\r
+ int ndx = (int)SendDlgItemMessage(nID, WM_GETTEXTLENGTH, 0, 0);\r
+ if (ndx)\r
+ {\r
+ SendDlgItemMessage(nID, EM_SETSEL, (WPARAM)ndx, (LPARAM)ndx);\r
+ SendDlgItemMessage(nID, EM_REPLACESEL, 0, (LPARAM) (_T("\r\n")));\r
+ }\r
+\r
+ // Append text\r
+ ndx = (int)SendDlgItemMessage(nID, WM_GETTEXTLENGTH, 0, 0);\r
+ SendDlgItemMessage(nID, EM_SETSEL, (WPARAM)ndx, (LPARAM)ndx);\r
+ SendDlgItemMessage(nID, EM_REPLACESEL, 0, (LPARAM) buf);\r
+}\r
+\r
+INT_PTR CClientDialog::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
+{\r
+ switch (uMsg)\r
+ {\r
+ case USER_CONNECT:\r
+ OnClientConnect();\r
+ break;\r
+ case USER_DISCONNECT:\r
+ OnClientDisconnect();\r
+ break;\r
+ case USER_RECEIVE:\r
+ OnClientReceive();\r
+ break;\r
+ case WM_ACTIVATE:\r
+ // Give focus to the Send Edit box\r
+ SendMessage(WM_NEXTDLGCTL, (WPARAM)(HWND)m_EditSend, TRUE);\r
+ break;\r
+ case WM_DESTROY:\r
+ PostQuitMessage(0);\r
+ break;\r
+ }\r
+\r
+ // Pass unhandled messages on to parent DialogProc\r
+ return DialogProcDefault(uMsg, wParam, lParam);\r
+}\r
+\r
+void CClientDialog::OnClientDisconnect()\r
+{\r
+ // Called when the socket is disconnected from the server\r
+ m_bClientConnected = FALSE;\r
+ m_ButtonConnect.EnableWindow( TRUE );\r
+\r
+ // Update the dialog\r
+ m_EditStatus.SetWindowText( _T("Disconnected from server") );\r
+ m_ButtonSend.EnableWindow( FALSE );\r
+ m_EditSend.EnableWindow( FALSE );\r
+ m_EditPort.EnableWindow( TRUE );\r
+ m_IP4Address.EnableWindow( TRUE );\r
+ m_RadioTCP.EnableWindow( TRUE );\r
+ m_RadioUDP.EnableWindow( TRUE );\r
+ m_RadioIP4.EnableWindow( TRUE );\r
+ m_ButtonConnect.SetWindowText( _T("Connect") );\r
+ if ( m_Client.IsIPV6Supported() )\r
+ {\r
+ m_EditIP6Address.EnableWindow( TRUE );\r
+ m_RadioIP6.EnableWindow( TRUE );\r
+ }\r
+}\r
+\r
+void CClientDialog::LoadCommonControlsEx()\r
+{\r
+ // This function adds support for the IP address control in the dialog.\r
+ HMODULE hComCtl;\r
+\r
+ try\r
+ {\r
+ // Load the Common Controls DLL\r
+ hComCtl = ::LoadLibrary(_T("COMCTL32.DLL"));\r
+ if (!hComCtl)\r
+ throw CWinException(_T("Failed to load COMCTL32.DLL"));\r
+\r
+ if (GetComCtlVersion() > 470)\r
+ {\r
+ // Declare a pointer to the InItCommonControlsEx function\r
+ typedef BOOL WINAPI INIT_EX(INITCOMMONCONTROLSEX*);\r
+ INIT_EX* pfnInit = (INIT_EX*)::GetProcAddress(hComCtl, "InitCommonControlsEx");\r
+\r
+ // Call InitCommonControlsEx\r
+ INITCOMMONCONTROLSEX InitStruct;\r
+ InitStruct.dwSize = sizeof(INITCOMMONCONTROLSEX);\r
+ InitStruct.dwICC = ICC_INTERNET_CLASSES;\r
+ if((!(*pfnInit)(&InitStruct)))\r
+ throw CWinException(_T("InitCommonControlsEx failed"));\r
+ }\r
+ else\r
+ {\r
+ ::MessageBox(NULL, _T("IP Address Control not supported!"), _T("Error"), MB_OK);\r
+ }\r
+\r
+ ::FreeLibrary(hComCtl);\r
+ }\r
+\r
+ catch (const CWinException &e)\r
+ {\r
+ e.what();\r
+ if (hComCtl)\r
+ ::FreeLibrary(hComCtl);\r
+ }\r
+}\r
+\r
+\r
+void CClientDialog::OnClientConnect()\r
+{\r
+ // Called when the connection to the server is established\r
+ m_bClientConnected = TRUE;\r
+ m_ButtonConnect.EnableWindow( TRUE );\r
+\r
+ // Move focus to the Send Edit box\r
+ SendMessage(WM_NEXTDLGCTL, (WPARAM)(HWND)m_EditSend, TRUE);\r
+ SetForegroundWindow();\r
+\r
+ // Update the dialog\r
+ m_IP4Address.EnableWindow( FALSE );\r
+ m_EditIP6Address.EnableWindow( FALSE );\r
+ m_ButtonSend.EnableWindow( TRUE );\r
+ m_EditSend.EnableWindow( TRUE );\r
+ m_EditPort.EnableWindow( FALSE );\r
+ m_RadioIP4.EnableWindow( FALSE );\r
+ m_RadioIP6.EnableWindow( FALSE );\r
+ m_RadioTCP.EnableWindow( FALSE );\r
+ m_RadioUDP.EnableWindow( FALSE );\r
+ m_EditStatus.SetWindowText( _T("Connected to server") );\r
+ m_ButtonConnect.SetWindowText( _T("Disconnect") );\r
+}\r
+\r
+int CClientDialog::OnClientReceive()\r
+{\r
+ // Called when the socket has data to receive\r
+ std::vector<TCHAR> vTChar( 1025, _T('\0') );\r
+ TCHAR* buf = &vTChar.front(); // TChar array with 1025 elements initialised to _T('\0')\r
+ int size = m_Client.Receive( buf, 1024, 0 ); // receive at most 1024 chars\r
+ if (SOCKET_ERROR == size)\r
+ {\r
+ Append( IDC_EDIT_STATUS, _T("Receive failed.") );\r
+ return size;\r
+ }\r
+\r
+ Append( IDC_EDIT_RECEIVE, buf );\r
+ return size;\r
+}\r
+\r
+BOOL CClientDialog::OnCommand(WPARAM wParam, LPARAM lParam)\r
+{\r
+ // Respond to the dialog buttons\r
+\r
+ UNREFERENCED_PARAMETER(lParam);\r
+\r
+ switch (LOWORD(wParam))\r
+ {\r
+ case IDC_BUTTON_CONNECT:\r
+ OnStartClient();\r
+ return TRUE;\r
+ case IDC_BUTTON_SEND:\r
+ OnSend();\r
+ // Give keyboard focus to the Send edit box\r
+ SendMessage( WM_NEXTDLGCTL, (WPARAM)(HWND)m_EditSend, TRUE);\r
+ return TRUE;\r
+ } //switch (LOWORD(wParam))\r
+\r
+ return FALSE;\r
+}\r
+\r
+BOOL CClientDialog::OnInitDialog()\r
+{\r
+ // Set the Icon\r
+ SetIconLarge(IDW_MAIN);\r
+ SetIconSmall(IDW_MAIN);\r
+\r
+ // reposition dialog\r
+ CRect rc = GetWindowRect();\r
+ MoveWindow( rc.left+14, rc.top+14, rc.Width(), rc.Height(), TRUE);\r
+\r
+ // Attach CWnd objects to the dialog's children\r
+ m_IP4Address.AttachDlgItem( IDC_IPADDRESS, this );\r
+ m_EditIP6Address.AttachDlgItem( IDC_EDIT_IPV6ADDRESS, this );\r
+ m_EditStatus.AttachDlgItem( IDC_EDIT_STATUS, this );\r
+ m_EditPort.AttachDlgItem( IDC_EDIT_PORT, this );\r
+ m_EditSend.AttachDlgItem( IDC_EDIT_SEND, this );\r
+ m_EditReceive.AttachDlgItem( IDC_EDIT_RECEIVE, this );\r
+ m_ButtonConnect.AttachDlgItem( IDC_BUTTON_CONNECT, this );\r
+ m_ButtonSend.AttachDlgItem( IDC_BUTTON_SEND, this );\r
+ m_RadioIP4.AttachDlgItem( IDC_RADIO_IPV4, this );\r
+ m_RadioIP6.AttachDlgItem( IDC_RADIO_IPV6, this );\r
+ m_RadioTCP.AttachDlgItem( IDC_RADIO_TCP, this );\r
+ m_RadioUDP.AttachDlgItem( IDC_RADIO_UDP, this );\r
+\r
+ // Set the initial state of the dialog\r
+ m_EditIP6Address.SetWindowText( _T("0000:0000:0000:0000:0000:0000:0000:0001") );\r
+ m_RadioIP4.SendMessage( BM_SETCHECK, BST_CHECKED, 0 );\r
+ m_EditStatus.SetWindowText( _T("Not Connected") );\r
+ m_EditPort.SetWindowText( _T("3000") );\r
+ m_RadioTCP.SendMessage( BM_SETCHECK, BST_CHECKED, 0 );\r
+ m_IP4Address.SendMessage( IPM_SETADDRESS, 0, MAKEIPADDRESS(127, 0, 0, 1) );\r
+\r
+ if (!m_Client.IsIPV6Supported())\r
+ {\r
+ m_RadioIP6.EnableWindow(FALSE);\r
+ m_EditIP6Address.EnableWindow(FALSE);\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+void CClientDialog::OnStartClient()\r
+{\r
+ TRACE(_T("Connect/Disconnect Button Pressed\n"));\r
+\r
+ LRESULT lr = m_RadioTCP.SendMessage( BM_GETCHECK, 0, 0 );\r
+ m_SocketType = (lr == BST_CHECKED)? SOCK_STREAM : SOCK_DGRAM ;\r
+\r
+ lr = m_RadioIP4.SendMessage( BM_GETCHECK, 0, 0 );\r
+ int IPfamily = (lr == BST_CHECKED)? PF_INET : PF_INET6 ;\r
+\r
+ if (!m_bClientConnected)\r
+ {\r
+ switch(m_SocketType)\r
+ {\r
+ case SOCK_STREAM:\r
+ {\r
+ // Create the socket\r
+\r
+ if (!m_Client.Create(IPfamily, SOCK_STREAM))\r
+ {\r
+ Append(IDC_EDIT_STATUS, m_Client.GetLastError());\r
+ MessageBox( _T("Failed to create Client socket"), _T("Connect Failed"), MB_ICONWARNING );\r
+ return;\r
+ }\r
+\r
+ // Retrieve the IP Address\r
+ CString strAddr;\r
+ if (PF_INET6 == IPfamily)\r
+ {\r
+ strAddr = m_EditIP6Address.GetWindowText();\r
+ }\r
+ else\r
+ {\r
+ DWORD dwAddr = 0;\r
+ m_IP4Address.SendMessage( IPM_GETADDRESS, 0, (LPARAM) (LPDWORD) &dwAddr );\r
+ in_addr addr = {0};\r
+ addr.S_un.S_addr = htonl(dwAddr);\r
+ strAddr = A2T( inet_ntoa(addr) );\r
+ }\r
+\r
+ // Retrieve the local port number\r
+ CString strPort = m_EditPort.GetWindowText();\r
+\r
+ // Temporarily disable the Connect/Disconnect button\r
+ m_ButtonConnect.EnableWindow(FALSE);\r
+\r
+ // Connect to the server\r
+ if (0 != m_Client.Connect(strAddr, strPort) )\r
+ {\r
+ Append(IDC_EDIT_STATUS, m_Client.GetLastError());\r
+ MessageBox( _T("Failed to connect to server. Is it started?"), _T("Connect Failed"), MB_ICONWARNING );\r
+ m_Client.Disconnect();\r
+ m_ButtonConnect.EnableWindow( TRUE );\r
+ return;\r
+ }\r
+ m_Client.StartEvents();\r
+\r
+ }\r
+ break;\r
+\r
+ case SOCK_DGRAM:\r
+ {\r
+ // Create the socket\r
+ if (!m_Client.Create(IPfamily, SOCK_DGRAM))\r
+ {\r
+ Append(IDC_EDIT_STATUS, m_Client.GetLastError());\r
+ MessageBox( _T("Failed to create Client socket"), _T("Connect Failed"), MB_ICONWARNING );\r
+ return;\r
+ }\r
+\r
+ m_Client.StartEvents();\r
+\r
+ //Update the dialog\r
+ m_IP4Address.EnableWindow( FALSE );\r
+ m_EditIP6Address.EnableWindow( FALSE );\r
+ m_ButtonSend.EnableWindow( TRUE );\r
+ m_EditSend.EnableWindow( TRUE );\r
+ m_EditPort.EnableWindow( FALSE );\r
+ m_RadioIP4.EnableWindow( FALSE );\r
+ m_RadioIP6.EnableWindow( FALSE );\r
+ m_RadioTCP.EnableWindow( FALSE );\r
+ m_RadioUDP.EnableWindow( FALSE );\r
+ m_ButtonConnect.SetWindowText( _T("Disconnect") );\r
+ m_EditStatus.SetWindowText( _T("Ready to Send") );\r
+ SendMessage( WM_NEXTDLGCTL, (WPARAM)(HWND)m_EditSend, TRUE );\r
+ m_bClientConnected = TRUE;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // Shutdown and close the client socket\r
+ m_Client.Disconnect();\r
+\r
+ // Update the dialog\r
+ m_IP4Address.EnableWindow( TRUE );\r
+ m_ButtonSend.EnableWindow( FALSE );\r
+ m_EditSend.EnableWindow( FALSE );\r
+ m_EditPort.EnableWindow( TRUE );\r
+ m_RadioIP4.EnableWindow( TRUE );\r
+ m_RadioTCP.EnableWindow( TRUE );\r
+ m_RadioUDP.EnableWindow( TRUE );\r
+ m_ButtonConnect.SetWindowText( _T("Connect") );\r
+ m_EditStatus.SetWindowText( _T("Not Connected") );\r
+\r
+ if (m_Client.IsIPV6Supported())\r
+ {\r
+ m_RadioIP6.EnableWindow(TRUE);\r
+ m_EditIP6Address.EnableWindow(TRUE);\r
+ }\r
+ m_bClientConnected = FALSE;\r
+ }\r
+}\r
+\r
+void CClientDialog::OnSend()\r
+{\r
+ switch (m_SocketType)\r
+ {\r
+ case SOCK_STREAM: // for TCP client\r
+ {\r
+ CString sSend = GetDlgItemText(IDC_EDIT_SEND);\r
+ if (SOCKET_ERROR == m_Client.Send(sSend, sSend.GetLength(), 0))\r
+ m_EditStatus.SetWindowText( _T("Send Failed") );\r
+ }\r
+ break;\r
+ case SOCK_DGRAM: // for UDP client\r
+ {\r
+ LRESULT lr = m_RadioIP4.SendMessage( BM_GETCHECK, 0, 0 );\r
+ int IPfamily = (lr == BST_CHECKED)? PF_INET : PF_INET6 ;\r
+\r
+ CString strPort = m_EditPort.GetWindowText();\r
+ CString strSend = m_EditSend.GetWindowText();\r
+\r
+ // Retrieve the IP Address\r
+ CString strAddr;\r
+ if (PF_INET6 == IPfamily)\r
+ {\r
+ strAddr = m_EditIP6Address.GetWindowText();\r
+ }\r
+ else\r
+ {\r
+ DWORD dwAddr = 0;\r
+ m_IP4Address.SendMessage( IPM_GETADDRESS, 0, (LPARAM) (LPDWORD) &dwAddr );\r
+ in_addr addr = {0};\r
+ addr.S_un.S_addr = htonl(dwAddr);\r
+ strAddr = A2T( inet_ntoa(addr) );\r
+ }\r
+\r
+ if (SOCKET_ERROR == m_Client.SendTo( strSend, strSend.GetLength(), 0, strAddr, strPort ))\r
+ m_EditStatus.SetWindowText( _T("SendTo Failed") );\r
+ }\r
+ break;\r
+ }\r
+}\r
+\r
+\r