5050
Как передавать значения между различными формами?

 

Боюсь что возможностей много :-) Однако, наверно их можно разделить на следующие группы:

Не могу удержаться, чтобы ещё раз не привести пример от 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"... Как надеюсь, работает! :-) Дальше можете баловаться в своё удовольствие... пока не поломаете! :-))

 
 
Hosted by uCoz