• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

WINSOCK: Microsoft Winsock Control

Started by José Roca, December 18, 2008, 02:25:31 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

José Roca

 
The Winsock control, invisible to the user, provides easy access to TCP and UDP network services. It can be used by Microsoft Access, Visual Basic, Visual C++, or Visual FoxPro developers. To write client or server applications you do not need to understand the details of TCP or to call low level Winsock APIs. By setting properties and invoking methods of the control, you can easily connect to a remote machine and exchange data in both directions.

TCP Basics

The Transfer Control Protocol allows you to create and maintain a connection to a remote computer. Using the connection, both computers can stream data between themselves.

If you are creating a client application, you must know the server computer's name or IP address (RemoteHost property), as well as the port (RemotePort property) on which it will be "listening." Then invoke the Connect method.

If you are creating a server application, set a port (LocalPort property) on which to listen, and invoke the Listen method. When the client computer requests a connection, the ConnectionRequest event will occur. To complete the connection, invoke the Accept method within the ConnectionRequest event.

Once a connection has been made, either computer can send and receive data. To send data, invoke the SendData method. Whenever data is received, the DataArrival event occurs. Invoke the GetData method within the DataArrival event to retrieve the data.

UDP Basics

The User Datagram Protocol (UDP) is a connectionless protocol. Unlike TCP operations, computers do not establish a connection. Also, a UDP application can be either a client or a server.

To transmit data, first set the client computer's LocalPort property. The server computer then needs only to set the RemoteHost to the Internet address of the client computer, and the RemotePort property to the same port as the client computer's LocalPort property, and invoke the SendData method to begin sending messages. The client computer then uses the GetData method within the DataArrival event to retrieve the sent messages.

© 2005 Microsoft Corporation. All rights reserved.

José Roca

#1
 
This example creates a TCP client that uses the port 1001.



  • Compile TCP_Client.BAS and TCP_Server.BAS

  • RUN TCP_Server.EXE - It will listen at port 1001

  • RUN TCP_Client.EXE. Click the Connect button.

  • Type some text in the input window of TCP_Client. It will be echoed in the output window of TCP_Server.

  • Type some text in the input window of TCP_Server. It will be echoed in the output window of TCP_Client.

The examples use registration-free instances of the control.

Registration-free means that you don't need to register the control to be able to use it. To use this registration-free version, you must copy MSWINSCK.OCX in the application folder, as if it was an standard DLL.

For using a registered version of the control, change the following code in the examples:


pTcpClient = CreateInstanceFromDll(EXE.Path$ & "MSWINSCK.OCX", $CLSID_Winsock, $IID_IMSWinsockControl, $RTLKEY_Winsock)
pTcpServer = CreateInstanceFromDll(EXE.Path$ & "MSWINSCK.OCX", $CLSID_Winsock, $IID_IMSWinsockControl, $RTLKEY_Winsock)


to:


pTcpClient = NEWCOM "MSWinsock.Winsock.1"
pTcpSerer = NEWCOM "MSWinsock.Winsock.1"


TCP Client:


' ########################################################################################
' This example creates a TCP client that uses the port 1001.
'
' Compile TCP_Client.BAS and TCP_Server.BAS
' RUN TCP_Server.EXE - It will listen at port 1001
' RUN TCP_Client.EXE. Click the Connect button.
' Type some text in the input window of TCP_Client. It will be echoed in the output window
' of TCP_Server.
' Type some text in the input window of TCP_Server. It will be echoed in the output window
' of TCP_Client.
'
' ########################################################################################

' SED_PBWIN - Use the PBWIN compiler
#COMPILE EXE
#DIM ALL

#INCLUDE "mswinsck.inc"
#INCLUDE "ole2utils.inc"

%IDC_INPUT  = 1001
%IDC_OUTPUT = 1002

GLOBAL g_hDlg AS DWORD
GLOBAL pTcpClient AS IMSWinsockControl

' ========================================================================================
' Main
' ========================================================================================
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   LOCAL hDlg AS LONG

   DIALOG NEW 0, "Winsock TCP Chat Test - Client", 10, 70, 250, 240, %WS_OVERLAPPED OR %WS_THICKFRAME OR %WS_SYSMENU OR _
   %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_VISIBLE, %WS_EX_TOPMOST TO hDlg
   ' For icon from resource, instead use something like, LoadIcon(hInst, "APPICON")
   DIALOG SEND hDlg, %WM_SETICON, %ICON_SMALL, LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
   DIALOG SEND hDlg, %WM_SETICON, %ICON_BIG, LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
   CONTROL ADD TEXTBOX, hDlg, %IDC_INPUT, "Run TCP_Server. Click conenct and then type some text. It will echoed in the Server window", 5, 5, 388, 90, _
      %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %ES_MULTILINE, %WS_EX_CLIENTEDGE
   CONTROL ADD TEXTBOX, hDlg, %IDC_OUTPUT, "", 5, 100, 388, 90, _
      %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %ES_MULTILINE OR %ES_READONLY, %WS_EX_CLIENTEDGE

   CONTROL ADD BUTTON, hDlg, %IDOK, "&Connect", 0, 0, 50, 14, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT
   CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Close", 0, 0, 50, 14, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT

   g_hDlg = hDlg

   DIALOG SHOW MODAL hDlg, CALL DlgProc

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main Dialog procedure
' ========================================================================================
CALLBACK FUNCTION DlgProc() AS LONG

   LOCAL  rc               AS RECT
   LOCAL  hr               AS LONG
   LOCAL  strText          AS STRING
   STATIC pTcpClientEvents AS DMSWinsockControlEventsImpl

   SELECT CASE CB.MSG

      CASE %WM_INITDIALOG
         ' Create a registration-free instance of the control
         pTcpClient = CreateInstanceFromDll(EXE.Path$ & "MSWINSCK.OCX", $CLSID_Winsock, $IID_IMSWinsockControl, $RTLKEY_Winsock)
         IF ISOBJECT(pTcpClient) THEN
            ' Connect to the events fired by the control
            pTcpClientEvents = CLASS "CDMSWinsockControlEvents"
            IF ISOBJECT(pTcpClientEvents) THEN EVENTS FROM pTcpClient CALL pTcpClientEvents
            ' Set the UDP protocol
            pTcpClient.Protocol = %sckTCPProtocol
            ' Set the remote host using the Local IP address
            pTcpClient.RemoteHost = pTcpClient.LocalIP
            ' Set the remote port
            pTcpClient.RemotePort = 1001
         END IF

      CASE %WM_SIZE
         IF CB.WPARAM <> %SIZE_MINIMIZED THEN
            GetClientRect CB.HNDL, rc
            MoveWindow GetDlgItem(CB.HNDL, %IDC_INPUT), 10, 10, (rc.nRight - rc.nLeft) - 20, ((rc.nBottom - rc.nTop) \ 2) - 40, %TRUE
            MoveWindow GetDlgItem(CB.HNDL, %IDC_OUTPUT), 10, ((rc.nBottom - rc.nTop) \ 2) - 20, (rc.nRight - rc.nLeft) - 20, ((rc.nBottom - rc.nTop) \ 2) - 40, %TRUE
            MoveWindow GetDlgItem(CB.HNDL, %IDOK), (rc.nRight - rc.nLeft) - 185, (rc.nBottom - rc.nTop) - 35, 75, 23, %TRUE
            MoveWindow GetDlgItem(CB.HNDL, %IDCANCEL), (rc.nRight - rc.nLeft) - 95, (rc.nBottom - rc.nTop) - 35, 75, 23, %TRUE
         END IF

      CASE %WM_COMMAND
         SELECT CASE CB.CTL
            CASE %IDOK
               IF CB.CTLMSG = %BN_CLICKED THEN
                  ' Connect to the server
                  pTcpClient.Connect
               END IF
            CASE %IDCANCEL
               IF CB.CTLMSG = %BN_CLICKED THEN DIALOG END CB.HNDL, 0
            CASE %IDC_INPUT
               IF CB.CTLMSG = %EN_CHANGE THEN
                  ' Retrieve the text of the input window
                  CONTROL GET TEXT CB.HNDL, %IDC_INPUT TO strText
                  ' Send the text
                  IF pTcpClient.State = %sckConnected THEN
                     pTcpClient.SendData strText
                  END IF

               END IF
         END SELECT

      CASE %WM_DESTROY
         ' Close the connection
         IF pTcpClient.State <> %sckClosed THEN
            pTcpClient.Close
         END IF
         ' Disconnect events
         IF ISOBJECT(pTcpClientEvents) THEN EVENTS END pTcpClientEvents
         ' Release the control
         IF ISOBJECT(pTcpClient) THEN pTcpClient = NOTHING

   END SELECT

END FUNCTION
' ========================================================================================


' ########################################################################################
' Class CDMSWinsockControlEvents
' Interface name = DMSWinsockControlEvents
' IID = {248DD893-BB45-11CF-9ABC-0080C7E7B78D}
' Microsoft Winsock Control events
' Attributes = 4112 [&H1010] [Hidden] [Dispatchable]
' Code generated by the TypeLib Browser 4.0.13 (c) 2008 by José Roca
' Date: 18 dic 2008   Time: 01:54:58
' ########################################################################################

CLASS CDMSWinsockControlEvents GUID$("{5DBC24EC-EEEB-4F33-BBD9-D1BEFACA501D}") AS EVENT

INTERFACE DMSWinsockControlEventsImpl GUID$("{248DD893-BB45-11CF-9ABC-0080C7E7B78D}") AS EVENT

  INHERIT IDispatch

   ' =====================================================================================
   METHOD Error <6> ( _
     BYVAL Number AS INTEGER _                          ' Number VT_I2 <Integer>
   , BYREF Description AS STRING _                      ' *Description VT_BSTR
   , BYVAL Scode AS LONG _                              ' Scode VT_I4 <Long>
   , BYVAL bstrSource AS STRING _                       ' Source VT_BSTR
   , BYVAL HelpFile AS STRING _                         ' HelpFile VT_BSTR
   , BYVAL HelpContext AS LONG _                        ' HelpContext VT_I4 <Long>
   , BYREF CancelDisplay AS INTEGER _                   ' *CancelDisplay VT_BOOL <Integer>
   )                                                    ' void

     SetWindowText g_Hdlg, "Error " & FORMAT$(Scode) & " - " & ACODE$(Description)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD DataArrival <0> ( _
     BYVAL bytesTotal AS LONG _                         ' bytesTotal VT_I4 <Long>
   )                                                    ' void

      ' Retrieve the text received and output it in the output window
      LOCAL vData AS VARIANT
      pTcpClient.GetData vData, 8   ' %vbString = 8
      CONTROL SET TEXT g_hDlg, %IDC_OUTPUT, VARIANT$(vData)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Connect <1>

      SetWindowText g_Hdlg, "Connect"

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD ConnectionRequest <2> ( _
     BYVAL requestID AS LONG _                          ' requestID VT_I4 <Long>
   )                                                    ' void

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Close <5>

      SetWindowText g_Hdlg, "Close"

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SendProgress <3> ( _
     BYVAL bytesSent AS LONG _                          ' bytesSent VT_I4 <Long>
   , BYVAL bytesRemaining AS LONG _                     ' bytesRemaining VT_I4 <Long>
   )                                                    ' void

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SendComplete <4>

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

END INTERFACE

END CLASS



TCP Server:


' ########################################################################################
' This example creates a TCP server that listen the port 1001.
'
' Compile TCP_Client.BAS and TCP_Server.BAS
' RUN TCP_Server.EXE - It will listen at port 1001
' RUN TCP_Client.EXE. Click the Connect button.
' Type some text in the input window of TCP_Client. It will be echoed in the output window
' of TCP_Server.
' Type some text in the input window of TCP_Server. It will be echoed in the output window
' of TCP_Client.
' ########################################################################################

' SED_PBWIN - Use the PBWIN compiler
#COMPILE EXE
#DIM ALL

#INCLUDE "mswinsck.inc"
#INCLUDE "ole2utils.inc"

%IDC_INPUT  = 1001
%IDC_OUTPUT = 1002

GLOBAL g_hDlg AS DWORD
GLOBAL pTcpServer AS IMSWinsockControl

' ========================================================================================
' Main
' ========================================================================================
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   LOCAL hDlg AS LONG

   DIALOG NEW 0, "Winsock TCP Chat Test - Server", 270, 70, 250, 240, %WS_OVERLAPPED OR %WS_THICKFRAME OR %WS_SYSMENU OR _
   %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_VISIBLE, %WS_EX_TOPMOST TO hDlg
   ' For icon from resource, instead use something like, LoadIcon(hInst, "APPICON")
   DIALOG SEND hDlg, %WM_SETICON, %ICON_SMALL, LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
   DIALOG SEND hDlg, %WM_SETICON, %ICON_BIG, LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
   CONTROL ADD TEXTBOX, hDlg, %IDC_INPUT, "Type some text and it will echoed in the Client window", 5, 5, 388, 90, _
      %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %ES_MULTILINE, %WS_EX_CLIENTEDGE
   CONTROL ADD TEXTBOX, hDlg, %IDC_OUTPUT, "", 5, 100, 388, 90, _
      %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %ES_MULTILINE OR %ES_READONLY, %WS_EX_CLIENTEDGE

   CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Close", 0, 0, 50, 14, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT

   g_hDlg = hDlg

   DIALOG SHOW MODAL hDlg, CALL DlgProc

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main Dialog procedure
' ========================================================================================
CALLBACK FUNCTION DlgProc() AS LONG

   LOCAL  rc AS RECT
   LOCAL  hr AS LONG
   LOCAL  strText AS STRING
   STATIC pTcpServerEvents AS DMSWinsockControlEventsImpl


   SELECT CASE CB.MSG

      CASE %WM_INITDIALOG
         ' Create a registration-free instance of the control
         pTcpServer = CreateInstanceFromDll(EXE.Path$ & "MSWINSCK.OCX", $CLSID_Winsock, $IID_IMSWinsockControl, $RTLKEY_Winsock)
         IF ISOBJECT(pTcpServer) THEN
            ' Connect to the events fired by the control
            pTcpServerEvents = CLASS "CDMSWinsockControlEvents"
            IF ISOBJECT(pTcpServerEvents) THEN EVENTS FROM pTcpServer CALL pTcpServerEvents
            ' Set the UDP protocol
            pTcpServer.Protocol = %sckTCPProtocol
            ' Set the remote port
            pTcpServer.LocalPort = 1001
            ' Call the Listen method
            pTcpServer.Listen
         END IF

      CASE %WM_SIZE
         ' Resize the two sample buttons of the dialog
         IF CB.WPARAM <> %SIZE_MINIMIZED THEN
            GetClientRect CBHNDL, rc
            MoveWindow GetDlgItem(CB.HNDL, %IDC_INPUT), 10, 10, (rc.nRight - rc.nLeft) - 20, ((rc.nBottom - rc.nTop) \ 2) - 40, %TRUE
            MoveWindow GetDlgItem(CB.HNDL, %IDC_OUTPUT), 10, ((rc.nBottom - rc.nTop) \ 2) - 20, (rc.nRight - rc.nLeft) - 20, ((rc.nBottom - rc.nTop) \ 2) - 40, %TRUE
            MoveWindow GetDlgItem(CB.HNDL, %IDCANCEL), (rc.nRight - rc.nLeft) - 95, (rc.nBottom - rc.nTop) - 35, 75, 23, %TRUE
         END IF

      CASE %WM_COMMAND
         SELECT CASE CB.CTL
            CASE %IDCANCEL
               IF CB.CTLMSG = %BN_CLICKED THEN DIALOG END CB.HNDL, 0
            CASE %IDC_INPUT
               IF CB.CTLMSG = %EN_CHANGE THEN
                  ' Retrieve the text of the input window
                  CONTROL GET TEXT CB.HNDL, %IDC_INPUT TO strText
                  ' Send the text
                  pTcpServer.SendData strText
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' Close the connection
         IF pTcpServer.State <> %sckClosed THEN
            pTcpServer.Close
         END IF
         ' Disconnect events
         IF ISOBJECT(pTcpServerEvents) THEN EVENTS END pTcpServerEvents
         ' Release the control
         IF ISOBJECT(pTcpServer) THEN pTcpServer = NOTHING

   END SELECT

END FUNCTION
' ========================================================================================


' ########################################################################################
' Class CDMSWinsockControlEvents
' Interface name = DMSWinsockControlEvents
' IID = {248DD893-BB45-11CF-9ABC-0080C7E7B78D}
' Microsoft Winsock Control events
' Attributes = 4112 [&H1010] [Hidden] [Dispatchable]
' Code generated by the TypeLib Browser 4.0.13 (c) 2008 by José Roca
' Date: 18 dic 2008   Time: 01:54:58
' ########################################################################################

CLASS CDMSWinsockControlEvents GUID$("{5DBC24EC-EEEB-4F33-BBD9-D1BEFACA501D}") AS EVENT

INTERFACE DMSWinsockControlEventsImpl GUID$("{248DD893-BB45-11CF-9ABC-0080C7E7B78D}") AS EVENT

  INHERIT IDispatch

   ' =====================================================================================
   METHOD Error <6> ( _
     BYVAL Number AS INTEGER _                          ' Number VT_I2 <Integer>
   , BYREF Description AS STRING _                      ' *Description VT_BSTR
   , BYVAL Scode AS LONG _                              ' Scode VT_I4 <Long>
   , BYVAL bstrSource AS STRING _                       ' Source VT_BSTR
   , BYVAL HelpFile AS STRING _                         ' HelpFile VT_BSTR
   , BYVAL HelpContext AS LONG _                        ' HelpContext VT_I4 <Long>
   , BYREF CancelDisplay AS INTEGER _                   ' *CancelDisplay VT_BOOL <Integer>
   )                                                    ' void

     SetWindowText g_Hdlg, "Error " & FORMAT$(Scode) & " - " & ACODE$(Description)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD DataArrival <0> ( _
     BYVAL bytesTotal AS LONG _                         ' bytesTotal VT_I4 <Long>
   )                                                    ' void

      ' Retrieve the text received and output it in the output window
      LOCAL vData AS VARIANT
      pTcpServer.GetData vData, 8   ' %vbString = 8
      CONTROL SET TEXT g_hDlg, %IDC_OUTPUT, VARIANT$(vData)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Connect <1>

      SetWindowText g_Hdlg, "Connect"

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD ConnectionRequest <2> ( _
     BYVAL requestID AS LONG _                          ' requestID VT_I4 <Long>
   )                                                    ' void

      ' Check if the control's State is closed. If not, close the connection
      ' before accepting the new connection.
      IF pTcpServer.State <> %sckClosed THEN pTcpServer.Close

      ' Accept the request with the requestID parameter.
      pTcpServer.Accept requestID
      SetWindowText g_Hdlg, "ConnectionRequest - requestID: " & FORMAT$(requestID)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Close <5>

      SetWindowText g_Hdlg, "Close"

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SendProgress <3> ( _
     BYVAL bytesSent AS LONG _                          ' bytesSent VT_I4 <Long>
   , BYVAL bytesRemaining AS LONG _                     ' bytesRemaining VT_I4 <Long>
   )                                                    ' void

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SendComplete <4>

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

END INTERFACE

END CLASS


José Roca

#2
 
This example creates two winsock controls, one in the port 1001 and the other in the port 1002. It uses the UDP protocol to echo the text written in the first edit control to the second winsock control. In the event DataArrival, we retrieve the text sent and output it in the second edit control.

The example uses registration-free instances of the control.

Registration-free means that you don't need to register the control to be able to use it. To use this registration-free version, you must copy MSWINSCK.OCX in the application folder, as if it was an standard DLL.

For using a registered version of the control, change the following code in the example:


pWinsockA = CreateInstanceFromDll(EXE.Path$ & "MSWINSCK.OCX", $CLSID_Winsock, $IID_IMSWinsockControl, $RTLKEY_Winsock)
pWinsockB = CreateInstanceFromDll(EXE.Path$ & "MSWINSCK.OCX", $CLSID_Winsock, $IID_IMSWinsockControl, $RTLKEY_Winsock)


to:


pWinsockA = NEWCOM "MSWinsock.Winsock.1"
pWinsockB = NEWCOM "MSWinsock.Winsock.1"


Full example code:


' ########################################################################################
' This example creates two winsock controls, one in the port 1001 and the other in the port
' 1002. It uses the UDP protocol to echo the text written in the first edit control to the
' second winsock control. In the event WinsockControlEvents_DataArrival, we retrieve the
' text sent and output it in the second edit control.
' ########################################################################################

' SED_PBWIN - Use the PBWIN compiler
#COMPILE EXE
#DIM ALL

#INCLUDE "mswinsck.inc"
#INCLUDE "ole2utils.inc"

%IDC_INPUT  = 1001
%IDC_OUTPUT = 1002

GLOBAL g_hDlg AS DWORD
GLOBAL pWinsockA AS IMSWinsockControl
GLOBAL pWinsockB AS IMSWinsockControl

' ========================================================================================
' Main
' ========================================================================================
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   LOCAL hDlg AS LONG

   DIALOG NEW 0, "Winsock UDP Test", , , 400, 240, %WS_OVERLAPPED OR %WS_THICKFRAME OR %WS_SYSMENU OR _
   %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_VISIBLE OR %DS_CENTER TO hDlg
   ' For icon from resource, instead use something like, LoadIcon(hInst, "APPICON")
   DIALOG SEND hDlg, %WM_SETICON, %ICON_SMALL, LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
   DIALOG SEND hDlg, %WM_SETICON, %ICON_BIG, LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
   CONTROL ADD TEXTBOX, hDlg, %IDC_INPUT, "Type some text and it will echoed in the second window", 5, 5, 388, 90, _
      %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %ES_MULTILINE, %WS_EX_CLIENTEDGE
   CONTROL ADD TEXTBOX, hDlg, %IDC_OUTPUT, "", 5, 100, 388, 90, _
      %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %ES_MULTILINE OR %ES_READONLY, %WS_EX_CLIENTEDGE

   CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Close", 0, 0, 50, 14, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT

   g_hDlg = hDlg

   DIALOG SHOW MODAL hDlg, CALL DlgProc

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main Dialog procedure
' ========================================================================================
CALLBACK FUNCTION DlgProc() AS LONG

   LOCAL  rc AS RECT
   LOCAL  hr AS LONG
   LOCAL  strText AS STRING
   STATIC pWinsockEventsA AS DMSWinsockControlEventsAImpl
   STATIC pWinsockEventsB AS DMSWinsockControlEventsAImpl

   SELECT CASE CB.MSG

      CASE %WM_INITDIALOG
         ' Create the first winsock control
         ' Create a registration-free instance of the control
         pWinsockA = CreateInstanceFromDll(EXE.Path$ & "MSWINSCK.OCX", $CLSID_Winsock, $IID_IMSWinsockControl, $RTLKEY_Winsock)
         IF ISOBJECT(pWinsockA) THEN
            ' Connect to the events fired by the control
            pWinsockEventsA = CLASS "CDMSWinsockControlEventsA"
            IF ISOBJECT(pWinsockEventsA) THEN EVENTS FROM pWinsockA CALL pWinsockEventsA
            ' Set the UDP protocol
            pWinsockA.Protocol = %sckUDPProtocol
            ' Set the remote host using the computer "friendly" name
            pWinsockA.RemoteHost = UCODE$("PEPEHP")   ' <-- change as needed
            ' Set the remote port
            pWinsockA.RemotePort = 1001
            ' Bind it to the local port
            pWinsockA.Bind 1002
         END IF

         ' Create the second winsock control
         pWinsockB = CreateInstanceFromDll(EXE.Path$ & "MSWINSCK.OCX", $CLSID_Winsock, $IID_IMSWinsockControl, $RTLKEY_Winsock)
         IF ISOBJECT(pWinsockB) THEN
            ' Connect to the events fired by the control
            pWinsockEventsB = CLASS "CDMSWinsockControlEventsB"
            IF ISOBJECT(pWinsockEventsB) THEN EVENTS FROM pWinsockB CALL pWinsockEventsB
            ' Set the UDP protocol
            pWinsockB.Protocol = %sckUDPProtocol
            ' Set the remote host using the computer "friendly" name
            pWinsockB.RemoteHost = UCODE$("PEPEHP")   ' <-- change as needed
            ' Set the remote port
            pWinsockB.RemotePort = 1002
            ' Bind it to the local port
            pWinsockB.Bind 1001
         END IF

      CASE %WM_SIZE
         ' Resize the two sample buttons of the dialog
         IF CB.WPARAM <> %SIZE_MINIMIZED THEN
            GetClientRect CBHNDL, rc
            MoveWindow GetDlgItem(CB.HNDL, %IDC_INPUT), 10, 10, (rc.nRight - rc.nLeft) - 20, ((rc.nBottom - rc.nTop) \ 2) - 40, %TRUE
            MoveWindow GetDlgItem(CB.HNDL, %IDC_OUTPUT), 10, ((rc.nBottom - rc.nTop) \ 2) - 20, (rc.nRight - rc.nLeft) - 20, ((rc.nBottom - rc.nTop) \ 2) - 40, %TRUE
            MoveWindow GetDlgItem(CB.HNDL, %IDCANCEL), (rc.nRight - rc.nLeft) - 95, (rc.nBottom - rc.nTop) - 35, 75, 23, %TRUE
         END IF

      CASE %WM_COMMAND
         SELECT CASE CB.CTL
            CASE %IDCANCEL
               IF CB.CTLMSG = %BN_CLICKED THEN DIALOG END CB.HNDL, 0
            CASE %IDC_INPUT
               IF CB.CTLMSG = %EN_CHANGE THEN
                  ' Retrieve the text of the input window
                  CONTROL GET TEXT CB.HNDL, %IDC_INPUT TO strText
                  ' Send the text
                  pWinsockA.SendData strText
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' Close the connections
         IF pWinsockA.State <> %sckClosed THEN pWinsockA.Close
         IF pWinsockB.State <> %sckClosed THEN pWinsockB.Close
         ' Disconnect events
         IF ISOBJECT(pWinsockEventsA) THEN EVENTS END pWinsockEventsA
         IF ISOBJECT(pWinsockEventsB) THEN EVENTS END pWinsockEventsB
         ' Release the controls
         IF ISOBJECT(pWinsockA) THEN pWinsockA = NOTHING
         IF ISOBJECT(pWinsockB) THEN pWinsockB = NOTHING

   END SELECT

END FUNCTION
' ========================================================================================


' ########################################################################################
' Class CDMSWinsockControlEvents
' Interface name = DMSWinsockControlEvents
' IID = {248DD893-BB45-11CF-9ABC-0080C7E7B78D}
' Microsoft Winsock Control events
' Attributes = 4112 [&H1010] [Hidden] [Dispatchable]
' ########################################################################################

CLASS CDMSWinsockControlEventsA GUID$("{5DBC24EC-EEEB-4F33-BBD9-D1BEFACA501D}") AS EVENT

INTERFACE DMSWinsockControlEventsAImpl GUID$("{248DD893-BB45-11CF-9ABC-0080C7E7B78D}") AS EVENT

  INHERIT IDispatch

   ' =====================================================================================
   METHOD Error <6> ( _
     BYVAL Number AS INTEGER _                          ' Number VT_I2 <Integer>
   , BYREF Description AS STRING _                      ' *Description VT_BSTR
   , BYVAL Scode AS LONG _                              ' Scode VT_I4 <Long>
   , BYVAL bstrSource AS STRING _                       ' Source VT_BSTR
   , BYVAL HelpFile AS STRING _                         ' HelpFile VT_BSTR
   , BYVAL HelpContext AS LONG _                        ' HelpContext VT_I4 <Long>
   , BYREF CancelDisplay AS INTEGER _                   ' *CancelDisplay VT_BOOL <Integer>
   )                                                    ' void

     SetWindowText g_Hdlg, "Error " & FORMAT$(Scode) & " - " & ACODE$(Description)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD DataArrival <0> ( _
     BYVAL bytesTotal AS LONG _                         ' bytesTotal VT_I4 <Long>
   )                                                    ' void

      ' Retrieve the text received and output it in the output window
      LOCAL vData AS VARIANT
      pWinsockA.GetData vData, 8   ' %vbString = 8
      CONTROL SET TEXT g_hDlg, %IDC_OUTPUT, VARIANT$(vData)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Connect <1>

      SetWindowText g_Hdlg, "Connect"

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD ConnectionRequest <2> ( _
     BYVAL requestID AS LONG _                          ' requestID VT_I4 <Long>
   )                                                    ' void

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Close <5>

      SetWindowText g_Hdlg, "Close"

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SendProgress <3> ( _
     BYVAL bytesSent AS LONG _                          ' bytesSent VT_I4 <Long>
   , BYVAL bytesRemaining AS LONG _                     ' bytesRemaining VT_I4 <Long>
   )                                                    ' void

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SendComplete <4>

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

END INTERFACE

END CLASS


CLASS CDMSWinsockControlEventsB GUID$("{5DBC24EC-EEEB-4F33-BBD9-D1BEFACA501E}") AS EVENT

INTERFACE DMSWinsockControlEventsBImpl GUID$("{248DD893-BB45-11CF-9ABC-0080C7E7B78D}") AS EVENT

  INHERIT IDispatch

   ' =====================================================================================
   METHOD Error <6> ( _
     BYVAL Number AS INTEGER _                          ' Number VT_I2 <Integer>
   , BYREF Description AS STRING _                      ' *Description VT_BSTR
   , BYVAL Scode AS LONG _                              ' Scode VT_I4 <Long>
   , BYVAL bstrSource AS STRING _                       ' Source VT_BSTR
   , BYVAL HelpFile AS STRING _                         ' HelpFile VT_BSTR
   , BYVAL HelpContext AS LONG _                        ' HelpContext VT_I4 <Long>
   , BYREF CancelDisplay AS INTEGER _                   ' *CancelDisplay VT_BOOL <Integer>
   )                                                    ' void

     SetWindowText g_Hdlg, "Error " & FORMAT$(Scode) & " - " & ACODE$(Description)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD DataArrival <0> ( _
     BYVAL bytesTotal AS LONG _                         ' bytesTotal VT_I4 <Long>
   )                                                    ' void

      ' Retrieve the text received and output it in the output window
      LOCAL vData AS VARIANT
      pWinsockB.GetData vData, 8   ' %vbString = 8
      CONTROL SET TEXT g_hDlg, %IDC_OUTPUT, VARIANT$(vData)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Connect <1>

      SetWindowText g_Hdlg, "Connect"

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD ConnectionRequest <2> ( _
     BYVAL requestID AS LONG _                          ' requestID VT_I4 <Long>
   )                                                    ' void

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Close <5>

      SetWindowText g_Hdlg, "Close"

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SendProgress <3> ( _
     BYVAL bytesSent AS LONG _                          ' bytesSent VT_I4 <Long>
   , BYVAL bytesRemaining AS LONG _                     ' bytesRemaining VT_I4 <Long>
   )                                                    ' void

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SendComplete <4>

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

END INTERFACE

END CLASS


José Roca

#3
 
This example creates a winsock control, in the port 1001 and binds it to the port 1002. UDP_Peer.bas creates another winsock control in the port 1002 and binds it to the port 1001.



  • Compile UDP_PeerA.BAS and UDP_PeerB.BAS

  • RUN both programs. They wil stay on top, side by side.

  • Type some text in the input window in UDP_PeerA. It will be echoed in the output window of UDP_PeerB.

  • Type some text in the input window in UDP_PeerB. It will be echoed in the output window of UDP_PeerA.

The examples use registration-free instances of the control.

Registration-free means that you don't need to register the control to be able to use it. To use this registration-free version, you must copy MSWINSCK.OCX in the application folder, as if it was an standard DLL.

For using a registered version of the control, change the following code in the examples:


pUdpClient = CreateInstanceFromDll(EXE.Path$ & "MSWINSCK.OCX", $CLSID_Winsock, $IID_IMSWinsockControl, $RTLKEY_Winsock)
pUdpServer = CreateInstanceFromDll(EXE.Path$ & "MSWINSCK.OCX", $CLSID_Winsock, $IID_IMSWinsockControl, $RTLKEY_Winsock)


to:


pUdpClient = NEWCOM "MSWinsock.Winsock.1"
pUdpSerer = NEWCOM "MSWinsock.Winsock.1"


UDP Client:


' ########################################################################################
' This example creates a winsock control, in the port 1001 and binds it to the port 1002.
' UDP_Peer.bas creates another winsock control in the port 1002 and binds it to the port 1001.
'
' Compile UDP_PeerA.BAS and UDP_PeerB.BAS
' RUN both programs. They wil stay on top, side by side.
' Type some text in the input window in UDP_PeerA. It will be echoed in the output window
' of UDP_PeerB.
' Type some text in the input window in UDP_PeerB. It will be echoed in the output window
' of UDP_PeerA.
' ########################################################################################

' SED_PBWIN - Use the PBWIN compiler
#COMPILE EXE
#DIM ALL

#INCLUDE "mswinsck.inc"
#INCLUDE "ole2utils.inc"

%IDC_INPUT  = 1001
%IDC_OUTPUT = 1002

GLOBAL g_hDlg AS DWORD
GLOBAL pUdpClient AS IMSWinsockControl

' ========================================================================================
' Main
' ========================================================================================
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   LOCAL hDlg AS LONG

   DIALOG NEW 0, "Winsock UDP Chat Test - Peer A", 10, 70, 250, 240, %WS_OVERLAPPED OR %WS_THICKFRAME OR %WS_SYSMENU OR _
   %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_VISIBLE, %WS_EX_TOPMOST TO hDlg
   ' For icon from resource, instead use something like, LoadIcon(hInst, "APPICON")
   DIALOG SEND hDlg, %WM_SETICON, %ICON_SMALL, LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
   DIALOG SEND hDlg, %WM_SETICON, %ICON_BIG, LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
   CONTROL ADD TEXTBOX, hDlg, %IDC_INPUT, "Type some text and it will echoed in the PeerB window", 5, 5, 388, 90, _
      %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %ES_MULTILINE, %WS_EX_CLIENTEDGE
   CONTROL ADD TEXTBOX, hDlg, %IDC_OUTPUT, "", 5, 100, 388, 90, _
      %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %ES_MULTILINE OR %ES_READONLY, %WS_EX_CLIENTEDGE

   CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Close", 0, 0, 50, 14, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT

   g_hDlg = hDlg

   DIALOG SHOW MODAL hDlg, CALL DlgProc

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main Dialog procedure
' ========================================================================================
CALLBACK FUNCTION DlgProc() AS LONG

   LOCAL  rc               AS RECT
   LOCAL  hr               AS LONG
   LOCAL  strText          AS STRING
   STATIC pUdpClientEvents AS DMSWinsockControlEventsImpl

   SELECT CASE CB.MSG

      CASE %WM_INITDIALOG
         ' Create the first winsock control
         pUdpClient = CreateInstanceFromDll(EXE.Path$ & "MSWINSCK.OCX", $CLSID_Winsock, $IID_IMSWinsockControl, $RTLKEY_Winsock)
         IF ISOBJECT(pUdpClient) THEN
            ' Connect to the events fired by the control
            pUdpClientEvents = CLASS "CDMSWinsockControlEvents"
            IF ISOBJECT(pUdpClientEvents) THEN EVENTS FROM pUdpClient CALL pUdpClientEvents
            ' Set the UDP protocol
            pUdpClient.Protocol = %sckUDPProtocol
            ' Set the remote host using the computer "friendly" name
            pUdpClient.RemoteHost = UCODE$("PEPEHP")   ' <-- change as needed
            ' Set the remote port
            pUdpClient.RemotePort = 1001
            ' Bind it to the local port
            pUdpClient.Bind 1002
         END IF

      CASE %WM_SIZE
         ' Resize the two sample buttons of the dialog
         IF CB.WPARAM <> %SIZE_MINIMIZED THEN
            GetClientRect CB.HNDL, rc
            MoveWindow GetDlgItem(CB.HNDL, %IDC_INPUT), 10, 10, (rc.nRight - rc.nLeft) - 20, ((rc.nBottom - rc.nTop) \ 2) - 40, %TRUE
            MoveWindow GetDlgItem(CB.HNDL, %IDC_OUTPUT), 10, ((rc.nBottom - rc.nTop) \ 2) - 20, (rc.nRight - rc.nLeft) - 20, ((rc.nBottom - rc.nTop) \ 2) - 40, %TRUE
            MoveWindow GetDlgItem(CB.HNDL, %IDCANCEL), (rc.nRight - rc.nLeft) - 95, (rc.nBottom - rc.nTop) - 35, 75, 23, %TRUE
         END IF

      CASE %WM_COMMAND
         SELECT CASE CB.CTL
            CASE %IDCANCEL
               IF CB.CTLMSG = %BN_CLICKED THEN DIALOG END CB.HNDL, 0
            CASE %IDC_INPUT
               IF CB.CTLMSG = %EN_CHANGE THEN
                  ' Retrieve the text of the input window
                  CONTROL GET TEXT CB.HNDL, %IDC_INPUT TO strText
                  ' Send the text
                  pUdpClient.SendData strText
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' Close the connection
         IF pUdpClient.State <> %sckClosed THEN pUdpClient.Close
         ' Disconnect events
         IF ISOBJECT(pUdpClientEvents) THEN EVENTS END pUdpClientEvents
         ' Release the control
         IF ISOBJECT(pUdpClient) THEN pUdpClient = NOTHING

   END SELECT

END FUNCTION
' ========================================================================================


' ########################################################################################
' Class CDMSWinsockControlEvents
' Interface name = DMSWinsockControlEvents
' IID = {248DD893-BB45-11CF-9ABC-0080C7E7B78D}
' Microsoft Winsock Control events
' Attributes = 4112 [&H1010] [Hidden] [Dispatchable]
' Code generated by the TypeLib Browser 4.0.13 (c) 2008 by José Roca
' Date: 18 dic 2008   Time: 01:54:58
' ########################################################################################

CLASS CDMSWinsockControlEvents GUID$("{5DBC24EC-EEEB-4F33-BBD9-D1BEFACA501D}") AS EVENT

INTERFACE DMSWinsockControlEventsImpl GUID$("{248DD893-BB45-11CF-9ABC-0080C7E7B78D}") AS EVENT

  INHERIT IDispatch

   ' =====================================================================================
   METHOD Error <6> ( _
     BYVAL Number AS INTEGER _                          ' Number VT_I2 <Integer>
   , BYREF Description AS STRING _                      ' *Description VT_BSTR
   , BYVAL Scode AS LONG _                              ' Scode VT_I4 <Long>
   , BYVAL bstrSource AS STRING _                       ' Source VT_BSTR
   , BYVAL HelpFile AS STRING _                         ' HelpFile VT_BSTR
   , BYVAL HelpContext AS LONG _                        ' HelpContext VT_I4 <Long>
   , BYREF CancelDisplay AS INTEGER _                   ' *CancelDisplay VT_BOOL <Integer>
   )                                                    ' void

     SetWindowText g_Hdlg, "Error " & FORMAT$(Scode) & " - " & ACODE$(Description)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD DataArrival <0> ( _
     BYVAL bytesTotal AS LONG _                         ' bytesTotal VT_I4 <Long>
   )                                                    ' void

      ' Retrieve the text received and output it in the output window
      LOCAL vData AS VARIANT
      pUdpClient.GetData vData, 8   ' %vbString = 8
      CONTROL SET TEXT g_hDlg, %IDC_OUTPUT, VARIANT$(vData)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Connect <1>

      SetWindowText g_Hdlg, "Connect"

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD ConnectionRequest <2> ( _
     BYVAL requestID AS LONG _                          ' requestID VT_I4 <Long>
   )                                                    ' void

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Close <5>

      SetWindowText g_Hdlg, "Close"

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SendProgress <3> ( _
     BYVAL bytesSent AS LONG _                          ' bytesSent VT_I4 <Long>
   , BYVAL bytesRemaining AS LONG _                     ' bytesRemaining VT_I4 <Long>
   )                                                    ' void

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SendComplete <4>

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

END INTERFACE

END CLASS


UDP Server:


' ########################################################################################
' This example creates a winsock control, in the port 1001 and binds it to the port 1002.
' UDP_Peer.bas creates another winsock control in the port 1002 and binds it to the port 1001.
'
' Compile UDP_PeerA.BAS and UDP_PeerB.BAS
' RUN both programs. They wil stay on top, side by side.
' Type some text in the input window in UDP_PeerA. It will be echoed in the output window
' of UDP_PeerB.
' Type some text in the input window in UDP_PeerB. It will be echoed in the output window
' of UDP_PeerA.
' ########################################################################################

' SED_PBWIN - Use the PBWIN compiler
#COMPILE EXE
#DIM ALL

#INCLUDE "mswinsck.inc"
#INCLUDE "ole2utils.inc"

%IDC_INPUT  = 1001
%IDC_OUTPUT = 1002

GLOBAL g_hDlg AS DWORD
GLOBAL pUdpServer AS IMSWinsockControl

' ========================================================================================
' Main
' ========================================================================================
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG

   LOCAL hDlg AS LONG

   DIALOG NEW 0, "Winsock UDP Chat Test - PeerB", 270, 70, 250, 240, %WS_OVERLAPPED OR %WS_THICKFRAME OR %WS_SYSMENU OR _
   %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_VISIBLE, %WS_EX_TOPMOST TO hDlg
   ' For icon from resource, instead use something like, LoadIcon(hInst, "APPICON")
   DIALOG SEND hDlg, %WM_SETICON, %ICON_SMALL, LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
   DIALOG SEND hDlg, %WM_SETICON, %ICON_BIG, LoadIcon(%NULL, BYVAL %IDI_APPLICATION)
   CONTROL ADD TEXTBOX, hDlg, %IDC_INPUT, "Type some text and it will echoed in the PeerA window", 5, 5, 388, 90, _
      %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %ES_MULTILINE, %WS_EX_CLIENTEDGE
   CONTROL ADD TEXTBOX, hDlg, %IDC_OUTPUT, "", 5, 100, 388, 90, _
      %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %ES_MULTILINE OR %ES_READONLY, %WS_EX_CLIENTEDGE

   CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Close", 0, 0, 50, 14, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %BS_FLAT

   g_hDlg = hDlg

   DIALOG SHOW MODAL hDlg, CALL DlgProc

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main Dialog procedure
' ========================================================================================
CALLBACK FUNCTION DlgProc() AS LONG

   LOCAL  rc               AS RECT
   LOCAL  hr               AS LONG
   LOCAL  strText          AS STRING
   STATIC pUdpServerEvents AS DMSWinsockControlEventsImpl

   SELECT CASE CB.MSG

      CASE %WM_INITDIALOG
         ' Create the second winsock control
         pUdpServer = CreateInstanceFromDll(EXE.Path$ & "MSWINSCK.OCX", $CLSID_Winsock, $IID_IMSWinsockControl, $RTLKEY_Winsock)
         IF ISOBJECT(pUdpServer) THEN
            ' Connect to the events fired by the control
            pUdpServerEvents = CLASS "CDMSWinsockControlEvents"
            IF ISOBJECT(pUdpServerEvents) THEN EVENTS FROM pUdpServer CALL pUdpServerEvents
            ' Set the UDP protocol
            pUdpServer.Protocol = %sckUDPProtocol
            ' Set the remote host using the computer "friendly" name
            pUdpServer.RemoteHost = UCODE$("PEPEHP")   ' <-- change as needed
            ' Set the remote port
            pUdpServer.RemotePort = 1002
            ' Bind it to the local port
            pUdpServer.Bind 1001
         END IF

      CASE %WM_SIZE
         ' Resize the two sample buttons of the dialog
         IF CB.WPARAM <> %SIZE_MINIMIZED THEN
            GetClientRect CB.HNDL, rc
            MoveWindow GetDlgItem(CB.HNDL, %IDC_INPUT), 10, 10, (rc.nRight - rc.nLeft) - 20, ((rc.nBottom - rc.nTop) \ 2) - 40, %TRUE
            MoveWindow GetDlgItem(CB.HNDL, %IDC_OUTPUT), 10, ((rc.nBottom - rc.nTop) \ 2) - 20, (rc.nRight - rc.nLeft) - 20, ((rc.nBottom - rc.nTop) \ 2) - 40, %TRUE
            MoveWindow GetDlgItem(CB.HNDL, %IDCANCEL), (rc.nRight - rc.nLeft) - 95, (rc.nBottom - rc.nTop) - 35, 75, 23, %TRUE
         END IF

      CASE %WM_COMMAND
         SELECT CASE CB.CTL
            CASE %IDCANCEL
               IF CB.CTLMSG = %BN_CLICKED THEN DIALOG END CB.HNDL, 0
            CASE %IDC_INPUT
               IF CB.CTLMSG = %EN_CHANGE THEN
                  ' Retrieve the text of the input window
                  CONTROL GET TEXT CB.HNDL, %IDC_INPUT TO strText
                  ' Send the text
                  pUdpServer.SendData strText
               END IF
         END SELECT

      CASE %WM_DESTROY
         ' Close the connection
         IF pUdpServer.State <> %sckClosed THEN pUdpServer.Close
         ' Disconnect events
         IF ISOBJECT(pUdpServerEvents) THEN EVENTS END pUdpServerEvents
         ' Release the control
         IF ISOBJECT(pUdpServer) THEN pUdpServer = NOTHING

   END SELECT

END FUNCTION
' ========================================================================================


' ########################################################################################
' Class CDMSWinsockControlEvents
' Interface name = DMSWinsockControlEvents
' IID = {248DD893-BB45-11CF-9ABC-0080C7E7B78D}
' Microsoft Winsock Control events
' Attributes = 4112 [&H1010] [Hidden] [Dispatchable]
' Code generated by the TypeLib Browser 4.0.13 (c) 2008 by José Roca
' Date: 18 dic 2008   Time: 01:54:58
' ########################################################################################

CLASS CDMSWinsockControlEvents GUID$("{5DBC24EC-EEEB-4F33-BBD9-D1BEFACA501D}") AS EVENT

INTERFACE DMSWinsockControlEventsImpl GUID$("{248DD893-BB45-11CF-9ABC-0080C7E7B78D}") AS EVENT

  INHERIT IDispatch

   ' =====================================================================================
   METHOD Error <6> ( _
     BYVAL Number AS INTEGER _                          ' Number VT_I2 <Integer>
   , BYREF Description AS STRING _                      ' *Description VT_BSTR
   , BYVAL Scode AS LONG _                              ' Scode VT_I4 <Long>
   , BYVAL bstrSource AS STRING _                       ' Source VT_BSTR
   , BYVAL HelpFile AS STRING _                         ' HelpFile VT_BSTR
   , BYVAL HelpContext AS LONG _                        ' HelpContext VT_I4 <Long>
   , BYREF CancelDisplay AS INTEGER _                   ' *CancelDisplay VT_BOOL <Integer>
   )                                                    ' void

     SetWindowText g_Hdlg, "Error " & FORMAT$(Scode) & " - " & ACODE$(Description)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD DataArrival <0> ( _
     BYVAL bytesTotal AS LONG _                         ' bytesTotal VT_I4 <Long>
   )                                                    ' void

      ' Retrieve the text received and output it in the output window
      LOCAL vData AS VARIANT
      pUdpServer.GetData vData, 8   ' %vbString = 8
      CONTROL SET TEXT g_hDlg, %IDC_OUTPUT, VARIANT$(vData)

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Connect <1>

      SetWindowText g_Hdlg, "Connect"

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD ConnectionRequest <2> ( _
     BYVAL requestID AS LONG _                          ' requestID VT_I4 <Long>
   )                                                    ' void

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD Close <5>

      SetWindowText g_Hdlg, "Close"

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SendProgress <3> ( _
     BYVAL bytesSent AS LONG _                          ' bytesSent VT_I4 <Long>
   , BYVAL bytesRemaining AS LONG _                     ' bytesRemaining VT_I4 <Long>
   )                                                    ' void

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

   ' =====================================================================================
   METHOD SendComplete <4>

     ' *** Insert your code here ***

   END METHOD
   ' =====================================================================================

END INTERFACE

END CLASS