Results 1 to 12 of 12

Thread: [RESOLVED] How to subclass in VB6 without a form?

  1. #1

    Thread Starter
    New Member
    Join Date
    Jul 2018
    Posts
    8

    Resolved [RESOLVED] How to subclass in VB6 without a form?

    I have a VB6 service now so I can run without a form and I want to add a Winsock class to create a TCP server.
    But all classes I can find for Winsock require that the callback from:

    WSAAsyncSelect Lib "Winsock.dll" (ByVal s As Integer, ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal lEvent As Long) As Integer

    must use an .hwnd for the callback, but I have no .hwnd if I do not have a form.
    How can I get thsi callback or create a subclass with no form?

  2. #2

  3. #3
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,009

    Re: How to subclass in VB6 without a form?

    I don't know if you already resoved the issue, but you can create a dummy window to use it just to get messages.

    Code:
    'Declarations:
    Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
    Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long
    
    Private Type CREATESTRUCT
        lpCreateParams As Long
        hInstance As Long
        hMenu As Long
        hWndParent As Long
        cy As Long
        cx As Long
        Y As Long
        X As Long
        style As Long
        lpszName As String
        lpszClass As String
        ExStyle As Long
    End Type
    
    Private mWnd As Long
    Code:
    ' Where you need to create the Window, it may be the Class_Initialize event
    Dim CS As CREATESTRUCT
    
    mWnd = CreateWindowEx(0, "STATIC", " ", 0, 0, 0, 1, 1, 0, 0, App.hInstance, CS)
    
    ' use the mWnd as the "hWnd"
    Code:
    ' Where you need to destrroy the Window, it may be the Class_Terminate event
    DestroyWindow mWnd
    Edit: but you can achieve the same with an invisible form.

    Code:
    Load frmMessages
    
    Unload frmMessages

  4. #4

    Thread Starter
    New Member
    Join Date
    Jul 2018
    Posts
    8

    Re: How to subclass in VB6 without a form?

    I am trying to avoid using forms completely since this is a service.
    So now I have a class called clsServer that encapsulates the Winsock dll.
    I can get a 'client' connection to work fine, but if I try to create a server, it works, but I am having a hard time finding out why I get an error when trying to start a new socket, what am I doing wrong here?:

    I declare the following in my main routine:

    Code:
    Global Socket() As clsServer
    Global SocketCount As Integer
    Then the following in my main service loop:

    Code:
    Dim ListenSocket As New clsServer
    
    'create a server socket that listens for connections..
    ListenSocket.SvrProtocol = sckTCPProtocol
    ListenSocket.SvrLocalPort = 5000
    ListenSocket.SvrSocketListen
    This all functions great, but when a new socket connects, I launch this routine which gives me a run-time error, why?

    Code:
    Public Sub NewSocketAccept()
    'when there's a new socket
    If IncommingSockID <> 0 Then
        SocketCount = SocketCount + 1
        ReDim Preserve Socket(1 To SocketCount) As clsServer 'set a new socket using the Winsock class that requires no form.
        SaveLog " [MISC] New socket accepted!, ID:" & IncommingSockID
        Socket(SocketCount).SvrAcceptRequest IncommingSockID 'Object Variable or With Block Variable not set?? Why?
        'reset so no other sockets can conenct..
        IncommingSockID = 0
    End If
    End Sub

  5. #5
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,122

    Re: How to subclass in VB6 without a form?

    My guess here: Socket(SocketCount) is not set to New clsServer before calling SvrAcceptRequest -- effectively calling it on Nothing

    cheers,
    </wqw>

  6. #6

    Thread Starter
    New Member
    Join Date
    Jul 2018
    Posts
    8

    Re: How to subclass in VB6 without a form?

    OK so I now have it all running, here is a copy of my project; it is a Windows Service, that uses an Asynch Winsock class, which works great as a TCP/IP client, but when I use it to create a TCP/IP server; sockets can connect, but whenever I load a new socket and try to accept the socketID, it keeps telling me that it is not a valid socket ID? Any idea's why?
    VB6 Winsock Server Service.zip

  7. #7
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,122

    Re: How to subclass in VB6 without a form?

    Try to implement this TCP/IP server in a separate project first, before integrating the NT service code.

    Currently you are having troubles with clsServer class, so first make it work in a standalone project.

    Use VBIDE to debug this simple Standard EXE project, don't fight with the final NT service code.

    cheers,
    </wqw>

  8. #8

    Thread Starter
    New Member
    Join Date
    Jul 2018
    Posts
    8

    Question Re: How to subclass in VB6 without a form?

    I don't really see the relevance since the service portion works just fine.
    That also defeats the purpose of trying to run it without a form.

    Regardless, here it is again, compiled with nothing but the Async Winsock class, it still generates the wrong error.
    Just run this and try to connect a TCP/IP client to: localhost:5000
    You will see the same error I am getting. But I cannot figure out why??

    VB6 Winsock Class Only.zip

  9. #9
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,122

    Re: How to subclass in VB6 without a form?

    In WinsockClass.frm remove line 53

    | If IncommingSockID <> 0 Then NewSocketAccept 'connect a new incomming socket if a new socket has been received..

    In clsServer.cls add line 219 with this

    | If IncommingSockID <> 0 Then NewSocketAccept 'connect a new incomming socket if a new socket has been received..

    In Declares.bas remove line 15 this

    | Socket(SocketCount).SvrLocalPort = 5000

    Now you have a multi-connection server on port 5000/tcp and here is short explanation what's going on:
    1. ListenSocket is listening on 5000/tcp
    2. The moment ConnectionRequest event is raised a new instance of clsServer is created and accepts current pending requestID
    3. This new socket uses *different* port (not 5000/tcp) to establish connection with the client
    4. For instance the actual established connection can be srv_ip:36123 <-> client_ip:16923 i.e. 36123 is totally random (and available) port, the same way 16923 is totally random (and available) port on the client
    5. This is how TCP/IP works -- the server listens on port 5000/tcp but on conn request uses another random (and available) *server* port to establish the actual connection with the client

    Btw, doing DoEvents : DoEvents multiple times is not going to fix any conceivable problem IMO.

    cheers,
    </wqw>

  10. #10

    Thread Starter
    New Member
    Join Date
    Jul 2018
    Posts
    8

    Re: How to subclass in VB6 without a form?

    That was so simple to fix - how could I not have seen it!

    Thank you loads wqweto, you rock!

  11. #11

    Thread Starter
    New Member
    Join Date
    Jul 2018
    Posts
    8

    Cool Re: How to subclass in VB6 without a form?

    That was so simple to fix - how could I not have seen it!

    Thank you loads wqweto, you rock!

  12. #12
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,219

    Re: [RESOLVED] How to subclass in VB6 without a form?

    Quote Originally Posted by Levis View Post
    I have a VB6 service now so I can run without a form and I want to add a Winsock class to create a TCP server.
    In a previous thread you've mentioned, that you planned to implement your own little WebServer.

    Nothing wrong with that IMO, since ones own http-supporting endpoint (running InApp, in a VB6-Std-Exe-Process)
    has its use-cases...

    Though now that you want to embed it as a *Service* (probably aiming for 24/7 usage and concurrent multi-user-requests),
    why not use the Web-Service that comes with each Win-OS (configurable in about half an hour, able to run and address VB6-compiled binaries)?

    You'll need at least a man-year of efforts, to make your own (http- or Web-)service run as stable as the existing one which comes with the OS.

    Olaf

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width