Posts: 2,695
Threads: 326
Joined: Apr 2022
Reputation:
217
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.
Posts: 184
Threads: 22
Joined: Mar 2023
Reputation:
12
Very cool! It (they) ran with no issues on my Mac. More dark magic from the Amazing Foo.
Posts: 2,695
Threads: 326
Joined: Apr 2022
Reputation:
217
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.
Posts: 2,158
Threads: 222
Joined: Apr 2022
Reputation:
102
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
Posts: 2,695
Threads: 326
Joined: Apr 2022
Reputation:
217
07-12-2024, 07:12 AM
(This post was last modified: 07-15-2024, 09:45 AM by SMcNeill.)
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.
Posts: 344
Threads: 24
Joined: Jul 2022
Reputation:
20
Hi Steve
it is a wonderful example!
Here the resut that I've got at its first run.
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.
|