Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations dencom on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

VFP Chat Client 1

Status
Not open for further replies.

craigsboyd

IS-IT--Management
Nov 9, 2002
2,839
US
I'm working on an alternate way for IT personnel to send messages around to the users of my networked applications. Something of a "IT is about to perform maintenance on the system. Please shutdown the application". Now I already have it so they can just send an alert and it pops up on the users' machines via the messagebox. But what I'm thinking is that a 2-way chat would be more useful. Anyone got experience with UDP and VFP or have a good example of a VFP chat program with code? Any help is appreciated.

Slighthaze = NULL
 
Hi Slighthaze,

Imagination is the answer... I have done that, but did not use it heavily. The concept is very simple.

I have posted an FAQ as to how we can call for a forced application shutdown for data maintenance. The same post, indicates how we can pass on the message or the duration of waiting time allowed. A similar concept is extended here..

1. Have a table with fields..
user1, user2, message1 (memo), message2 (memo field).
2. Add these in a form with a timer class and keep updating the messages1 in the memo and reading the messages2 for user1 terminal... and the other way in users2 terminal.

3. To start the conversation, keep firing a timer checking for User2 name = login name.. so that we can ffind the name in user1 field to know who is calling user2.

But this takes a bit of timer load and resulting performance downgrade.

:)

ramani :)
(Subramanian.G),FoxAcc, ramani_g@yahoo.com

 
Ramani,

Thank you for your reply. I should have been more specific in my question. What you propose is very similar to what I have now, I add a timer class to _screen when application opens and check every 10 seconds for any alert message. What I would really like to do is setup a two-way conversation using UDP and forego the timer class. I will probably end up using winsock but I thought I might post here first and see if anyone has some code or example for jump start.

Slighthaze = NULL
 
Ok Well, this is what I came up with - UDP chat in VFP via Winsock OCX, had to modify it a little so it would work on same machine, wanted to give a working example here of UDP chat in VFP, nothing to it really...cut-n-paste the code below into prg file and run it. I am assuming that the MS Winsock ocx is registered on your machine.

PUBLIC oForm, oForm2

oForm = CREATEOBJECT("clsChat",1)
oForm.visible = .t.

oForm2 = CREATEOBJECT("clsChat",2)
oForm2.visible = .t.

READ EVENTS

DEFINE CLASS clschat AS form


Top = 0
Left = 0
Height = 268
Width = 376
DoCreate = .T.
Caption = "VFP CHAT"
Name = "clschat"


ADD OBJECT txtchatname AS textbox WITH ;
Height = 23, ;
Left = 216, ;
Top = 12, ;
Width = 132, ;
Name = "txtChatname"

ADD OBJECT edtchat AS editbox WITH ;
Height = 134, ;
Left = 24, ;
ReadOnly = .T., ;
Top = 48, ;
Width = 324, ;
DisabledBackColor = RGB(255,255,255), ;
DisabledForeColor = RGB(0,0,0), ;
Name = "edtChat"

ADD OBJECT txtmessage AS textbox WITH ;
Height = 23, ;
Left = 84, ;
Top = 194, ;
Width = 264, ;
Name = "txtMessage"

ADD OBJECT command1 AS commandbutton WITH ;
Top = 221, ;
Left = 298, ;
Height = 25, ;
Width = 50, ;
Caption = "Send", ;
Name = "Command1"


ADD OBJECT winsock1 AS WSControl

ADD OBJECT label2 AS label WITH ;
AutoSize = .T., ;
BackStyle = 0, ;
Caption = "MESSAGE", ;
Height = 17, ;
Left = 24, ;
Top = 197, ;
Width = 59, ;
Name = "Label2"

ADD OBJECT label1 AS label WITH ;
AutoSize = .T., ;
BackStyle = 0, ;
Caption = "CHAT NAME", ;
Height = 17, ;
Left = 144, ;
Top = 15, ;
Width = 70, ;
Name = "Label1"


PROCEDURE Init
LPARAMETERS plForm
IF plform = 1
thisform.winsock1.object.bind(1234)
thisform.txtChatname.value = "likestochat"
ELSE
thisform.winsock1.object.bind(1235)
thisform.txtChatname.value = "sirchatalot"
thisform.AutoCenter = .t. &&So they don't overlap
ENDIF
thisform.txtMessage.setfocus()
ENDPROC


PROCEDURE Unload
CLEAR events
ENDPROC

PROCEDURE txtmessage.KeyPress
LPARAMETERS nKeyCode, nShiftAltCtrl
IF nKeycode = 13 AND nShiftAltCtrl = 0
IF !EMPTY(thisform.txtMessage.value)
thisform.command1.Click()
ENDIF
ENDIF
ENDPROC

PROCEDURE command1.Click
LOCAL sChatName, sMessageSent
WITH thisform
sChatName = ALLTRIM(thisform.txtChatname.value)
sMessageSent = sChatName +" says: " + ALLTRIM(thisform.txtMessage.value)
WITH .winsock1.object
.RemotePort = 1235
.RemoteHost = "127.0.0.1"
.SendData(sMessageSent)
.RemotePort = 1234
.RemoteHost = "127.0.0.1"
.SendData(sMessageSent)
ENDWITH
.txtMessage.value = ""
endwith
ENDPROC

ENDDEFINE

Define Class WSControl As OleControl
OleClass='MSWinsock.Winsock.1'
Top = 228
Left = 24
Height = 100
Width = 100
Name = "winsock1"

PROCEDURE Init
this.object.Protocol = 1
ENDPROC

PROCEDURE DataArrival
LPARAMETERS bytestotal
sMessage = SPACE(bytestotal)
thisform.winsock1.object.GetData(@sMessage)
thisform.edtChat.Value = thisform.edtChat.Value + sMessage + CHR(13)
ENDPROC

Enddefine


***Now who's gonna add the emoticons? LOL
***Honestly though I would like to get it working with ***winsock.dll and ditch the ocx

Slighthaze = NULL
 
Hi slighthaze,

I modified your code a little so it can work two way. But I only test it in two instance of EXE, cause I don't have network here.

I'll post it if you still interested
Regards

-- AirCon --
 
AirCon,

...modified your code a little so it can work two way...

Yes, I am still interested. Please post here.

Slighthaze = NULL
 
You can find some examples of sending an SMTP email using SMTP here:
One example uses the WinSock.OCX, the other uses the WinSock.DLL ... You should be able to adapt the SMTP code to do chat instead.

(ps, I have a TCP chat component under development that not only does chat, but also, effectively, does remote control of the VFP program running on a customer's machine; When it's done, I expect it will make our tech-support burden a little lighter. The Techie can issue any one-line VFP command, get a screen shot, get or put a file. Any command sent preceeded by a "?" has it's result returned and displayed to the techie.
Because of the extensive control it offers the server of the client's machine, the chat can only be initiated by the client: ie: no ports are held open on the client until the customer requests tech-support help.)
 
slighthaze,
Here is the code. Create a new project and compile this to an exe
Code:
PUBLIC oForm, oForm2

Local lnPortNo, lcPortNo, lnCount

Set exclusive off
Set multilocks on
Set deleted on
Set refresh to 1,1

_VFP.Visible = .F.

If !file('ChatPort.dbf')
   Create table ChatPort (PortNo C(10), IPAddress C(20))
   Index on PortNo tag PortNo
endif
Use ChatPort order PortNo
CursorSetProp('Buffering', 5)

lnPortNo = 1000
Count for !deleted()
If (_tally > 0)
   Go bottom
   lnPortNo = int(val(PortNo) + 1)
endif
lcPortNo = alltrim(str(lnPortNo))

Insert into ChatPort (PortNo) Values (lcPortNo)
TableUpdate(0, .T.)

Set order to
oForm = CREATEOBJECT("clsChat", lnPortNo)
oForm.visible = .t.
Read events

Go top
Scan for (alltrim(PortNo) == lcPortNo)
   Delete
EndScan
TableUpdate(1, .T.)
Store Null to oForm, oForm2
Release oForm, oForm2

Count for !deleted()
Close databases all
If (_tally == 0)
   Erase ChatPort.*
endif

Clear all
Close all


DEFINE CLASS clschat AS form

   Top = 0
   Left = 0
   Height = 268
   Width = 376
   DoCreate = .T.
   Caption = "VFP CHAT"
   Name = "clschat"
   ShowWindow = 2

   ADD OBJECT txtchatname AS textbox WITH ;
      Height = 23, ;
      Left = 216, ;
      Top = 12, ;
      Width = 132, ;
      Name = "txtChatname"

   ADD OBJECT edtchat AS editbox WITH ;
      Height = 134, ;
      Left = 24, ;
      ReadOnly = .T., ;
      Top = 48, ;
      Width = 324, ;
      DisabledBackColor = RGB(255,255,255), ;
      DisabledForeColor = RGB(0,0,0), ;
      Name = "edtChat"

   ADD OBJECT txtmessage AS textbox WITH ;
      Height = 23, ;
      Left = 84, ;
      Top = 194, ;
      Width = 264, ;
      Name = "txtMessage"

   ADD OBJECT command1 AS commandbutton WITH ;
      Top = 221, ;
      Left = 298, ;
      Height = 25, ;
      Width = 50, ;
      Caption = "Send", ;
      Name = "Command1"

   ADD OBJECT winsock1 AS WSControl

   ADD OBJECT label2 AS label WITH ;
      AutoSize = .T., ;
      BackStyle = 0, ;
      Caption = "MESSAGE", ;
      Height = 17, ;
      Left = 24, ;
      Top = 197, ;
      Width = 59, ;
      Name = "Label2"

   ADD OBJECT label1 AS label WITH ;
      AutoSize = .T., ;
      BackStyle = 0, ;
      Caption = "CHAT NAME", ;
      Height = 17, ;
      Left = 144, ;
      Top = 15, ;
      Width = 70, ;
      Name = "Label1"


   PROCEDURE Init
   LPARAMETERS tnPortNo
      With ThisForm
         .winsock1.object.bind(tnPortNo)
         Replace IPAddress with .winsock1.LocalIP
         TableUpdate(0, .T.)
         .txtchatname.value = "Chat Port#: " + alltrim(str(.winsock1.LocalPort))
         .txtmessage.setfocus()
      EndWith
   EndProc


   Procedure Destroy
      ThisForm.RemoveObject('WinSock1')
   EndProc

   PROCEDURE Unload
      CLEAR events
   EndProc

   PROCEDURE txtmessage.KeyPress
   LPARAMETERS nKeyCode, nShiftAltCtrl
      IF nKeyCode = 13 AND nShiftAltCtrl = 0
         IF !EMPTY(thisform.txtmessage.value)
            thisform.command1.Click()
         ENDIF
      ENDIF
   EndProc

   PROCEDURE command1.Click
   LOCAL sChatName, sMessageSent, lnPort

      WITH thisform
         sChatName = ALLTRIM(thisform.txtchatname.value)
         sMessageSent = sChatName +" says:   " + ALLTRIM(thisform.txtmessage.value)
         WITH .winsock1.object
            Go top
            Scan while !eof()
               .RemotePort = int(val(PortNo))
               .RemoteHost = IPAddress
               .SendData(sMessageSent)
            EndScan
         ENDWITH
         .txtmessage.value = ""
         .txtmessage.setfocus()
      EndWith
   EndProc
EndDefine

Define Class WSControl As OleControl
   OleClass='MSWinsock.Winsock.1'
   Top = 228
   Left = 24
   Height = 100
   Width = 100
   Name = "winsock1"

   PROCEDURE Init
      this.object.Protocol = 1
   EndProc

   Procedure Error(nError, cMethod, nLine)
      If (nError == 1429)
         Delete
         TableUpdate(0, .T.)
      endif
   EndProc

   PROCEDURE DataArrival
   LPARAMETERS bytestotal
      sMessage = SPACE(bytestotal)
      With ThisForm
         .winsock1.object.GetData(@sMessage)
         .edtchat.Value = .edtchat.Value + sMessage + CHR(13)
         .edtchat.refresh()
         .edtchat.SelStart = len(alltrim(.edtchat.Value))
      EndWith
   EndProc
EndDefine
Let me know how it works :)
Regards

-- AirCon --
 
Aircon,

My apologies for the very long delay. I finally got around to looking at this. I'm not exactly sure I understand it. There is a oform2 that is never used and I only see the one chat window oForm1...I had thought that when I ran it I would see two chat windows open up and that I would be able to communicate between them on my local machine, I must be wrong in my thinking on this. Also, port 1000 was a bad pick for my machine since there were ports being used near that number...had to switch that to get it up and running. I think this program would make a nice FAQ, but I think we need to refine a few things and get a good working example that anyone could run from a prg inside VFP or as a compiled exe as you have suggested. Could you get back to me on this?

Slighthaze = NULL
 
Slighthaze

I'd forgot a little about this. You could run it in two instances or more, to simulate users. Each of instances can interact each other.


-- AirCon --
 
Works like a charm Aircon. Definately worth a star and please create a FAQ on it...explain about running a couple of instances or make it so the program bring up two instances (ShellExecute maybe?) or two forms.

Slighthaze = NULL
 
Thanks for the star Slighthaze :)

But it is your code at first. I just made a modification to your code. Also I'm not good in explaining and I don't think can make a good FAQ (my english is not good either). You can go ahead to make an FAQ for this

Regards

-- AirCon --
 
Btw, if you need any help, I will be ready (I hope)

Regards

-- AirCon --
 
Ok. I'm thinking it should be able to run as an example on a member's workstation or as an actual chat client...would have to set up a chat server of sorts at this end but shouldn't be too much work to create a relay system of sorts...when I get some time I'll mess around with it and see what I can come up with.

Slighthaze = NULL
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top