KDKephart


I'm an old Clipper (S' 87) programmer that needs to figure out forms with VFP. The attached code generates a form containing a set of four optiongroups that set basic comm port parameters on the local host for serial communication with an instrument (usually an electronic balance). I'm trying to use the form to replace a series of cascading menus in the original program. My intent is for the form to recognize the 5 existing parameters in the main prg, permit user input and then pass any changes back to the calling procedure or function using a array embedded in the form when the user clicks [OK]. Clicking [Cancel] should leave the parameters unchanged. Can somebody please suggest a technique for passing multiple variables back and forth between forms and calling procedures

*/ COMM_OPTIONS.PRG - Defines Comm Port Parameters on Local Machine /*
*/ Variable declarations copied from main PRG file. Values restored from .CFG file. /*

private m.CommPort, m.BaudRate, m.Parity, m.ByteLength, m.Stopbit, m.X
dimension m.X[5]

m.CommPort = 1
m.BaudRate = 5
m.Parity = 0
m.ByteLength = 7
m.StopBit = 0

*/ Form coding begins here /*

m.X = testform()

for i = 1 to 5
xIdea
next

cancel

function testform

frmMyForm = CREATEOBJECT('Form') && Create a Form

with frmMyForm

.Closable = .T. && Disable the Control menu box
.windowtype = 1 && Makes popup screen modal
.alwaysontop = .T. && Make option form remain on top
.autocenter = .T.
.width = 530
.height = 220
.backcolor = rgb(239,239,239)
.titlebar = 1
.caption = "EBU32 Serial Port Settings"
.borderstyle = 3

.AddObject('frmText1','hLabel1') && Column text headers
.AddObject('frmText2','hLabel2')
.AddObject('frmText3','hLabel3')
.AddObject('frmText4','hLabel4')

.AddObject('frmOpGrp1','OptionGroup1') && Comm Port Buttons
.AddObject('frmOpGrp2','OptionGroup2') && Baud Rate Buttons
.AddObject('frmOpGrp3','OptionGroup3') && Parity Buttons
.AddObject('frmOpGrp4','OptionGroup4') && Byte/Stop Buttons

.AddObject('frmCmdOK','MyCmndBtn1') && OK button
.AddObject('frmCmdCancel','MyCmndBtn2') && Cancel button

* if .addproperty('cpVal[5]') && declares array to input existing parameter values
* .cpVal[1] = m.CommPort
* .cpVal[2] = m.BaudRate
* .cpVal[3] = m.Parity
* .cpVal[4] = m.Bytelength
* .cpVal[5] = m.StopBit
* endif

if .addproperty('rtnVal[5]') && declares array for return values
endif

endwith

frmMyForm.SHOW() && Display the form
READ EVENTS && Start event processing

endfunc

define class hLabel1 as label && Header caption for comm port buttons
top = 10
left = 20
caption = 'Ports'
backcolor = rgb(239,239,239)
forecolor = rgb(0,51,102)
fontsize = 12
fontbold = .T.
fontname = 'Arial'
autosize = .T.
visible = .T.
enddefine

define class hLabel2 as label && Header caption for baud rate buttons
top = 10
left = 140
caption = 'Baud'
backcolor = rgb(239,239,239)
forecolor = rgb(0,51,102)
fontsize = 12
fontbold = .T.
fontname = 'Arial'
autosize = .T.
visible = .T.
enddefine

define class hLabel3 as label && Header caption for parity buttons
top = 10
left = 250
caption = 'Parity'
backcolor = rgb(239,239,239)
forecolor = rgb(0,51,102)
fontsize = 12
fontbold = .T.
fontname = 'Arial'
autosize = .T.
visible = .T.
enddefine

define class hLabel4 as label && Header caption for bytelength/stopbit buttons
top = 10
left = 350
caption = 'Byte Length'
backcolor = rgb(239,239,239)
forecolor = rgb(0,51,102)
fontsize = 12
fontbold = .T.
fontname = 'Arial'
autosize = .T.
visible = .T.
enddefine

define class OptionGroup1 as optiongroup && Comm port buttons group

ButtonCount = 4
Top = 30
Left = 20
Height = 120
Width = 100
Backcolor = rgb(239,239,239)
value = m.CommPort + 1
borderstyle = 0
visible = .T.
Name = "Optiongroup1"

Option1.Caption = "Comm1"
Option1.Top = 0
Option1.Left = 0
Option1.Height = 30
Option1.Width = 100
Option1.backcolor = rgb(239,239,239)
Option1.forecolor = rgb(0,51,102)
Option1.fontsize = 12
Option1.fontbold = .T.
Option1.fontname = 'Arial'
Option1.tabstop = .F.
Option1.Name = "Option1"

Option2.Caption = "Comm2"
Option2.Top = 30
Option2.Left = 0
Option2.Height = 30
Option2.Width = 100
Option2.backcolor = rgb(239,239,239)
Option2.forecolor = rgb(0,51,102)
Option2.fontsize = 12
Option2.fontbold = .T.
Option2.fontname = 'Arial'
Option2.tabstop = .F.
Option2.Name = "Option2"

Option3.Caption = "Comm3"
Option3.Top = 60
Option3.Left = 0
Option3.Height = 30
Option3.Width = 100
Option3.backcolor = rgb(239,239,239)
Option3.forecolor = rgb(0,51,102)
Option3.fontsize = 12
Option3.fontbold = .T.
Option3.fontname = 'Arial'
Option3.tabstop = .F.
Option3.Name = "Option3"

Option4.Caption = "Comm4"
Option4.Top = 90
Option4.Left = 0
Option4.Height = 30
Option4.Width = 100
Option4.backcolor = rgb(239,239,239)
Option4.forecolor = rgb(0,51,102)
Option4.fontsize = 12
Option4.fontbold = .T.
Option4.fontname = 'Arial'
Option4.tabstop = .F.
Option4.Name = "Option4"

procedure init
with thisform
endwith
ENDPROC

procedure click
with thisform
endwith
endproc

procedure interactivechange
with thisform
endwith
endproc

enddefine



define class OptionGroup2 as optiongroup && Baud rate buttons group

ButtonCount = 6
Top = 30
Left = 140
Height = 180
Width = 70
Backcolor = rgb(239,239,239)
value = m.BaudRate
borderstyle = 0
visible = .T.
Name = "Optiongroup2"

Option1.Caption = "300"
Option1.Top = 0
Option1.Left = 0
Option1.Height = 30
Option1.Width = 70
Option1.backcolor = rgb(239,239,239)
Option1.forecolor = rgb(0,51,102)
Option1.fontsize = 12
Option1.fontbold = .T.
Option1.fontname = 'Arial'
Option1.tabstop = .F.
Option1.Name = "Option1"

Option2.Caption = "1200"
Option2.Top = 30
Option2.Left = 0
Option2.Height = 30
Option2.Width = 70
Option2.backcolor = rgb(239,239,239)
Option2.forecolor = rgb(0,51,102)
Option2.fontsize = 12
Option2.fontbold = .T.
Option2.fontname = 'Arial'
Option2.tabstop = .F.
Option2.Name = "Option2"

Option3.Caption = "2400"
Option3.Top = 60
Option3.Left = 0
Option3.Height = 30
Option3.Width = 70
Option3.backcolor = rgb(239,239,239)
Option3.forecolor = rgb(0,51,102)
Option3.fontsize = 12
Option3.fontbold = .T.
Option3.fontname = 'Arial'
Option3.tabstop = .F.
Option3.Name = "Option3"

Option4.Caption = "4800"
Option4.Top = 90
Option4.Left = 0
Option4.Height = 30
Option4.Width = 70
Option4.backcolor = rgb(239,239,239)
Option4.forecolor = rgb(0,51,102)
Option4.fontsize = 12
Option4.fontbold = .T.
Option4.fontname = 'Arial'
Option4.tabstop = .F.
Option4.Name = "Option4"

Option5.Caption = "9600"
Option5.Top = 120
Option5.Left = 0
Option5.Height = 30
Option5.Width = 70
Option5.backcolor = rgb(239,239,239)
Option5.forecolor = rgb(0,51,102)
Option5.fontsize = 12
Option5.fontbold = .T.
Option5.fontname = 'Arial'
Option5.tabstop = .F.
Option5.Name = "Option5"

Option6.Caption = "19200"
Option6.Top = 150
Option6.Left = 0
Option6.Height = 30
Option6.Width = 70
Option6.backcolor = rgb(239,239,239)
Option6.forecolor = rgb(0,51,102)
Option6.fontsize = 12
Option6.fontbold = .T.
Option6.fontname = 'Arial'
Option6.tabstop = .F.
Option6.Name = "Option6"

procedure init
with thisform
endwith
ENDPROC

procedure click
with thisform
endwith
endproc

procedure interactivechange
with thisform
endwith
endproc

enddefine

define class OptionGroup3 as optiongroup && Parity buttons group

ButtonCount = 3
Top = 30
Left = 250
Height = 90
Width = 70
Backcolor = rgb(239,239,239)
value = m.Parity + 1
borderstyle = 0
visible = .T.
Name = "Optiongroup3"

Option1.Caption = "None"
Option1.Top = 0
Option1.Left = 0
Option1.Height = 30
Option1.Width = 70
Option1.backcolor = rgb(239,239,239)
Option1.forecolor = rgb(0,51,102)
Option1.fontsize = 12
Option1.fontbold = .T.
Option1.fontname = 'Arial'
Option1.tabstop = .F.
Option1.Name = "Option1"

Option2.Caption = "Odd"
Option2.Top = 30
Option2.Left = 0
Option2.Height = 30
Option2.Width = 70
Option2.backcolor = rgb(239,239,239)
Option2.forecolor = rgb(0,51,102)
Option2.fontsize = 12
Option2.fontbold = .T.
Option2.fontname = 'Arial'
Option2.tabstop = .F.
Option2.Name = "Option2"

Option3.Caption = "Even"
Option3.Top = 60
Option3.Left = 0
Option3.Height = 30
Option3.Width = 70
Option3.backcolor = rgb(239,239,239)
Option3.forecolor = rgb(0,51,102)
Option3.fontsize = 12
Option3.fontbold = .T.
Option3.fontname = 'Arial'
Option3.tabstop = .F.
Option3.Name = "Option3"

procedure init
with thisform
endwith
ENDPROC

procedure click
with thisform
endwith
endproc

procedure interactivechange
with thisform
endwith
endproc

enddefine

define class OptionGroup4 as optiongroup && Byte length/stop bits buttons group

ButtonCount = 3
Top = 30
Left = 350
Height = 90
Width = 160
Backcolor = rgb(239,239,239)
value = iif(m.ByteLength = 8, 1, iif(m.StopBit = 2, 3, 2))
borderstyle = 0
visible = .T.
Name = "Optiongroup4"

Option1.Caption = "8 bit byte/1 stop bit"
Option1.Top = 0
Option1.Left = 0
Option1.Height = 30
Option1.Width = 160
Option1.backcolor = rgb(239,239,239)
Option1.forecolor = rgb(0,51,102)
Option1.fontsize = 12
Option1.fontbold = .T.
Option1.fontname = 'Arial'
Option1.tabstop = .F.
Option1.Name = "Option1"

Option2.Caption = "7 bit byte/1 stop bit"
Option2.Top = 30
Option2.Left = 0
Option2.Height = 30
Option2.Width = 160
Option2.backcolor = rgb(239,239,239)
Option2.forecolor = rgb(0,51,102)
Option2.fontsize = 12
Option2.fontbold = .T.
Option2.fontname = 'Arial'
Option2.tabstop = .F.
Option2.Name = "Option2"

Option3.Caption = "7 bit byte/2 stop bit"
Option3.Top = 60
Option3.Left = 0
Option3.Height = 30
Option3.Width = 160
Option3.backcolor = rgb(239,239,239)
Option3.forecolor = rgb(0,51,102)
Option3.fontsize = 12
Option3.fontbold = .T.
Option3.fontname = 'Arial'
Option3.tabstop = .F.
Option3.Name = "Option3"

procedure init
with thisform
endwith
ENDPROC

procedure click
with thisform
endwith
endproc

procedure interactivechange
with thisform
endwith
endproc

enddefine

define class MyCmndBtn1 as commandbutton && Create OK command button
Caption = '\<OK' && Caption on the Command button
Left = 315 && Command button column
Top = 150 && Command button row
Height = 24 && Command button height
width = 48
Visible = .T.


procedure click

with thisform

.rtnVal[1] = .frmOpGrp1.value - 1
.rtnVal[2] = .frmOpGrp2.value
.rtnVal[3] = .frmOpGrp3.value - 1
.rtnVal[4] = iif(.frmOpGrp4.value = 1, 8, 7)
.rtnVal[5] = iif(.frmOpGrp4.value = 3, 2, 1)

endwith

clear events && Stop event processing, close Form
thisform.release()

endproc

procedure unload

return thisform.rtnVal

endproc

enddefine

define class MyCmndBtn2 as commandbutton && Create Cancel command button
Caption = '\<Cancel' && Caption on the Command button
Cancel = .T. && Default Cancel Command button (Esc)
Left = 385 && Command button column
Top = 150 && Command button row
Height = 24 && Command button height
width = 48
Visible = .T.

procedure click
clear events && Stop event processing, close Form
thisform.release()
return .f.
endproc

enddefine




Re: Passing multiple variables from forms w/ VFP7SP1

AndyKr


You can pass parameters to the form's INIT() method. But parameters in a form are only visible to the method that receives them, so you should then transfer them to form properties... code like this will do it:

FUNCTION INIT( tcParam1, tcParam2, tcParam3, tcParam4, tcParam5 )

*** Repeat as needed....
IF NOT EMPTY(tcParam1 )
ThisForm.Addproperty( "Param1", tcParam1 )
ENDIF

Then any other code, in any object, can reference "ThisForm.Param1" and get or set it's value.

TO pass the parameteers, just attach to the DO FORM command:

DO FORM myForm WITH Value1, Value2......







Re: Passing multiple variables from forms w/ VFP7SP1

CetinBasoz

There are multiple ways to pass parameters and get return parameters. One of the ways is as you did by declaring them as private. However in an OO language like VFP you better forget that there are variable declarations other than local (only at one place and one variable commonly known as oApp application object is public). Language has other types allowed but consider local is the only one.

That said, for a moment forget it's about forms but passing and receiving parameters from a function. There are 2 problems:
1) Parameters you are allowed to pass is limited (27 according to documentation but I have never learned the actual limit).
2) You can only return a single variable.

However both problems are beaten with a single shot if you use what is commonly known as "parameter objects". An object is a variable so you can pass 27 of them and get back 1. And the good side of this is that an object could have numbers of (unlimited -never hit a limit) properties and one or more of those properties could be array properties (or even objects such as a chain of treeview objects). In other words a single variable could carry back and forth what memory allows.

In code it can be expressed as:

Local loParam,loResult
loParam =
Createobject("Empty")
AddProperty(loParam,"p1",1)
AddProperty(loParam,"p2",Date())
AddProperty(loParam,"p3","hello")
loResult = myProcedure(m.loParam)
loResult.Start,loResult.End,loResult.
Name

Procedure
myProcedure(toParm)
*...
Local loRet
loRet =
Createobject("Empty")
AddProperty(loRet,"start",toParm.p2-toParm.p1)
AddProperty(loRet,"end",toParm.p2)
AddProperty(loRet,"name",Upper(toParm.p3))
Return loRet
Endproc

Well Empty object and AddProperty() is available in VFP9 but that gives the idea. You could do the same with another object like custom and oCustom.AddProperty().

Now if correlate this with a form using, modal forms you could return an "loRet" variable that carries values as properties (only modal forms could return a value). It looks like:

local oParmToPass,oRet
* create and populate oParmToPass object
do form myModalForm with m.oParmToPass to m.oRet

However the called form actually need not to return anything if we had a reference to it and it's alive. We could directly get or set its members' properties (and/or call methods - public ones).

I want to show that approach with "your" form. I'll send that as another post to prevent crowd.

PS: In your form check that if you're correctly inializing the values. Sounded wrong to me. ie: CommPort=1 initialized as Comm2 (m.CommPort + 1).






Re: Passing multiple variables from forms w/ VFP7SP1

CetinBasoz

Here is modified version of your form:

clear
*/ COMM_OPTIONS.PRG - Defines Comm Port Parameters on Local Machine /*
*/ Variable declarations copied from main PRG file. Values restored from .CFG file. /*
LOCAL loPortSettings
loPortSettings = GetPortSettings()
"Commport via hardcoded property:", loPortSettings.CommPort && check via property name
* or dynamically check all properties
LOCAL ix
FOR ix = 1 TO AMEMBERS(aProps,loPortSettings)
aProps[m.ix]+ " is:", GETPEM(m.loPortSettings,aProps[m.ix])
endfor

FUNCTION GetPortSettings
Local oForm,loParm
Create Cursor parmCreator (CommPort l, BaudRate l, Parity l, ByteLength l, StopBit l)
Scatter Name loParm
Use In "parmCreator" && done with it
* load defaults to parameter object
loParm.CommPort = 1
loParm.BaudRate = 5
loParm.Parity = 0
loParm.ByteLength = 7
loParm.StopBit = 0

oForm = Createobject('myForm',loParm) && create form
oForm.Show(1) && Show as a modal form

*****
* Code would reach here when form's visiblity is false - hide(),visible=.f.,release()
*****
Local laRet[1]
*Since we didn't release but simply hide the form we still have access to it via its ref var
With oForm
Acopy(.rtnVal, laRet ) && copy array to a local array
* set values from form selected values
If !(.Tag == "CANCELLED") && check cancel flag
loParm.CommPort = .OptionGroup1.Value - 1
loParm.BaudRate = .OptionGroup2.Value
loParm.Parity = .OptionGroup3.Value - 1
loParm.ByteLength = Iif(.OptionGroup4.Value = 1, 8, 7)
loParm.StopBit = Iif(.OptionGroup4.Value = 3, 2, 1)
Endif
Endwith
*done with form release it
oForm.Release()
Release oForm && also its variable

* show array
LOCAL ix
FOR ix = 1 TO 5
"Array member:",m.ix,"Value:",laRet[m.ix]
ENDFOR
RETURN loParm && return settings to caller
endproc


Define Class myForm As Form
ControlBox = .T. && Disable the Control menu box
AlwaysOnTop = .T. && Make option form remain on top
AutoCenter = .T.
Width = 530
Height = 220
BackColor = Rgb(239,239,239)
Caption = "EBU32 Serial Port Settings"
Dimension rtnVal[5] && don't really need this - showing possibilities only

&& Header caption for comm port buttons
Add Object hLabel1 As Label With Top = 10, Left = 20, Caption = 'Ports'
&& Header caption for baud rate buttons
Add Object hLabel2 As Label With Top = 10, Left = 140, Caption = 'Baud'
&& Header caption for parity buttons
Add Object hLabel3 As Label With Top = 10, Left = 250, Caption = 'Parity'
&& Header caption for bytelength/stopbit buttons
Add Object hLabel4 As Label With Top = 10, Left = 350, Caption = 'Byte Length'
&& Comm port buttons group - Value = m.CommPort + 1
Add Object OptionGroup1 As OptionGroup With ;
ButtonCount = 4, Top = 30, Left = 20, AutoSize = .T.,;
BackColor = Rgb(239,239,239),BorderStyle = 0,;
Option1.Caption = "Comm1", Option1.Top = 0,;
Option2.Caption = "Comm2", Option2.Top = 30,;
Option3.Caption = "Comm3", Option3.Top = 60,;
Option4.Caption = "Comm4", Option4.Top = 90
&& Baud rate buttons group - Value = m.BaudRate
Add Object OptionGroup2 As OptionGroup With ;
ButtonCount = 6, Top = 30, Left = 140, AutoSize = .T.,;
BackColor = Rgb(239,239,239),BorderStyle = 0,;
Option1.Caption = "300", Option1.Top = 0,;
Option2.Caption = "1200", Option2.Top = 30,;
Option3.Caption = "2400", Option3.Top = 60,;
Option4.Caption = "4800", Option4.Top = 90,;
Option5.Caption = "9600", Option5.Top = 120,;
Option6.Caption = "19200", Option6.Top = 150
&& Parity buttons group - Value = m.Parity + 1
Add Object OptionGroup3 As OptionGroup With ;
ButtonCount = 3, Top = 30, Left = 250, AutoSize = .T.,;
BackColor = Rgb(239,239,239),BorderStyle = 0,;
Option1.Caption = "None", Option1.Top = 0,;
Option2.Caption = "Odd", Option2.Top = 30,;
Option3.Caption = "Even", Option3.Top = 60
&& Byte length/stop bits buttons group
*Value = Iif(m.ByteLength = 8, 1, Iif(m.Stopbit = 2, 3, 2))
Add Object OptionGroup4 As OptionGroup With ;
ButtonCount = 3, Top = 30, Left = 350, AutoSize = .T.,;
BackColor = Rgb(239,239,239),BorderStyle = 0,;
Option1.Caption = "8 bit byte/1 stop bit", Option1.Top = 0,;
Option2.Caption = "7 bit byte/1 stop bit", Option2.Top = 30,;
Option3.Caption = "7 bit byte/2 stop bit", Option3.Top = 60
&& Create OK command button
Add Object MyCmndBtn1 As CommandButton With ;
Caption = '\<OK', Left = 315, Top = 150, Height = 24, Width = 48
&& Create Cancel command button
Add Object MyCmndBtn2 As CommandButton With ;
Caption = '\<Cancel', Cancel = .T., Left = 385, Top = 150, Height = 24,Width = 48

Procedure Init
Lparameters toParm
With This
.SetAll("Height",30,"OptionButton")
.SetAll("Width",100,"OptionButton")
.SetAll("BackColor",Rgb(239,239,239),"OptionButton")
.SetAll("BackColor",Rgb(239,239,239),"Label")
.SetAll("ForeColor",Rgb(0,51,102),"OptionButton")
.SetAll("ForeColor",Rgb(0,51,102),"Label")
.SetAll("FontSize",12,"OptionButton")
.SetAll("FontSize",12,"Label")
.SetAll("FontBold",.T.,"OptionButton")
.SetAll("FontBold",.T.,"Label")
.SetAll("FontName",'Arial',"OptionButton")
.SetAll("FontName",'Arial',"Label")
.SetAll("TabStop",.F.,"OptionButton")
.SetAll("Autosize",.T.,"Label")
* Set values based on based parameters
.OptionGroup1.Value = toParm.CommPort + 1
.OptionGroup2.Value = toParm.BaudRate
.OptionGroup3.Value = toParm.Parity + 1
.OptionGroup4.Value = Iif(toParm.ByteLength = 8, 1, Iif(toParm.StopBit = 2, 3, 2))
Endwith
Endproc

Procedure MyCmndBtn1.Click
With Thisform
.rtnVal[1] = .OptionGroup1.Value - 1
.rtnVal[2] = .OptionGroup2.Value
.rtnVal[3] = .OptionGroup3.Value - 1
.rtnVal[4] = Iif(.OptionGroup4.Value = 1, 8, 7)
.rtnVal[5] = Iif(.OptionGroup4.Value = 3, 2, 1)
* close Form
.Hide()
Endwith
Endproc

Procedure MyCmndBtn2.Click
* close Form
Thisform.Hide()
Thisform.Tag = "CANCELLED" && set a flag
Endproc
Enddefine





Re: Passing multiple variables from forms w/ VFP7SP1

KDKephart

Andy & Cetin - Thank you both for the reply. I'm still digesting your suggestions and will respond again after I see Cetin's modifications to my code, and have had time to work with suggestions from both of you. I wished to address the concern over the CommPort variable coding scheme. I'm using MarshallSoft's serial communication library for VFP. The convention required to identify ports is an integer of n-1. In other words, to use Comm1 the program has to pass "0" as an integer, Comm2 has to pass "1", and so on. In other parts of the code I display a string indentifing the Comm port in use with "Comm"+str(m.CommPort+1,1,0). Similar issue with the parity and the number of stop bits. Two stop bits are identified by the integer "2", yet one stop bit requires "0". Baud rates are used actual baud numbers, but I translate into integers reflecting the radio button that represents the current setting. Actually, any advice or solution to more directly handle this sort of input would be most welcome.

I use private variables because I use the old "save to"/"restore from" commands to save and retreive program settings in between sessions.

Ken





Re: Passing multiple variables from forms w/ VFP7SP1

KDKephart

Andy and Cetin - Thank you both for replying. I plan on responding after I receive the modified code of my script from Cetin, and have had time to work with the suggestions that both of you provided. For years I've used VFP to write short scripts for data management, but I am a newbie regarding object orient programing with VFP. I'm still trying to figure the main difference in creating forms with the 'createobject('form')' method vs 'define class as form' approach. I did wish to address the concerns regarding the Comm port coding scheme used.

I'm using MarshalSoft's serial communication library for VFP. The convention used by the library to identify ports uses a integer of n-1. In other words, to use Comm1 the program has to pass the integer "0" to the DLL function, "1" for Comm2 and so on. Same or similar situation for parity and stop bits. Stop bits are more challenging, 2 bits requiring passing the integer "2" but 1 stop bit requires "0". Baud rate are passed as actual values (e.g. 19200, 9600, 4800, etc). I translate the baud rate to intergers in order to associate with the radio button that reflects the current setting to the user.

Yes, I make use of private variables, particular those I plan to save in a .cfg or .ini file to recall settings in between sessions. I use the old "save to"/"restore from" commands to accomplish this, but I always do so inside a main or master procedure that forms the main program loop. I do try to use local variables inside sub-procedures by declaration or lparameters where ever possible. It's not perfect, but I don't how to handle the situation differently.

Actually, any advice you may have to improve the function of this form will be most welcome, including different coding schemes.

Ken





Re: Passing multiple variables from forms w/ VFP7SP1

KDKephart

Cetin - What can I say but thank you. The script does exactly what I want it to do. There are several VFP functions and programing techniques you've used that I need to study up on, particularly on the top end of the script where you set up the parameter object. I actually tried to use the setAll method on some of my scripts to reduce the code, but kept getting errors.

I apologize for the double responses to your first message. When posted, I received a "WebPageError" message and wasn't sure it went through. I retyped and sent again.

Ken





Re: Passing multiple variables from forms w/ VFP7SP1

KDKephart

Andy - Another MVP has responded and rewrote me script to show me the solution. I did want to thank you for responding and to say that I recognized your name from a posting on another forum that inspired me to attempt this approach. Again, thanks.

Ken





Re: Passing multiple variables from forms w/ VFP7SP1

CetinBasoz

You're welcome. Don't worry we get that web page error often and know the pain:)

There is nothing special abut setting the parameter object. It's an old trick I have been using for years. In VFP9 there is "Empty" object and supporting addproperty() function. So you can do:

o = CreateObject("Empty")
Addproperty(o, "CommPort", 1)
AddProperty(o, "Parity"', 0)

etc. and resulting object o has only 2 properties on it. In VFP3/5...7 there weren't such an object and furthermore VFP5 and prior didn't have AddProperty method on objects (now many like form,custom,line ...) have it. Either you needed a C FLL to do the job or old Indian tricks as such.

use customer
scatter name loCustomer

creates an loCustomer object where fields become a property and sets property values to current record's content.

loCustomer.Company && is practically same as saying customer.Company but loCustomer is a variable I can pass.

So to utilize this I create a temp cursor with field (property) names I want, scatter to name and dismiss cursor. Datatypes are not important as once I have it I'm free to set any property to any value.





Re: Passing multiple variables from forms w/ VFP7SP1

KDKephart

I appreciate the insights on using VFP 9 for this purpose. Given this successful experience, I've contacted my IT support person to obtain the upgrade. I do have one problem with your modified version of the code I need to address and one question concerning your methods used.

I discovered that when you click on the close window button of the form (not the cancel button), a series of errors ensue beginning with a data type mismatch at the line "With oForm" in the middle of the GetPortSettings function. It appears that the close button action destroys the form before it is released and all subsequent oForm references will generate errors. I place a on shutdown command ( on shutdown oForm.release() ) at the top of the function code sequence, but that didn't solve the problem. Should a proc unload module be placed in the form with a release method to gracefully exit the form when the close button is used. I suppose the alternative would be to remove the window banner from the form, leaving the user with only the [Ok] and [Cancel] command buttons.

I follow your logic in the code pretty well, but do not totally understand the the following sequence of commands:

With oForm
Acopy(.rtnVal, laRet ) && copy array to a local array
* set values from form selected values
If !(.Tag == "CANCELLED") && check cancel flag
loParm.CommPort = .OptionGroup1.Value - 1
loParm.BaudRate = .OptionGroup2.Value
loParm.Parity = .OptionGroup3.Value - 1
loParm.ByteLength = Iif(.OptionGroup4.Value = 1, 8, 7)
loParm.StopBit = Iif(.OptionGroup4.Value = 3, 2, 1)
Endif
Endwith

Since loParam is directly populated with the oForm property values, are the rtnVal and laRet values needed I know you indicated rtnVal was not really needed, but I don't understand if the declaration wasn't needed or the array itself wasn't needed. It appears you are using these two arrays to display independent confirmation that loParams possesses the correct values. I do understand the flagging of the cancel action in the code.

Ken





Re: Passing multiple variables from forms w/ VFP7SP1

CetinBasoz

My bad.

ControlBox = .T. && Disable the Control menu box

Would be:

ControlBox = .F. && Disable the Control menu box

However a better way is not to rely on CloseBox unavailibility and control that one too. Add this code in form cass code (say before last line):

PROCEDURE queryunload
NODEFAULT
this
.Tag = "CLOSEBUTTON"
this.Hide()
endproc

You should then decide what to do if it was via closebutton click.

Array was not really needed anywhere. I included it just to show you can do with arrays too. Sometimes they might be better to use. With object parameter none of the properties should need to be in a particular order as if they were "named" parameters. With array you need to know member order (and pray array is not sorted unintentionally - or be multidimensional where one column holds original indexes).





Re: Passing multiple variables from forms w/ VFP7SP1

KDKephart

I understand the concepts well enough to consider this thread completed. I appreciate the help.

Ken





Re: Passing multiple variables from forms w/ VFP7SP1

Naomi Nosonovsky

For the procedure myProcedure why do we need to create another object

Since objects are always passed by reference, would this work

local loParamObject

....

llReturn = MyFunc(m.loParamObject)

function myFunc

lparameters toParamObject

toParamObject.Property = 'New Value'

return SomeValue





Re: Passing multiple variables from forms w/ VFP7SP1

CetinBasoz

Sorry I don't understand. Where is procedure "myProcedure"

Yes objects are passed by reference, you'd have "New Value" set.





Re: Passing multiple variables from forms w/ VFP7SP1

Naomi Nosonovsky

Hi Cetin,

I was referring to this message. Why do we need to create another object in the MyProcedure and return it instead of just changing Parameter Object properties directly