Sometimes it is hard to imagine how things may be simple, even when VFP do not have messaging system.
Sample situation 1: We have data saving routine that checks certain fields and show message when they're not valid or required. After this we need to focus control that edits appropriate field. This require exact pointing to control, exactly know where it is located. When you have a lot of controls on form and complex objects tree with pageframes, it is quite a bit of mess. Sample situation 2: We have complex form with many controls and want to quickly refresh data for some of them in different places. To refresh, we usually use thisform.Refresh(). However, this may be quite slow in some situations, such as show processing result during some process. Command thisform.mycontainer.Mypageframe.pages(thisform.mycontainer.Mypageframe.ActivePage).Refresh may help too, but you see how it looks and what it cause when some of object names changed or objects rearranged. And this solves problem in particular only.
Wishes: It will be good when we can send message to all controls of form like 'FocusSelfByField' or 'RefreshSelf'. When control receive such message and see that its control source match to sent field, it focuses self. Or just refreshes self.
Problem: VFP do not have its native built-in tools to make such type of messaging.
Solution: Using some tricks, we may easy organize messaging without problems. Following are solutions for both sample situations:
Sample situation 1 solution: Message processing part Make base classes for controls in form (most applications usually already have such classes). Define property 'FocusSelfByField' for each data-bound focusable control. Make Assign method for this property: PROCEDURE FocusSelfByField_Assign lparameters vNewVal if upper(this.ControlSource) == upper(vNewVal) this.SetFocus endif ENDPROC Message sending part During validation, use following line to focus required control in case of problem: thisform.SetAll('FocusSelfByField','MyTable.MyField')
Sample situation 2 solution: Message processing part For controls that require special quick refreshing, make class and define 'RefreshSelf' property with assign method: PROCEDURE RefreshSelf_Assign lparameters vNewVal this.Refresh() ENDPROC Message sending part During some sort of processing to quickly refresh controls without refreshing of entire form, use following lines: thisform.SetAll('RefreshSelf',.T.) && send message DOEVENTS && to assure internal events processed and results will be painted on form
Important notes 1. Broadcast message properties should be defined for root object too from which 'SetAll' method called (in samples - for form), it may be without assign method. This is for case when no objects with property that specified in SetAll command. In other words, sometimes SetAll method cause error when no objects with specified property. 2. SetAll command for messaging is much more quick compare to VFP code to scan all objects of form. 3. This method is very useful to communicate with controls inside grid or between particular controls on form when you do not know exact location of control.