大多数实际的应用程序由多个窗体组成。信息经常需要在窗体之间传递。将信息传递给窗体,可借助传递给窗体的参数,或通过设置窗体的属性。获得消息的方式依靠于窗体模态的还是非模态的。
1.从非模态窗体获取数据
通过调用公共成员函数或查询窗体的属性,可以很轻易地从非模态的窗体中抽取信息。例如,假定应用程序包含一个非模态的窗体调用ColorForm,其中包含一个列表框ColorListBox。列表框中包括了一个颜色列表(“红色”、“绿色”、“蓝色”等)。每次用户选择一种新的颜色,当前被选择的颜色名字符串自动地存储在ColorListBox的CurrentColor属性里。该窗体类声明如下:
该列表框的OnClick事件处理程序—ColorListBoxClick,在每次选择一个新的列表框的项时设置CurrentColor属性的值。该事件处理程序从包含这种颜色的列表框中得到字符串任命,并将它设为CurrentColor的值。CurrentColor属性使用设置函数setColor来将实际属性值存储在私有数据成员curColor中:
现在假定应用程序有另一个窗体ResultsForm,在其中的一个按钮(UpdateButton)被单击时,需要找到当前在ColorForm中被选择的颜色。那么,UpdateButton的OnClick事件处理程序可能会如下所示:
该事件处理程序首先通过检验指针是否为零来证实ColorForm的存在。然后获取ColorForm的CurrentColor属性值。CurrentColor查询调用其获取函数getColor,如下所示:
作为选择,若ColorForm的getColor函数是公共的,另一窗体可以不使用CurrentColor属性而得到当前颜色(例如,StringsS=ColorForm->getColor();)。实际上,也没什么方法可防止另一窗体通过直接检验列表框的选择而得到ColorForm的当前被选定颜色:
然而,使用属性使ColorForm的接口变得非常简单。所有需做的事仅是检查ColorForm的CurrentColor属性值。
2.从模态的窗体获取数据
如同非模态的窗体一样,模态的窗体经常包含其他的窗体需要的信息。最常见的例子是窗体A启动模态的窗体B。当窗体B关闭时,窗体A需要知道用户如何处理窗体B以便决定如何继续处理窗体A。假如窗体B仍然在内存中,可通过属性或成员函数查询它,与上例中非模态窗体的方式相同。但若窗体B关闭时从内存中删除时如何处理呢?因为窗体没有显式返回值,必须在它被删除前保留重要的信息。
为举例说明,将ColorForm窗体改为模态窗体。类声明如下:
例中窗体有一包含颜色列表的列表框ColorListBox。当按下SelectButton按钮时,将列出ColorListBox当前被选择的颜色名。CancelButton是用于关闭窗体的按钮。
注重类中加入了一个自定义的构造函数,它使用了一个String*参数。假定启动ColorForm的窗体知道String*所指的串。那么构造函数的实现将如下所示:
构造函数将指针保存到私有数据成员curColor中并将字符串初始化为空字符串。
注重要使用上例的自定义构造函数,窗体必须是显式创建的。不能是在应用程序开始时自动创建的。细节请参见4.3.1节。
在应用程序中,若用户从列表框中选择一种颜色并用SelectButton按钮来保存选择并关闭窗体。则SelectButton的OnClick事件处理程序为:
注重到事件处理程序会将所选择颜色名存储到传递给构造函数的串的地址中。若要有效地使用ColorForm,调用窗体必须传递给构造函数一个存在的串。例如,假定窗体ResultsForm中的按钮UpdateButton被按下时,ColorForm将被ResultsForm。则事件处理程序为:
UpdateButtonClick创建一个字符串S。S的地址将传递给GetColor函数,GetColor会创建ColorForm,并将指向S的指针作为参数传递给构造函数。ColorForm一关闭它就被删除,但若用户选择了一种颜色,被选择颜色名仍然被保存在S中。若用户没有选择颜色就关闭了ColorForm,S中将包含一空串。
上例使用一个串变量从模态窗体获取信息。当然,根据需要可使用更复杂的对象。记住,应该总是提供一种方法让调用窗体知道是否模态窗体没有做任何变化或选择就关闭了(比如提供缺省为空的字符串S)。