Chat App / Messenger
#1
This is a TCP/IP routine. Windows users will need to Okay it, on the first run, with Windows Defender.

I posted two versions. The first minimizes and restores the chat window to activate it. The second uses QB64 _SCREENCLICK. auto-activation allows us to continuously send messages back and forth without clicking the window each rotation.

Sorry Linux and mac users, I tried, but to return focus to each active chat window requires one Win32 API command to restore the window, and mn pointed out that _SCREENCLICK isn't supported in these operating systems. If anyone can figure out a QB64 way to force a minimized window back to the desktop, please let me know.

So to gives this a try, you need to copy and run both the "host" and client" programs. Since the host starts the client, you will need to name the client as messenger_client.bas and save it as messenger_client.exe before you run the host program.

Min/Restore Version

Host
Code: (Select All)
DECLARE DYNAMIC LIBRARY "user32"
    FUNCTION ShowWindow& (BYVAL hWnd AS LONG, BYVAL nCmdShow AS LONG) 'maximize process
END DECLARE

_SCREENMOVE 0, 0
title$ = "Messenger_Host"
_TITLE (title$)
_DELAY .1
hWnd& = _WINDOWHANDLE

_SCREENMOVE 0, 0 ' Set up this host window to the left of your desktop.
WIDTH 60, 25
PALETTE 0, 8
COLOR 7, 0
CLS
IF NOT _FILEEXISTS("messenger_client.exe") THEN PRINT "Cannot find file: messenger_client.exe. Ending...": END
DIM host_msg AS STRING, client_msg AS STRING
DO
    IF initiate = 0 THEN ' This only needs to be performed once, to open the client window.
        DO UNTIL x ' Stay in loop until window determines if it is the host or client window.
            x = _OPENCLIENT("TCP/IP:1234:localhost") ' Used to establish a TCP/IP routine.
            IF x = 0 THEN
                x = _OPENHOST("TCP/IP:1234") ' Note the host and clinet must have the same 1234 I.D. number.
                a$ = "Opening as host." ' x channel is now open and this window becomes the host.
            ELSE
                a$ = "Opening as client." ' Should not go here for this demo.
            END IF
            PRINT a$
        LOOP
        SHELL _HIDE _DONTWAIT "START messenger_client.exe" ' Open the client window.
        initiate = -1 ' Switches this block statement off for all subsequent loops.
    END IF

    IF z = 0 THEN ' Initiates an open channel number when zero.
        DO
            z = _OPENCONNECTION(x) ' Checks if host is available to transfer data.
        LOOP UNTIL z
        PRINT "Connection established."
        _DELAY 1
        LOCATE 2: PRINT SPACE$(_WIDTH * 2) ' Remove previous text.
        LOCATE 3, 1
        GOSUB focus
    END IF

    ' Okay, time to input something on the host that will be communicated to the client.
    COLOR 7: LINE INPUT "Message to client: "; host_msg: PRINT

    PUT #z, , host_msg ' Input is now entered into TCP/IP routine.
    IF host_msg = "" THEN SYSTEM

    DO
        GET #z, , client_msg
    LOOP UNTIL LEN(client_msg) ' Exits loop when a return msg is received.

    COLOR 6: PRINT "Message from client: "; client_msg: PRINT

    host_msg = "": PUT #z, , host_msg$ ' Now put our client value back into the routine. Failure to do so would result in the client not waiting in the GET #x DO/LOOP.
    _KEYCLEAR ' Prevents typing before ready.

    GOSUB focus
LOOP

focus:
_SCREENICON
y& = ShowWindow&(hWnd&, 9)
RETURN


Client (Remember, name and save this one as messenger_client.exe).
Code: (Select All)
DECLARE DYNAMIC LIBRARY "user32"
    FUNCTION ShowWindow& (BYVAL hWnd AS LONG, BYVAL nCmdShow AS LONG) 'maximize process
END DECLARE

title$ = "Messenger_Client"
_TITLE (title$)
_DELAY .1

hWnd& = _WINDOWHANDLE

DIM host_msg AS STRING, client_msg AS STRING
_SCREENMOVE 600, 0 ' Set up this client window next to your host window.
WIDTH 50, 25
PALETTE 0, 8
COLOR 7, 0
CLS
x = _OPENCLIENT("TCP/IP:1234:localhost") ' Used to establish a TCP/IP routine.
PRINT "Opened as client.": PRINT
DO UNTIL x = 0 ' Prevents running if this app is opened without using host.
    DO
        _LIMIT 30
        GET #x, , host_msg ' Waits until it receives message sent from the host.
    LOOP UNTIL LEN(host_msg)

    COLOR 6: PRINT "Message from host: "; host_msg
    PRINT
    _KEYCLEAR ' Prevents typing before ready.

    GOSUB focus

    COLOR 7: LINE INPUT "Message to host: "; client_msg: PRINT
    IF client_msg = "" THEN SYSTEM

    PUT #x, , client_msg
LOOP
END

focus:
_SCREENICON
y& = ShowWindow&(hWnd&, 9)
RETURN

This project is slightly modified from my October 28th post at The QBasic Forum: https://www.tapatalk.com/groups/qbasic/t...39735.html

That one used all Win32 API to find, minimize and restore the window. If you are interested in seeing the extra API stuff, check it out. Also, I play loose and fast with the API type variables. So far I've only been stung once by changing an _OFFSET to a LONG. Most of the time you can get away from convention.

Oh, why bother minimizing and restoring? Well, so far none of us can figure out a way to get a window not just in focus, but active and in focus after another window is made active. Spriggsy and I both came up with the min/restore trick at the same time, which was pretty funny.

Okay, for Linus and Mac fans... (And yes, I made _SCREENCLICK 'smart' so you can move the windows around).

_SCREENCLICK Version: Same App, but uses _SCREENCLICK instead of Win32 API to activate each window.

Host
Code: (Select All)
_SCREENMOVE 0, 0
title$ = "Messenger_Host"
_TITLE (title$)
_DELAY .1

_SCREENMOVE 0, 0 ' Set up this host window to the left of your desktop.
WIDTH 60, 25
PALETTE 0, 8
COLOR 7, 0
CLS
IF NOT _FILEEXISTS("messenger_client.exe") THEN PRINT "Cannot find file: messenger_client.exe. Ending...": END
DIM host_msg AS STRING, client_msg AS STRING
DO
    IF initiate = 0 THEN ' This only needs to be performed once, to open the client window.
        DO UNTIL x ' Stay in loop until window determines if it is the host or client window.
            x = _OPENCLIENT("TCP/IP:1234:localhost") ' Used to establish a TCP/IP routine.
            IF x = 0 THEN
                x = _OPENHOST("TCP/IP:1234") ' Note the host and clinet must have the same 1234 I.D. number.
                a$ = "Opening as host." ' x channel is now open and this window becomes the host.
            ELSE
                a$ = "Opening as client." ' Should not go here for this demo.
            END IF
            PRINT a$
        LOOP
        SHELL _HIDE _DONTWAIT "START messenger_client.exe" ' Open the client window.
        initiate = -1 ' Switches this block statement off for all subsequent loops.
    END IF

    IF z = 0 THEN ' Initiates an open channel number when zero.
        DO
            z = _OPENCONNECTION(x) ' Checks if host is available to transfer data.
        LOOP UNTIL z
        PRINT "Connection established."
        _DELAY 1
        LOCATE 2: PRINT SPACE$(_WIDTH * 2) ' Remove previous text.
        LOCATE 3, 1
        GOSUB focus
    END IF

    ' Okay, time to input something on the host that will be communicated to the client.
    COLOR 7: LINE INPUT "Message to client: "; host_msg: PRINT

    PUT #z, , host_msg ' Input is now entered into TCP/IP routine.
    IF host_msg = "" THEN SYSTEM

    DO
        GET #z, , client_msg
    LOOP UNTIL LEN(client_msg) ' Exits loop when a return msg is received.

    COLOR 6: PRINT "Message from client: "; client_msg: PRINT

    host_msg = "": PUT #z, , host_msg$ ' Now put our client value back into the routine. Failure to do so would result in the client not waiting in the GET #x DO/LOOP.
    _KEYCLEAR ' Prevents typing before ready.

    GOSUB focus
LOOP

focus:
_SCREENCLICK _SCREENX + 60, _SCREENY + 10
RETURN


Client (Name as messenger_client.exe).
Code: (Select All)
title$ = "Messenger_Client"
_TITLE (title$)
_DELAY .1

DIM host_msg AS STRING, client_msg AS STRING
_SCREENMOVE 600, 0 ' Set up this client window next to your host window.
WIDTH 50, 25
PALETTE 0, 8
COLOR 7, 0
CLS
x = _OPENCLIENT("TCP/IP:1234:localhost") ' Used to establish a TCP/IP routine.
PRINT "Opened as client.": PRINT
DO UNTIL x = 0 ' Prevents running if this app is opened without using host.
    DO
        _LIMIT 30
        GET #x, , host_msg ' Waits until it receives message sent from the host.
    LOOP UNTIL LEN(host_msg)

    COLOR 6: PRINT "Message from host: "; host_msg
    PRINT
    _KEYCLEAR ' Prevents typing before ready.

    GOSUB focus

    COLOR 7: LINE INPUT "Message to host: "; client_msg: PRINT
    IF client_msg = "" THEN SYSTEM

    PUT #x, , client_msg
LOOP
END

focus:
_SCREENCLICK _SCREENX + 60, _SCREENY + 10
RETURN


Pete
Reply
#2
It will have to be your program for Windows with Wine because "_SCREENCLICK" isn't implemented on Unix-like operating systems.

It's the penultimate line of both programs you presented in your previous post.
Reply
#3
LOL at Unix Like AKA Linux. like-unix = l-unix, which is an anagram for linux. So now I wonder if it was actually named after Linus Torvalds and this is just a coincidence. Anyway, back on topic, I just checked the Wiki, and there it is...

"Keyword not supported in Linux or macOS versions"

Well I edited the post to just a second version using _SCREENCLICK. Off the top of my head, I can't think of a method that would work to activate a Linux or MacOS window with QB64, but if I come up with one, I'll double check the Wiki, first.

Thanks!

Pete
Reply
#4
(12-09-2022, 04:20 PM)Pete Wrote: LOL at Unix Like AKA Linux. like-unix = l-unix, which is an anagram for linux. So now I wonder if it was actually named after Linus Torvalds and this is just a coincidence.
"Linux" was supposed to be the name of only the kernel. But people insisted so much on that word for the whole operating system, including the parts Mr. Torvalds had nothing to do with and that he had criticized in the past, and some distros made a "style" out of being just "Linux" instead of "GNU/Linux". There's for example "Debian GNU/Linux" but "Fedora Linux". The distro-maker, guided somewhat by legalese (FSF enough said), chooses what their creation is to be called.
Reply
#5
Well I posted a challenge to see if anyone has or can come across a substitute method of activating a window in Linux/Mac systems.

https://staging.qb64phoenix.com/showthread.php?tid=1254

Pete
Reply
#6
I'm curious, with team Steve in charge, is there any kind of overarching vision upheld by discipline when it comes to multi-platform (linux/mac/etc) or is it anything goes these days?  Any more than say QB64 implementing QB45 on windows Vista onwards
Reply
#7
Yes, the bar closes at 12.

Pete
Reply
#8
thanks for reminding me, I sometimes forget this is a bar and not a strip club with Steve prancing about
Reply
#9
Yeah the nurses weren't too happy with him, either, when he kept putting on his hospital gown backwards.

Pete
If eggs are brain food, Biden takes his scrambled.
Reply
#10
oh yeah, that's an old trick from Steve to keep you from sticking to the chair (or is it the other way around?)
Reply




Users browsing this thread: 4 Guest(s)