21.4.5 给对话框资源添加控件
虽然已经将IDD_CUSTOMER_FORM对话框与Customers表联系起来,但在创建Orders表中的新记录的过程中还需要提供所有必要的信息。新的Orders记录中各个字段的数据源如图21-14所示。
需要提供的一半字段来自用户选择的Customers表记录。因为是在创建新订单,所以需要合成新的特定的订单ID。为此,可以找出当前Orders表中使用的最大ID,然后仅仅使该ID值加1即可。
|
| (点击查看大图)图 21-14 |
为了选择客户,用户需要滚动记录集,直到所需的客户出现为止。之后,就可以从该记录集中检索构造新的Orders记录所需的数据。可以在对话框中显示当前日期作为订单日期,并提供一个控件供用户选择要求的发货日期。其他字段仅仅分配任意的数值,以免使该示例过于复杂。
当然,不需要在对话框中显示Customers表的所有信息,仅仅显示名称就足以识别要选择的客户。但还是需要该记录集中的数据。可以像图21-15所显示的那样布置IDD_CUSTOMER_ FORM对话框上的控件。
|
| (点击查看大图)图 21-15 |
从图中可以看出这些控件的用法以及需要给它们分配的ID。日期/时间采集器控件允许输入或选择日期、时间。选择的是日期还是时间取决于为Format属性选择的值。这里的控件使用Short Date格式。选择日期的方法是单击向下箭头,从弹出的日历中选择某个日期。注意,显示订单日期的控件是用户不可以访问的,因为该日期值就是当天的日期。设定这种控件状态的方法是将Disabled属性的值设置为True。还要注意,对应订单ID和客户名称的编辑控件,其Read Only属性需要被设置为True,以防止对显示值进行修改。
可以给CCustomerView类添加两个变量,存储来自日期/时间采集器控件的值。右击订单日期编辑控件,并从弹出菜单中选择Add Variable。图21-16是此时出现的对话框。
|
| (点击查看大图)图 21-16 |
需要选择Value类别和CTime类型,因为需要的是存储控件值的变量,而非用来访问控件本身的变量。可以将该成员命名为m_OrderDate。Add Member Variable Wizard自动将该变量的初始化代码添加到CCustomerView类的构造函数中,并在DoDataExchange()函数中添加DDX_函数调用,以实现该变量与控件之间的数据交换。以类似的方式,可以为另一个日期/时间采集器控件添加名为m_RequiredDate的变量。
虽然该视图与对应于Customers表的记录集相关,但事实上只有显示客户名称的编辑控件需要连接到CCustomerSet记录集,因为在对话框上只需要显示该字段。为此,可以在CCustomerView类的DoDataExchange()函数中添加一条DDX_函数调用:
- void CCustomerView::DoDataExchange(CDataExchange* pDX)
- {
- CRecordView::DoDataExchange(pDX);
- DDX_DateTimeCtrl(pDX, IDC_ORDERDATE, m_OrderDate);
- DDX_DateTimeCtrl(pDX, IDC_REQUIREDDATE, m_RequiredDate);
- DDX_FieldText(pDX, IDC_COMPANYNAME, m_pSet->m_CompanyName, m_pSet);
- }
此刻,还可以右击各个按钮,并从弹出菜单中选择Add Event Handler,从而将处理程序添加到这些按钮的CCustomerView类。如果愿意,可以将默认的函数名缩写为OnSelectproducts()和OnCancelorder()。将在后面编写这两个处理程序的代码,并处理其余控件。
在选择过客户之后,IDD_PRODUCT_FORM对话框要选择订购的产品。当在客户选择对话框上单击Select Products按钮之后,应用程序将切换到产品选择对话框。需要在该对话框上显示足够的信息,以允许用户选择产品;还必须提供用于输入数量和折扣的控件。添加了控件的产品选择对话框如图21-17所示。
|
| (点击查看大图)图 21-17 |
注意,除对应数量和折扣的两个编辑控件以外,这里的其他控件都是只读的,因为数量和折扣是唯一需要用户提供的两个数值。可以在CProductView类的DoDataExchange()函数中添加下面这条语句,将对应产品名称的编辑控件连接到CProductSet记录集:
- void CProductView::DoDataExchange(CDataExchange* pDX)
- {
- CRecordView::DoDataExchange(pDX);
- DDX_FieldText(pDX, IDC_PRODUCTNAME, m_pSet->m_ProductName, m_pSet);
- }
DDX_FieldText()函数调用在CProductSet对象的m_ProductSet成员和ID为IDD_ PRODUCTNAME的控件之间交换数据。
使用为上一个对话框资源使用的相同技术,在CProductView类中为Select Product和Done按钮添加BN_CLICKED事件处理程序;可以将这两个函数命名为OnSelectproduct()和OnDone(),以保持与按钮标签一致。
显示订单ID和客户名称的编辑控件必须以源于上一个对话框的值进行初始化,因此需要有容纳这些控件值的类变量。在IDD_PRODUCT_FORM对话框中依次右击这两个控件,并从弹出菜单中选择Add Variable。应该为这两个变量选择Value类别,它们也都可以是公有的。为m_OrderID变量选择long类型,为m_CustomerName变量选择CString类型。
用户要在对应数量和折扣的编辑控件中输入数值,因此在CProductView类中还需要有对应这两个控件的变量,这两个变量也都是Value类别。添加一个名为m_Quantity的int类型变量存储数量,再添加一个名为m_Discount的float类型变量存储折扣值。现在应该发现,这两个变量在构造函数和DoDataExchange()函数中是像下面这样初始化的:
- void CProductView::DoDataExchange(CDataExchange* pDX)
- {
- CRecordView::DoDataExchange(pDX);
- DDX_FieldText(pDX, IDC_PRODUCTNAME, m_pSet->m_ProductName, m_pSet);
- DDX_Text(pDX, IDC_NEWORDER, m_OrderID);
- DDX_Text(pDX, IDC_COMPANYNAME, m_CustomerName);
- DDX_Text(pDX, IDC_ORDERQUANTITY, m_Quantity);
- DDX_Text(pDX, IDC_ORDERDISCOUNT, m_Discount);
- }
定义过对话框之后,可以实现在对话框之间切换的机制。