QB64 Phoenix Edition
Multiscreen program - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Prolific Programmers (https://qb64phoenix.com/forum/forumdisplay.php?fid=26)
+---- Forum: SMcNeill (https://qb64phoenix.com/forum/forumdisplay.php?fid=29)
+---- Thread: Multiscreen program (/showthread.php?tid=2858)



Multiscreen program - SMcNeill - 07-11-2024

Code: (Select All)
DIM SHARED AS LONG x, y, client
SCREEN _NEWIMAGE(640, 480, 32)
host = _OPENHOST("TCP/IP:7319") ' no host found, so begin new host
IF host THEN
_SCREENMOVE 0, 0
DO
IF client = 0 THEN client = _OPENCONNECTION(host) ' receive any new connection
IF client THEN SendXY
x = x + 1: IF x > 1280 THEN x = 0
CLS
_PRINTSTRING (x, y), "Steve is Amazing"
IF x > 1280 - _PRINTWIDTH("Steve is Amazing") THEN _PRINTSTRING (x - 1280, y), "Steve is Amazing"
_DISPLAY
_LIMIT 30
LOOP
ELSE
_SCREENMOVE 640, 0
client = _OPENCLIENT("TCP/IP:7319:localhost") ' Attempt to connect to local host as a client
DO
GetXY
CLS
_PRINTSTRING (x - 640, y), "Steve is Amazing"
_DISPLAY
_LIMIT 30
LOOP
END IF


SUB SendXY
PUT #client, , x
PUT #client, , y
END SUB

SUB GetXY
GET #client, , x
GET #client, , y
END SUB

Inspired by Tempodi's topic: https://qb64phoenix.com/forum/showthread.php?tid=2855

Here, I wanted to create a true multi-screen program. Nothing fancy, but something nice and simple to showcase how easy it is to actually do something like this.

Try run this:

1) Run this.
2) Run a second version of this at the same time while the first version is running.

Then let both versions run for a complete cycle or two, to see the simple effect.

Note: You may need to jump through whatever bells and whistles your OS requires for network/TCP-IP communications and such with your FireWall and Security.


RE: Multiscreen program - NakedApe - 07-11-2024

Very cool! It (they) ran with no issues on my Mac. More dark magic from the Amazing Foo.  Smile


RE: Multiscreen program - SMcNeill - 07-11-2024

The first post was a very simple example of how you'd use two programs and have them communicate with each other, to produce a "multi-screen" program.   Below is a better example of this process at work, for those who might be interested in just running ONE program and letting it produce the multi-screens and handle everything for us.

Code: (Select All)
DIM SHARED AS LONG x, y, r, nul, client
SCREEN _NEWIMAGE(640, 480, 32)
host = _OPENHOST("TCP/IP:7319") ' no host found, so begin new host
IF host THEN
    _SCREENMOVE 0, 0
    SHELL _DONTWAIT COMMAND$(0)
    DO
        IF client = 0 THEN
            client = _OPENCONNECTION(host) ' receive any new connection
        ELSE

            x = x + 2: IF x > 1280 THEN x = 0
            CLS
            _PRINTSTRING (x, y), "Steve is Amazing"
            IF x > 1280 - _PRINTWIDTH("Steve is Amazing") THEN _PRINTSTRING (x - 1280, y), "Steve is Amazing"
            _DISPLAY
            _LIMIT 30
            IF _EXIT THEN x = -1: y = -1
            SendXY: GetXY
            IF x < 0 THEN SYSTEM
        END IF
    LOOP
ELSE
    _SCREENMOVE 640, 0
    client = _OPENCLIENT("TCP/IP:7319:localhost") ' Attempt to connect to local host as a client
    DO
        GetXY
        CLS
        _PRINTSTRING (x - 640, y), "Steve is Amazing"
        _DISPLAY
        _LIMIT 30
        IF _EXIT THEN x = -1: y = -1: SendXY
        IF x < 0 THEN SYSTEM
    LOOP
END IF


SUB SendXY
    PUT #client, , x
    PUT #client, , y
END SUB

SUB GetXY
    GET #client, , x
    GET #client, , y
END SUB

Note that this is a little different than before.  Here, you just run this program and it'll handle making both screens and interacting with them.

Also notice that once you _EXIT from one screen, it'll also automatically exit from the other screen as well. 

Two screens, working together for one program, and both ending at the same time. 

It this *isn't* a "multi-screen" program, I don't know what the heck it might actually be classified as.  Tongue


RE: Multiscreen program - Pete - 07-12-2024

Okay, now that Biden is done ****ing in his big boy pants, here is what I put together a few years back involving two screen communication over tcp/ip...

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_lm.exe") THEN PRINT "Cannot find file: messenger_client_LM.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_lm.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

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


To get it to work, compile the second one as: Messenger_Client_LM.exe

Next, SAVE and RUN the first one as: Messenger_Host_LM.exe

Type a message in the host and press Enter to send it. It will appear in the client, which will then prompt you to make a reply.

Note: It uses _SCREENCLICK for focus, so don't move the windows. If anyone knows a better API focus method, that actually works in practice, that would be nice. 

Pete


RE: Multiscreen program - SMcNeill - 07-12-2024

Aye.  You see a lot of programs like this -- any chat server/client, or any multiplayer game works in this manner.  One program hosts; one program is the client.  You're right -- it's very similar to what I'm doing here.  The only real difference is I'm letting one program do both things for us, so it's BOTH the client and the host, and the host is doing all the actual work and calculations while the client has a much smaller area of responsibility.

Where do I see something like this perhaps being useful?

Mainly for folks who may want to create custom pop-up windows, similar to our _MESSAGEBOX or _INPUTBOX and  such.  

Structure your main program so it can handle command line instructions.   When you need a custom pop-up, SHELL Command$(0) with the proper parameter, and start a second instance of your program which uses that to create the pop-up for you.  Let both programs communicate back and forth, until the pop-up is finished, then close it and return control back to the main program.

I think that's about the main thing I'd use it for, I guess. Wink


RE: Multiscreen program - TempodiBasic - 07-14-2024

Hi Steve
it is a wonderful example!

Here the resut that I've got at its first run.

[Image: immagine-2024-07-14-090948782.png]

It shows an Y-order pass through the two applications.


I was thinking how modify the code to get an  One Y ordered scale to pass through the two applications.
This may need the absolute Y cohordinates of the text that goes through.