![]() |
![]() |
Как передавать значения между различными формами? |
Боюсь что возможностей много :-) Однако, наверно их можно разделить на следующие группы:
Не могу удержаться, чтобы ещё раз не привести пример от Mike Korneev, совмещающий в себе второй и третий случаи, причём от возможностей третьего Mike оставил только модальность формы! :-)
*********** any.prg
local lc_Tmp
lc_Tmp='1234'
createobj('ff',@lc_Tmp)
?lc_Tmp
define class ff as form
autocenter=.t.
width=200
height=100
add object txt as textbox with top=20, left=50, width=100
add object cmd as commandbutton with top=60, left=50, height=25, width=100
func cmd.click
thisform.hide
endfunc
func init(rc_Val)
this.txt.value=rc_Val
this.show(1)
rc_Val=this.txt.Value
return .f.
endfunc
enddef
********** end of any.prg
обратите внимание: метод Hide() позволяет продолжить выполнение команд, следующих за show(1) при всё ещё "живом" указателе This, в то время как передача значения в Init(rc_Val) осуществляется именно по ссылке.
Чтобы хоть как-то продемонстрировать возможности из первой группы могу привести следующий демонстрационный пример:
*//////////////////////////// any.prg for VFP 6.0
RELEASE goFrmManager
PUBLIC goFrmManager
goFrmManager = CREATEOBJECT('frmmanager')
IF VARTYPE(goFrmManager) # 'O'
RELEASE goFrmManager
RETURN .F.
ENDIF
RELEASE Form1
PUBLIC Form1
Form1 = CREATEOBJECT('form1')
IF VARTYPE(Form1) # 'O'
RELEASE Form1
RETURN .F.
ENDIF
Form1.Show()
goFrmManager.Show()
**************************************************
*-- Form: frmmanager (d:\myapp\vfp\formsetgetvalue\frmmanager.scx)
*-- ParentClass: form
*-- BaseClass: form
*-- Time Stamp: 06/16/01 06:18:06 PM
*
DEFINE CLASS frmmanager AS form
Height = 129
Width = 348
DoCreate = .T.
AutoCenter = .T.
BorderStyle = 2
Caption = "Manager forms properties"
MaxButton = .F.
MinButton = .F.
Name = "frmManager"
ADD OBJECT lblnameform AS label WITH ;
Caption = "Name:", ;
Height = 16, ;
Left = 14, ;
Top = 4, ;
Width = 41, ;
TabIndex = 1, ;
Name = "lblNameForm"
ADD OBJECT txtnameform AS textbox WITH ;
Value = "Form1", ;
Height = 25, ;
Left = 60, ;
TabIndex = 2, ;
Top = 0, ;
Width = 133, ;
Name = "txtNameForm"
ADD OBJECT cmdcheckactive AS commandbutton WITH ;
Top = 0, ;
Left = 204, ;
Height = 25, ;
Width = 133, ;
Caption = "Is as Acive", ;
TabIndex = 3, ;
Name = "cmdCheckActive"
ADD OBJECT lblpropery AS label WITH ;
Caption = "Property:", ;
Height = 16, ;
Left = 2, ;
Top = 34, ;
Width = 54, ;
TabIndex = 4, ;
Name = "lblPropery"
ADD OBJECT txtproperty AS textbox WITH ;
Value = "text1.value", ;
Height = 25, ;
Left = 60, ;
TabIndex = 5, ;
Top = 30, ;
Width = 131, ;
Name = "txtProperty"
ADD OBJECT lblvalue AS label WITH ;
Caption = "Value:", ;
Height = 18, ;
Left = 17, ;
Top = 62, ;
Width = 40, ;
TabIndex = 7, ;
Name = "lblValue"
ADD OBJECT txtvalue AS textbox WITH ;
Height = 25, ;
Left = 60, ;
TabIndex = 8, ;
Top = 60, ;
Width = 133, ;
Name = "txtValue"
ADD OBJECT cmdget AS commandbutton WITH ;
Top = 60, ;
Left = 204, ;
Height = 25, ;
Width = 61, ;
Caption = "Get", ;
TabIndex = 9, ;
Name = "cmdGet"
ADD OBJECT cmdreset AS commandbutton WITH ;
Top = 60, ;
Left = 276, ;
Height = 25, ;
Width = 61, ;
Caption = "ReSet", ;
TabIndex = 10, ;
Name = "cmdReset"
ADD OBJECT cmdexit AS commandbutton WITH ;
Top = 96, ;
Left = 114, ;
Height = 25, ;
Width = 120, ;
Caption = "Cancel", ;
TabIndex = 11, ;
Name = "cmdExit"
ADD OBJECT txtresult AS textbox WITH ;
Height = 25, ;
Left = 204, ;
ReadOnly = .T., ;
TabIndex = 6, ;
Top = 29, ;
Width = 133, ;
Name = "txtResult"
PROCEDURE getform
LPARAMETERS tcNameForm
IF VARTYPE(tcNameForm) # 'C' OR EMPTY(tcNameForm)
RETURN NULL
ENDIF
LOCAL loFrm, lnCntFrm, lcNameForm
lcNameForm = UPPER(ALLTRIM(tcNameForm))
FOR lnCntFrm = 1 TO _SCREEN.FormCount
IF lcNameForm == UPPER(ALLTRIM(_SCREEN.Forms(lnCntFrm).Name))
RETURN _SCREEN.Forms(lnCntFrm)
ENDIF
ENDFOR
RETURN NULL
ENDPROC
PROCEDURE eval
LPARAMETERS toFrm, tcType
*
*-- It's very primitive calculator, and usual do not write so...
*-- However, it's sufficient for our purposes
LOCAL loFrm, lcObj, loObj, lcRetVal
lcRetVal = ''
WITH ThisForm
IF VARTYPE(toFrm) # 'O'
.txtResult.Value = 'Not found'
RETURN lcRetVal
ENDIF
*
*-- Get expression to evaluate
lcObj = 'toFrm.'+ALLTRIM(.txtProperty.Value)
LOCAL lnPos, lcSubObj
*
*-- Check: is object?
lnPos = RATC('.', lcObj)
IF lnPos > 0
lcSubObj = LEFTC(lcObj, lnPos-1)
IF TYPE(lcSubObj) = 'O'
*
*-- In case error this value will changed...
*-- in ThisForm.Error() event
.txtResult.Value = 'Ok!'
DO CASE
CASE tcType = 'get'
*
*-- Try evaluate
lcRetVal = EVALUATE(lcObj)
CASE tcType = 'set'
*
*-- Prep command & try evaluate
lcRetVal = lcObj+' = "'+ALLTRIM(.txtValue.Value)+'"'
&lcRetVal
OTHERWISE
lcRetVal = ''
ENDCASE
*
*-- Check result
IF !EMPTY(lcRetVal)
IF .txtResult.Value = 'Ok!'
RETURN lcRetVal
ELSE
RETURN ''
ENDIF
ENDIF
ENDIF
ENDIF
.txtResult.Value = 'Not Object'
ENDWITH
RETURN ''
ENDPROC
PROCEDURE Error
LPARAMETERS nError, cMethod, nLine
LOCAL ARRAY laErr[1]
LOCAL lcMsg
=AERROR(laErr)
lcMsg = 'Error: '+LTRIM(STR(laErr[1]))+CHR(13);
+'Description: '+laErr[2]+CHR(13);
+'Method: '+cMethod+CHR(13);
+'Line: '+LTRIM(STR(nLine))
*
*-- Now set error indication (see comments in ThisForm.eval())
ThisForm.txtResult.Value = 'Error as Object'
ACTIVATE SCREEN
??CHR(7)
MessageBox(lcMsg, 16, ThisForm.Caption)
ENDPROC
PROCEDURE cmdcheckactive.Click
LOCAL loFrm
WITH ThisForm
.txtResult.Value = ;
IIF(VARTYPE(.GetForm(.txtNameForm.Value)) = 'O';
,'Ok!', 'Not found')
ENDWITH
ENDPROC
PROCEDURE cmdget.Click
LOCAL lcValue
WITH ThisForm
lcValue = .Eval(.GetForm(.txtNameForm.Value), 'get')
IF !EMPTY(lcValue)
*
*-- Is result: set returns value
.txtValue.Value = lcValue
ENDIF
ENDWITH
ENDPROC
PROCEDURE cmdreset.Click
LOCAL lcValue
WITH ThisForm
.Eval(.GetForm(.txtNameForm.Value), 'set')
ENDWITH
ENDPROC
PROCEDURE cmdexit.Click
ThisForm.Release()
ENDPROC
ENDDEFINE
*
*-- EndDefine: frmmanager
**************************************************
**************************************************
*-- Form: form1 (d:\myapp\vfp\formsetgetvalue\form1.scx)
*-- ParentClass: form
*-- BaseClass: form
*-- Time Stamp: 06/11/01 10:46:03 PM
*
DEFINE CLASS form1 AS form
Top = 0
Left = 0
Height = 80
Width = 234
DoCreate = .T.
BorderStyle = 2
Caption = "Form1"
MaxButton = .F.
MinButton = .F.
Name = "Form1"
ADD OBJECT text1 AS textbox WITH ;
Value = "Test", ;
Height = 25, ;
Left = 24, ;
Top = 12, ;
Width = 157, ;
Name = "Text1"
ADD OBJECT cmdexit AS commandbutton WITH ;
Top = 48, ;
Left = 144, ;
Height = 25, ;
Width = 73, ;
Caption = "Cancel", ;
Name = "cmdExit"
PROCEDURE cmdexit.Click
ThisForm.Release()
ENDPROC
ENDDEFINE
*
*-- EndDefine: form1
**************************************************
*//////////////////////////// end of any.prg
Конечно, мой пример значительно проигрывает, как по объёму кода, так и требует значительно меньшего количества извилин, которые нужно напрячь, чтобы понять: как это работает :-). Однако, запустите пример ...ткните на форме "Manager forms properties" кнопку "Is as Acive"... далее на кнопку "Get"... наконец, изменив значение в текстовом поле Value, нажмите кнопку "ReSet"... Как надеюсь, работает! :-) Дальше можете баловаться в своё удовольствие... пока не поломаете! :-))
