6.3.7 工具条的消息映射技巧
如果工具条上的按钮都存在对应的菜单命令,那么可以直接利用类向导classwizard 进行命令消息的映射,否则必须通过手工的方法来进行命令按钮的消息映射。由于同一工具栏的命令按钮都存在相类似的功能,所以只要注意将同一工具条中的命令按钮id值设置成连续值,就可以利用范围命令处理机制统一对所有按钮命令进行管理,即所有命令按钮的消息可以在同一命令消息处理函数和更新命令消息处理函数中进行管理,这样不但结构紧凑而且维护特别方便。鉴于类向导classwizard 不支持范围命令处理功能,所以其消息映射机制必须通过手工方式来完成。按钮命令消息既可以在框架窗口中映射,也可以在文档和视图中完成映射,由于文档对象通常用来管理程序中的数据部分,并且在多文档应用程序(mdi) 中,一个文档可能有多个视图与之关联,因此把工具栏中的命令按钮消息映射在文档中比较合适些。其实现步骤如下:
(1)在文档实现文件ctooldoc.h中增加函数定义和数据成员:
class cctooldoc : public cdocument
{......//其它代码
protected:
uint iposition; file://命令按钮消息位置
......//其它代码
protected:
file://{{afx_msg(cctooldoc)
afx_msg void ontool(uint nid);//命令消息映射
afx_msg void onupdatetool(ccmdui* pcmdui);//更新消息映射
file://}}afx_msg
declare_message_map()
......//其它代码
}
(2)在文档实现文件ctooldoc.cpp中进行消息映射
begin_message_map(cctooldoc,cdocument)
file://{{afx_msg_map(cctooldoc)
on_command_range(id_button_line,
id_button_sort,ontool);
on_update_command_ui_range(id_button_line,
id_button_sort,onupdatetool);
file://}}afx_msg_map
end_message_map()
函数中的参数id_buttonline和id_buttonsort分别为工具栏中第一个按钮和最后一个按钮的消息,如果要增加或减少了按钮数,则必须使其id值保持连续,并且需要修改函数中的最后一个消息值。对应函数的代码如下:
void ctooldoc::ontool(uint nid)
{ file://按钮消息处理函数
iposition=nid-id_button_line;
switch(iposition){
case 1:
......//调用按钮一的处理功能
case 2:
......//调用按钮二的处理功能
......
case n:
......//调用按钮n的处理功能
break;
}
}
void ctooldoc::onupdatetool(ccmdui* pcmdui)
{ file://更新按钮函数
pcmdui->setcheck(iposition==(pcmdui->m_nid
-id_button_line));
}
由于命令按钮比较多,其处理功能代码部分这里省略。
6.3.8 驾驭工具条按钮的状态显示更新
(1)互斥按钮的状态更新
很多应用程序中都存在相互排斥的工具条按钮,如开始和停止按钮,初始状态时停止按钮被禁止,当应用程序进行数据通讯、查找和打印等功能时,停止按钮有效而开始按钮禁止,当命令结束或按停止按钮后,开始按钮有效而停止按钮被禁止。这就是工具条中按钮的显示状态更新问题。
与菜单栏一样,工具条的构造、析构过程及其窗口的创建都是由应用程序的主框架窗口来管理的。当用户点击菜单条的菜单项时,windows 就会向应用程序发送wm_initmenupopup消息,以便应用程序在菜单显示之前对菜单项进行添加或修改,当利用mfc 类库编程时只要针对某一具体的菜单项进行消息映射,加入相应的消息处理函数,mfc类库就会发送更新消息update_command_ui,使菜单在弹出时消息处理函数能够对菜单项进行禁止、变灰和其它处理。工具条的消息处理过程与菜单栏完全相同,它也存在工具条显示更新消息update_command_ui ,只不是由于工具条总是处于显示状态,所以对其消息处理函数的调用是在应用程序的空闲状态时进行处理的,这点与菜单栏有所不同,当应用程序命令按钮所要执行的功能占用大量的处理器资源时,如进行通讯处理或大量数据计算时,应用程序的主框架窗口就无暇进入空闲状态,于是工具条中的命令按钮函数就不能被及时调用,按钮的显示状态就不能被及时更新,这就为工具条按钮的显示状态及时更新带来一定的困难。
基于文档的应用程序一般情况下都是在文档视中对工具条按钮进行处理,所以要实现按钮显示状态的及时更新,必须在命令按钮响应函数中利用ctoolbarctrl类的成员函数enablebutton()函数对按钮的显示状态进行必要的处理,其步骤如下:
①首先利用类向导classwizard 对cctoolview类进行开始按钮和停止按钮的command命令消息映射,增加对应消息的处理函数;
②在实现文件ctoolview.h中增加成员变量:
public:
bool m_bcontiune;//开始按钮标志
bool m_bset;//结束按钮标志
③在实现文件ctoolview.cpp中增加代码完善按钮状态更新:
......//其它代码
void drawrecttext(rect &rc,cdc &dc);