21.3.1 实现更新模式(1)
首先提供记录应用程序是否处于更新模式的功能。要实现该功能,可以给COrderDetailsView类添加某个enum声明,并声明该enum类型的一个变量来反映当前的模式。给COrderDetailsView类的公有部分添加下面这两行代码:
- enum Mode {READ_ONLY, UPDATE}; // Application modes
- Mode m_Mode; // Records the current mode
应用程序最初处于READ_ONLY模式,因此可以在构造函数中相应地初始化m_Mode:
- enum Mode {READ_ONLY, UPDATE}; // Application modes
- Mode m_Mode; // Records the current mode
可以在添加到视图类的OnEditorder()处理程序中,实现按钮标签和程序模式的切换。原则上,该函数的初始版本需要实现如下所述的功能:
- void COrderDetailsView::OnEditorder()
- {
- if(m_Mode == UPDATE)
- { // When button was clicked we were in update
-
- // Disable input to edit controls
- // Change the Update button text to Edit Order
- // Make the Cancel button invisible
- // Enable Record menu items and toolbar buttons
- // Complete the update
- m_Mode = READ_ONLY; // Change to read-only mode
- }
- else
- { // When button was clicked we were in read-only mode
- // Enable input to edit controls
- // Change the Edit Order button text to Update
- // Make the Cancel button visible
- // Disable Record menu items and toolbar buttons
- // Start the update
- m_Mode = UPDATE; // Switch to update mode
- }
- }
模式切换代码已经给出。此刻,该函数能够做到的全部只是使m_Mode成员在READ_ONLY和UPDATE之间切换,以记录当前的模式。我们需要的其他功能只是在注释中作了描述。接下来,研究如何依次实现每行注释。
1. 启用和禁用编辑控件
要修改某个控件的属性,需要调用与该控件相关的函数。这意味着必须能够访问某个表示该控件的对象。给视图类添加某个控件变量非常简单;只需在该对话框的Design窗口中右击该控件,并从弹出菜单中选择Add Variable即可。图21-8是为显示折扣值的编辑控件添加变量时显示的对话框。
|
| (点击查看大图)图 21-8 |
此处输入的变量名是m_DiscountCtrl。因为该变量与某个编辑控件有关,所以其类型是CEdit。单击Finish将该变量添加到视图类中。为显示订单数量的编辑控件重复该过程,并将相应的变量命名为m_QuantityCtrl。
在给视图类添加过这两个控件变量之后,就可以访问相应的控件,并更新它们的样式。因此,将OnEditorder()函数修改成下面这样:
- void COrderDetailsView::OnEditorder()
- {
- if(m_Mode == UPDATE)
- { // When button was clicked we were in update
-
- // Disable input to edit controls
- m_QuantityCtrl.SetReadOnly();
- m_DiscountCtrl.SetReadOnly();
-
- // Change the Update button text to Edit Order
- // Make the Cancel button invisible
- // Enable Record menu items and toolbar buttons
- // Complete the update
- m_Mode = READ_ONLY; // Change to read-only mode
- }
- else
- { // When button was clicked we were in read-only mode
-
- // Enable input to edit controls
- m_QuantityCtrl.SetReadOnly(FALSE);
- m_DiscountCtrl.SetReadOnly(FALSE);
-
- // Change the Edit Order button text to Update
- // Make the Cancel button visible
- // Disable Record menu items and toolbar buttons
- // Start the update
- m_Mode = UPDATE; // Switch to update mode
- }
- }
CEdit类的SetReadOnly()成员有一个BOOL类型的形参,其默认值是TRUE。因此,不带实参调用该函数意味着实参是默认值,该控件的只读属性将被设置为真。如果调用该函数时传递FALSE值,则该控件的只读属性将被设置为假。顺便提一下,可以删除if-else语句中对SetReadOnly()函数的调用,然后在if语句之后添加下面这两条语句,从而减少函数中的代码:
- m_QuantityCtrl.SetReadOnly(m_Mode == UPDATE);
- m_DiscountCtrl.SetReadOnly(m_Mode == UPDATE);
当m_Mode的值是UPDATE时,实参表达式m_Mode == UPDATE为TRUE;否则为FALSE。因此,这两次对SetReadOnly()函数的调用与原来的四次调用作用相同。不利方面是对代码中所发生的事情交代得不是十分清楚。
需要提醒读者的是,许多MFC函数都有值为TRUE或FALSE的BOOL类型的形参,因为它们是在C++(www.cppentry.com)中的bool类型可以使用之前编写的。如果愿意,总是可以使用bool类型的数值作为对应BOOL形参的实参,但我更喜欢为BOOL类型的形参坚持使用TRUE和FALSE实参值,而仅为bool类型的变量使用true和false。