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